Help us understand the problem. What is going on with this article?

docker-compose.yml を環境ごとに分割する

前提

Compose ファイルフォーマットバーション 3.x

結論

-f オプションを使う

$ docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

または環境変数を使う: COMPOSE_FILE, COMPOSE_PATH_SEPARATOR

$ export COMPOSE_PATH_SEPARATOR=:
$ export COMPOSE_FILE=docker-compose.yml:docker-compose.prod.yml
$ docker-compose up -d

ファイル間、プロジェクト間での Compose 設定の共有 — Docker-docs-ja 17.06 ドキュメント

注意

  • extends キーワードは 2.1 までのサポートで、(2020年7月現在)ではご利用いただけません🙅‍♀️
  • COMPOSE_FILEの区切り文字はOSによって異なるのでCOMPOSE_PATH_SEPARATORを明示的に指定しておくと無難
  • -fオプションではなく環境変数を使う場合は他プロジェクトに影響するかもしれないのでそこは注意

Makefile と合わせて使う

簡単な例としてベースとなるファイルと、環境用のファイルをそれぞれ用意した。

docker-compose.yml
version: "3"
volumes:
  app-node_modules:
  app-dist:
services:
  app:
    build: ./app
    container_name: app
    volumes:
      - ./app/src:/usr/app
      - app-node_modules:/usr/app/node_modules
      - app-dist:/usr/app/dist
docker-compose.prod.yml
version: "3"
services:
  app:
    ports:
      - 80:80
    environment:
      PRODUCTION: 'true'
docker-compose.local.yml
version: "3"
services:
  app:
    ports:
      - 8080:80
    environment:
      DEBUG: 'true'

これらを環境によって切り替えるための Makefile を作る

ここでは環境変数を使って docker-compose の上書きを想定した

Makefile
# 本番では make [cmd] e=prod とする

# local or prod
ENV=local

pre:
ifdef e
ENV=${e}
endif

set-env := export ENV=$(ENV) ;\
           export COMPOSE_PATH_SEPARATOR=: ;\
           export COMPOSE_FILE=docker-compose.yml:docker-compose.$(ENV).yml

up: pre
    $(set-env)\
    docker-compose up -d

down: pre
    $(set-env)\
    docker-compose down

rebuild: pre
    $(set-env)\
    docker-compose build --no-cache

上記の設定で環境ごとにコマンドで切り替えられるようになった👏

# ローカル開発
$ make rebuild
$ make up
$ make down

# 本番環境
$ make rebuild e=prod
$ make up e=prod
$ make down e=prod

これは簡単な例だが、実際にはより多くの設定になるため、多くの冗長な設定から解放されて幸せになれる❤️

Makefile がないとメンテナンス性も開発体験も落ちるので、嫌がらずに開発序盤から用意しよう🤗

結合時の挙動について

1つの値を持つオプションか、複数の値を持つオプションかで挙動が変わってくる

以下公式より引用: 設定の追加と上書き — Docker-docs-ja 17.06 ドキュメント

1 つの値しか持たないオプション、たとえば image、command、mem_limit のようなものは、古い値が新しい値に置き換えられます。

# docker-compose.yml
command: python app.py

# docker-compose.prod.yml
command: python otherapp.py

# docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
command: python otherapp.py

# 後に書いた方が適応される

複数の値を持つオプション、つまり ports、 expose、 external_links、 dns、 dns_search、 tmpfs では、両者の設定をつなぎ合わせます。

# docker-compose.yml
expose:
  - "3000"

# docker-compose.prod.yml
expose:
  - "4000"
  - "5000"

# docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
expose:
  - "3000"
  - "4000"
  - "5000"

# 両者適応される

environment、 labels、 volumes、 devices の場合、Compose は設定内容を "マージ" して、ローカル定義の値が優先するようにします。

# docker-compose.yml
environment:
  - FOO=original
  - BAR=original

# docker-compose.prod.yml
environment:
  - BAR=local
  - BAZ=local

# docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
environment:
  - FOO=original
  - BAR=local
  - BAZ=local

# 競合してたら後に書いた方が優先され、競合してないものは適応される

💸 Compose ファイルのご利用は計画的に💸

(ブログに書いた内容そのまま転載した)

yKicchan
ウェブえんじにゃ〜ん
https://www.ykicchan.dev
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした