docker-compose.ymlを置くフォルダ名を「docker」にするのはやめよう

docker-compose.ymlを置くフォルダ名を「docker」にするのはやめよう


プロジェクト直下にdockerという名前のフォルダを作ってdocker-compose.ymlを置くと、Composeのプロジェクト名がdockerになり、コンテナ名やネットワーク名が紛らわしくなる。実際に何が困るのかと、代わりにどう命名すべきかを整理する。

はじめに

Dockerを使ったプロジェクトを作るとき、リポジトリのルートにdocker/というフォルダを作って、その中にdocker-compose.ymlDockerfileをまとめたくなることがあります。

整理されているようで一見きれいに見えるのですが、これをやると地味に厄介な問題が起きます。

Docker Composeはデフォルトで「docker-compose.ymlが置かれているディレクトリ名」をプロジェクト名として使うため、dockerというフォルダに置いた瞬間、コンテナ名やネットワーク名にdockerという文字列が紛れ込んでくるのです。

何が起きるか

例えば以下のような構成にしたとします。

myapp/
├── docker/
│   └── docker-compose.yml
└── src/

docker/ディレクトリの中でdocker compose up -dを実行すると、コンテナ名は次のようになります。

$ docker compose up -d
$ docker ps
CONTAINER ID   IMAGE          NAMES
xxxxxxxxxxxx   postgres:15    docker-db-1
xxxxxxxxxxxx   myapp:latest   docker-web-1

myapp-web-1myapp-db-1になってほしいところが、すべてdocker-xxx-1になってしまいます。

ネットワーク名も同様です。

$ docker network ls
NETWORK ID     NAME             DRIVER    SCOPE
xxxxxxxxxxxx   docker_default   bridge    local

何が困るか

docker psの結果がそもそも読みにくい

「Dockerコマンドの実行結果」の中に「docker」という名前のコンテナが並ぶので、コマンド名なのか固有名詞なのか頭の中で変換が必要になります。

複数プロジェクトをこの構成で運用していると、すべてのプロジェクトのコンテナがdocker-web-1docker-db-1のような同じ名前になり、docker psを見ても今どのプロジェクトのコンテナを見ているのか分からなくなります。

grepしてもノイズが多すぎる

ログやコンテナ名をdockerという文字列でフィルタしようとしても、Dockerに関する記述・コマンド自体にもdockerという単語が大量に含まれるため、検索性が落ちます。

# これではコンテナ名のdockerなのか、docker関連コマンドの一部なのか判別しづらい
$ docker ps | grep docker

プロジェクト名の衝突

複数のリポジトリで同じようにdocker/というフォルダ名を採用していると、Composeのプロジェクト名(=コンテナ名のプレフィックス)がすべてdockerで揃ってしまい、同じマシン上で複数プロジェクトを動かすと名前が衝突しやすくなります。

対処法

フォルダ名をプロジェクト名にする

最もシンプルな対処は、dockerという汎用的な名前ではなく、プロジェクト名やサービス名をフォルダ名に使うことです。

myapp/
├── infra/          # もしくは deploy/ など
│   └── docker-compose.yml
└── src/

そもそもdocker-compose.ymlを専用フォルダに分ける必要がなければ、リポジトリのルート直下に置いてしまうのも有効です。

myapp/
├── docker-compose.yml
└── src/

COMPOSE_PROJECT_NAMEやnameフィールドで明示する

フォルダ構成は変えられない事情がある場合は、Composeのプロジェクト名を明示的に指定することでも回避できます。

docker-compose.ymlにトップレベルのnameを指定する方法です。

name: myapp

services:
  web:
    build: .
  db:
    image: postgres:15

もしくは.envCOMPOSE_PROJECT_NAMEを定義しておく方法もあります。

# .env
COMPOSE_PROJECT_NAME=myapp

どちらの方法でも、フォルダ名に関係なくコンテナ名はmyapp-web-1myapp-db-1のようになります。

まとめ

  • Docker Composeはデフォルトでdocker-compose.ymlが置かれたディレクトリ名をプロジェクト名として使う
  • フォルダ名をdockerにすると、コンテナ名・ネットワーク名がすべてdocker-xxxになり、紛らわしく検索性も落ちる
  • 対処法は2つ
    • フォルダ名をdockerのような汎用名にせず、プロジェクト名やサービス名にする
    • フォルダ構成を変えられない場合は、nameフィールドやCOMPOSE_PROJECT_NAMEでプロジェクト名を明示する

「整理用のフォルダ名」と「コンテナ名のプレフィックス」が同じ仕組みで決まることを意識して、命名するのが良さそうです。