それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

docker-composeでプロジェクト名をいい感じに設定する。Found orphan containers 対策

docker-compose にはプロジェクト名称がある

おまえらのdocker-composeの使い方では、プロジェクト名称でハマる。

よくある使い方

cd my-docker
docker-compose up -d 

この場合、 プロジェクト名=フォルダ名になる。プロジェクト名は自動的に作られ、プロジェクト名を元に「ネットワーク名が作られる」

問題になる場面

同名フォルダ名で、ymlがあると面倒になる。けっこうこれは起きてしまう。 複数起動したらどうなるか

cd dirA/my-docker
docker-compose up -d 
#
cd another-project/my-docker
docker-compose up -d 

このとき、名前の重複が発生し、意図しない終了と削除が発生する。2つ目のディレクトリで、docker-compose downをしても で1つ目が終了してしまうなどが起きる。

無事に終了ができたとしてもネットワーク名の重複でFound orphan containers になる。

要は、 docker-compose.yml は単純に2つ起動できないのである。

問題が起きる原因。

なぜそうなるか。プロジェクト名が同じになり、ネットワーク名がおなじになり、同じネットワークを使うプロジェクトで名前被りが発生して面倒が起きる。

プロジェクト名を指定しろ。

docker-composeを複数起動するのなら、ちゃんとプロジェクト名を付ける必要がある。

cd dirA/my-docker
docker-compose -p MyProj up -d 

プロジェクト名を管理しろ

ただし、プロジェクト名称がわからなくなると docker-composeコマンドが使えない

おなじpsコマンドでも得られる結果は全く違ったものになる。

cd dirA/my-docker
docker-compose -p MyProj  ps 
docker-compose ps 
  • -p があるときは、プロジェクト名称を参照
  • なしの場合。「プロジェクト名=ディレクトリ名=my-docker」が使われる

プロジェクト独立空間

docker-compose はプロジェクト単位で全く別の独立空間になってる。

docker コンテナ自体が独立空間であり、名前をつけられるのと同じ。docker-composeはプロジェクト名毎で独立空間になっている。

未設定時は、プロジェクト名称=フォルダ名なのである。意図しない名前重複が発生し理由がわからず頭を抱えることになる。

プロジェクト名をいい感じに指定する。

プロジェクト名称をどこかに、設定するべきである。プロジェクト名称を決めずに利用し名前重複を未然に防止する必要がある。

また、プロジェクト名を手軽に参照できるようにする必要がある。

方法1 環境変数を使う

COMPOSE_PROJECT_NAMEを使うと、 -p NAME を省略できる。

cd dirA/my-docker
export COMPOSE_PROJECT_NAME=MyProj
docker-compose  ps 

次の使い方もできる。

cd dirA/my-docker
COMPOSE_PROJECT_NAME=MyProj docker-compose   ps 

ただし、順番に注意する。

docker-compose -p name ps # 動く
docker-compose ps -p name # 動かない。

-p は 一番先頭に付けないと動きません。

方法2 .env ファイルを使う。

dirA/my-docker/.env を使うことで、プロジェクト名称を省略できる。

cd dirA/my-docker
echo 'COMPOSE_PROJECT_NAME=MyProj' > .env
docker-compose  ps 

.env ファイルは、gitプロジェクトとは別に実行時に指定するために使えるものであるが、なぜかプロジェクトにも使われる。

.env ファイルが使える理由

docker-composeには、--env-file のオプションがあり、 --env-fileのデフォルトが、.env になっている。 docker-composeはカレントディレクトリからファイルを読み込むので、./.env が対象になる。

そのため、.env を設置すれば読み込まれる。

.env は docker-compose.yml中に変数や依存を放り込むために使われる。

docker-composeのコマンドとymlの変数を混ぜるので、管理がしにくいところである。

プロジェクト名を意識する

docker-composeを使うとき、暗黙プロジェクト名に注意を払うか、明示的プロジェクト名に変える必要がある。

それをしないと、名前空間がかぶり、コンテナ名・ネットワーク名で重複し起動終了に予想外の自体が起きる。

プロジェクト名をソースコードで指定しといてくれないか。

env ファイルにプロジェクト名を書いたとしても。プロジェクト名は常に意識しておくべきである。

#.env ファイルが有る場合
docker-compose ps 
# .env ファイルがない場合
docker-compose ps 

コマンドが同じでもプロジェクト名 が違うと全く別の空間に docker-composeされるのである。

だから、docker-composeを使うならプロジェクト名をちゃんと書いておけ。

systemdの場合

systemd で docker-composeするとき

[Unit]
Description=docker-composeの%iコンテナ管理
Requires=docker.service
After=docker.service

[Service]

## プロジェクト名称をつける
Environment=COMPOSE_PROJECT_NAME=MyXXX
WorkingDirectory=/var/project
ExecStart=/usr/bin/docker-compose up

[Install]
WantedBy=multi-user.target

ちゃんとソースコードや設定ファイルに明示するようにdocker-composeしてほしいのである。

でないと、まとめて複数起動したときにハマるのである。CI/CDとかでも起きるのである。

sudo -u runner docker-compose up
sudo -u runner docker-compose up

適当にソース渡されて適当にテストしたら思いきりドハマリしたじゃないか。

docker は人類の手に負えない。人間が触るもんじゃない。k8s や portainerなど自動管理するためのものだ。

-p は 一番先頭に付けないと動きません。とか意図しない動作もあるし。docker-composeは両手をあげて初心者に使わせるものじゃないと思うんだ。

docker-composeは思わぬところでハマりますよね。

--profile--project とかさ。もうちょっと何とかならないのかなぁ