社内でDockerを利用したプロジェクトが増えてきて、ポートの競合問題やコンテナが多すぎて重いなどの問題があり、「ひとまず現状これがベストかな?」と思える設定に落ち着いたので、それを書く。
概要
- DB や mailhog などの共通で利用できるコンテナは共通化し、DBなどのポート競合や起動コンテナを減らす
nginx-proxy
でリバースプロキシして web のポート競合も回避するlaravel
のプロジェクトでしか私は使用していないが、汎用性はあると思う
注意
DBを共有にするため、プロジェクト毎にDBのバージョンを分けたい場合には対応できない。
そういった場合は、
律儀に、ポート番号が被らないように各プロジェクトで設定するか
ループバックアドレスをプロジェクト毎に割り当てるか (https://qiita.com/hanlio/items/243006a67fb8d535d958)
で対応が可能です。
ディレクトリ構成
.
├── webdev
│ ├── dump/
│ └── docker-compose.yaml
├── project1
│ ├── docker-compose.yaml
│ └── etc...
└── project2
├── docker-compose.yaml
└── etc...
共通コンテナの設定
adwin さんが公開してくれているリポジトリに nginx-proxy
を追加いただけ。
https://github.com/adwinying/webdev
docker-compose.yaml
docker-compose -d pgsql mailhog proxy
と必要なコンテナのみ起動する- ダンプファイルなどがあれば、
dump
ディレクトリを作成して、そこにダンプファイルを格納する
version: '3'
services:
mysql:
image: mysql:5.7
ports:
- '${MYSQL_PORT:-3306}:3306'
environment:
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD:-password}'
MYSQL_DATABASE: '${DB_DATABASE:-db}'
MYSQL_USER: '${DB_USERNAME:-sail}'
MYSQL_PASSWORD: '${DB_PASSWORD:-password}'
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
volumes:
- 'webdev-mysql:/var/lib/mysql'
- './dump:/tmp/dump'
networks:
- webdev
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-p${DB_PASSWORD:-password}"]
retries: 3
timeout: 5s
pgsql:
image: postgres:13
ports:
- '${PGSQL_PORT:-5432}:5432'
environment:
PGPASSWORD: '${DB_PASSWORD:-password}'
POSTGRES_DB: '${DB_DATABASE:-db}'
POSTGRES_USER: '${DB_USERNAME:-sail}'
POSTGRES_PASSWORD: '${DB_PASSWORD:-password}'
volumes:
- 'webdev-pgsql:/var/lib/postgresql/data'
- './dump:/tmp/dump'
networks:
- webdev
healthcheck:
test: ["CMD", "pg_isready", "-q", "-d", "${DB_DATABASE:-db}", "-U", "${DB_USERNAME:-sail}"]
retries: 3
timeout: 5s
redis:
image: 'redis:alpine'
ports:
- '${REDIS_PORT:-6379}:6379'
volumes:
- 'webdev-redis:/data'
networks:
- webdev
healthcheck:
test: ["CMD", "redis-cli", "ping"]
retries: 3
timeout: 5s
meilisearch:
image: 'getmeili/meilisearch:latest'
ports:
- '${MEILISEARCH_PORT:-7700}:7700'
volumes:
- 'webdev-meilisearch:/data.ms'
networks:
- webdev
mailhog:
image: 'mailhog/mailhog:latest'
ports:
- '${MAILHOG_PORT:-1025}:1025'
- '${MAILHOG_DASHBOARD_PORT:-8025}:8025'
networks:
- webdev
proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
- "127.0.0.1:80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
restart: always
privileged: true
networks:
- webdev
networks:
webdev:
name: webdev
driver: bridge
volumes:
webdev-mysql:
driver: local
webdev-pgsql:
driver: local
webdev-redis:
driver: local
webdev-meilisearch:
driver: local
プロジェクト毎の設定
共通コンテナを立ち上げた後、プロジェクト毎では web のコンテナだけ起動すれば良い
docker-compose.yaml
- ports は 80 だけ指定すれば、コンテナ側のポートは適当に割り当ててくれる
- environment に VIRTUAL_HOST を設定することで、
http://laravel.test
にアクセスした際、nginx-proxy がよしなにしてくれる - 共通コンテナと同一ネットワークに所属する必要があるので、
networks
にwebdev
を指定している
version: '3'
services:
app:
image: thecodingmachine/php:7.4-v4-apache
ports:
- '80'
environment:
PHP_EXTENSIONS: bcmath gd intl pdo_pgsql pgsql
PHP_INI_MEMORY_LIMIT: 512M
PHP_INI_DATE__TIMEZONE: Asia/Tokyo
PHP_INI_MBSTRING__LANGUAGE: Japanese
APACHE_DOCUMENT_ROOT: /var/www/html/public
VIRTUAL_HOST: 'laravel.test'
volumes:
- '.:/var/www/html'
networks:
- webdev
networks:
webdev:
external: true
name: webdev
hosts ファイル
hostsファイルに、 VIRTUAL_HOST の値を追記。
127.0.0.1 laravel.test
おまけ
少しズレるが、docker-compose
コマンドが長すぎるので、Taskfile の設定も置いておきます。
使用手順
docker-compose.yaml
と同一階層に置くchmod 755 ./Taskfile
で権限を変更するalias task=./Taskfile
などとエイリアスを設定する
これで準備完了です。
task artisan migrate
などで実行できるので便利!
Taskfile
#!/bin/bash
# https://github.com/adriancooney/Taskfile#install
function up {
docker-compose up -d
}
function down {
docker-compose down
}
function restart {
docker-compose restart
}
function exec {
docker-compose exec app "$@"
}
function bash {
exec bash
}
function php {
exec /usr/bin/php "$@"
}
function artisan {
exec /usr/bin/php artisan "$@"
}
function composer {
exec /usr/local/bin/composer "$@"
}
function test {
exec vendor/bin/phpunit "$@"
}
function tinker {
artisan tinker
}
function start {
echo "start task not implemented"
}
function default {
help
}
function help {
echo "$0 <task> <args>"
echo "Tasks:"
compgen -A function | cat -n
}
TIMEFORMAT="Task completed in %3lR"
time ${@:-default}