docker-composeのProjectという概念について
大本のディレクトリを分けても、同名フォルダ配下にあるymlを元に docker-compose up するとRecreating されてしまう。
例えばmyProjectに開発用のymlがあるとする(volumes等々だいぶ記述を省いている)。 フォルダ名をmyProjectとする。
myProject/docker-compose.yml
version: '2' services: nginx: image: nginx container_name: "nginx-dev" ports: - "8080:80" app: build: ./php container_name: "app-dev"
普通に起動すると、こうなる。
$ docker-compose up -d Creating network "compose_default" with the default driver Creating app-dev ... done Creating nginx-dev ... done
$ docker-compose ps Name Command State Ports ------------------------------------------------------------------------ app-dev docker-php-entrypoint php-fpm Up 9000/tcp nginx-dev nginx -g daemon off; Up 0.0.0.0:8080->80/tcp
あまり使うことはないが、docker ps でも見てみる。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3e845fb43f2e nginx "nginx -g 'daemon of…" 53 seconds ago Up 52 seconds 0.0.0.0:8080->80/tcp nginx-dev d60726667f0e myproject_app "docker-php-entrypoi…" 53 seconds ago Up 52 seconds 9000/tcp app-dev
コンテナ名はそれぞれ、ymlのcontainer_nameで指定したものになっている。 ただ気にしていなかったのは、appコンテナはDockerfileから作っているので、myproject_appというIMAGE名になっている点。
この環境を検証環境やステージングで使おうとしたとき、2環境欲しいなと思うことがある。 1つの環境はチームメンバーが通常開発に使用する安定的なもので、もう1つは設定や構成を変更する開発案件で使用するもの。
そこで、ymlを分けて以下のように管理することにした。
/myProject |--docker-compose.yml |--php | |--Dockerfile |--ymlfiles | |--docker-compose.staging.develop.yml | |--docker-compose.staging.stable.yml
ポートフォワーディングでホスト側を分ければ2環境同時に使うことができると考えた。
myProjectはgit cloneしてきた同じものだが、その上の階層で分けている。
- /home/webmaster/stable/myProject/ymlfiles
- /home/webmaster/develop/myProject/ymlfiles
そしてコンテナ名もそれぞれ変更した。これで問題ないように思えた。
version: '2' services: nginx: image: nginx container_name: "nginx-staging-stable" ports: - "8080:80" app: build: ../php container_name: "app-staging-stable"
version: '2' services: nginx: image: nginx container_name: "nginx-staging-develop" ports: - "8080:80" app: build: ../php container_name: "app-staging-develop"
stableを立ち上げる。
$ docker-compose -f docker-compose.staging.stable.yml up -d app-staging-stable is up-to-date Starting nginx-staging-stable ... done $ docker-compose -f docker-compose.staging.stable.yml ps Name Command State Ports ----------------------------------------------------------------------------------- app-staging-stable docker-php-entrypoint php-fpm Up 9000/tcp nginx-staging-stable nginx -g daemon off; Up 0.0.0.0:8080->80/tcp
developを立ち上げる。
$ docker-compose -f docker-compose.staging.develop.yml up -d Recreating app-staging-stable ... done Recreating nginx-staging-stable ... done szk416s-MacBook-Pro:~/study/myProject/ymlfiles szk416 $ docker-compose -f docker-compose.staging.develop.yml ps Name Command State Ports ------------------------------------------------------------------------------------ app-staging-develop docker-php-entrypoint php-fpm Up 9000/tcp nginx-staging-develop nginx -g daemon off; Up 0.0.0.0:8080->80/tcp
なんと、 Recreatingされてしまい、先に作ったapp-staging-stableとnginx-staging-stableは消えてしまった。
docker ps で見ても同じ。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d569715fafaf nginx "nginx -g 'daemon of…" 56 seconds ago Up 54 seconds 0.0.0.0:8080->80/tcp nginx-staging-develop 159d41b57e5b ymlfiles_app "docker-php-entrypoi…" 56 seconds ago Up 54 seconds 9000/tcp app-staging-develop
何が起こったのか?
docker-compose にはProjectという概念がある
公式ドキュメントにはちゃんと書いてあるし、確認するコマンドもある
-p, --project-name NAME 別のプロジェクト名を指定 (デフォルト: directory name)
各設定ファイルはプロジェクト名を持っています。 -p フラグでプロジェクト名を指定できます。フラグを指定しなければ、Compose は現在のディレクトリの名前を使います。詳細は COMPOSE_PROJECT 環境変数 をご覧ください。
cf. docker-compose コマンド概要 — Docker-docs-ja 17.06.Beta ドキュメント
ここでいう、 フラグを指定しなければ、Compose は現在のディレクトリの名前を使います というのが重要で、
docker ps の結果の方を見ると、 ymlfiles_app
と、ディレクトリ名 + サービス名になっていることがわかる。
つまり、いくら大本のディレクトリから分けていたとしても、親ディレクトリが ymlfiles
なので同じプロジェクトとして扱われてしまっていた。
基本的にはない話だが、本番環境などであればシャレにならない。
そもそも、環境変数にymlを指定する手段があるところを見ると、複数立てるようなことはしない方が良いのだろう。
フォルダごとに.envを置いてPROJECT_NAMEを指定する手段もあるようだが、こういうのは後からチームに加わった人が気付きづらいので良くないと考えている。
結局、ymlfiles-stable, ymlfiles_develop のように分けて管理することにした。 愚直だが一番わかり易いと思う。