LoginSignup
11
8

More than 1 year has passed since last update.

複数のプロジェクトで Docker を使用する場合の個人的ベストプラクティス

Last updated at Posted at 2021-11-30

社内で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 がよしなにしてくれる
  • 共通コンテナと同一ネットワークに所属する必要があるので、 networkswebdev を指定している
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 の設定も置いておきます。

使用手順

  1. docker-compose.yaml と同一階層に置く
  2. chmod 755 ./Taskfile で権限を変更する
  3. 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}

本記事は個人ブログからの転記です。
https://zumikiti-note.netlify.app/posts/docker-multi-up/

11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8