Edited at

docker-composeで作成されるものの名前を明示的に指定する方法


背景

docker-composeを利用するときに、コンテナ・ホスト名・データボリューム・ネットワーク名などの名前を指定しないと、自動的に名前が生成される。

あくまでも個人的な見解だが、ルールを覚えない限りは以下のような面倒な点があると考える。


  • 作成されたものの名前を確認する必要がある。

  • 意図せずにデフォルトネットワークが作られる。

  • コンテナ間通信するときのFQDNはコンテナ名がわからない。(これについては別ページで別途記載するが、サービス名でも通信できた)

  • 自動生成されたデータボリュームがわからないので紐づけを確認する必要がある。

    コンテナとデータボリュームの関係を確認するには以下の方法があるが、どちらもコマンド自体覚えるのが面倒。(他にもあるかもしれないし、alias作れと言われればその通りだが、ある程度覚えておかないと新しい環境で再度aliasの設定内容を調べないといけない)


    • docker inspect ${コンテナ名} | jq .[0].Mounts

    • docker ps --format "table {{.Names}}\t{{.Mounts}}"



docker-compose.ymlのバージョン3.5からネットワーク名も指定してできるようになって、全部解消したのでここにまとめます。


目的(ゴール)


  • 基本的に作成されるものの名前は全部、docker-compose.ymlで事前に定義できるようにする。

  • docker-composeコマンド実行時に作成されていないデータボリュームやネットワークが自動生成されること。

  • 意図しないデフォルトネットワークなどが作成されないこと。


前提とする環境


  • DockerホストOS:CentOS7

  • Docker version 18.09.6, build 481bc77156

  • docker-compose version 1.24.0, build 0aa59064

  • docker-compose.ymlのバージョン:3.5


シンプルな定義で作成される名前

docker-composeを利用する場合に特に名前を指定しないと、以下のようになる。


  • コンテナ名 => ${プロジェクト名}${サービス名}${連番}

  • ホスト名 => CONTAINER ID

  • データボリューム名 => 任意のID(たぶんuuidのハイフン無し版)

  • ネットワーク名 => ${プロジェクト名}}_default(networksを定義しない場合)

※1.プロジェクト名とは、、、


  • デフォルトではdockse-compose.ymlのカレントディレクトリ名


  • docker-compose -p ${プロジェクト名}で上書きできる。

  • 環境変数"COMPOSE_PROJECT_NAME"で上書きできる。

以下に違いをわかりやすくするために、シンプルなもので作成してみた結果を記載する。


docker-compose.yml

version: '3.5'

services:
web:
image: nginx:stable-alpine

db:
image: postgres:alpine


作成結果を確認する。


結果

[docker-user@docker-host test]$ docker-compose up -d

Creating network "test_default" with the default driver
Creating test_web_1 ... done
Creating test_db_1 ... done
[docker-user@docker-host test]$ docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Networks}}\t{{.Mounts}}"
CONTAINER ID NAMES IMAGE NETWORKS MOUNTS
3b4634c1b885 test_web_1 nginx:stable-alpine test_default
09ab8eb433a8 test_db_1 postgres:alpine test_default 4f6e06816684d8…
[docker-user@docker-host test]$ docker volume ls
DRIVER VOLUME NAME
local 4f6e06816684d8e22994e30e7b4bbdce9a51a889e1b021c021f33a0326c36709
[docker-user@docker-host test]$ docker network ls
NETWORK ID NAME DRIVER SCOPE
18b99de55ca4 bridge bridge local
09fbaf5da94d host host local
b5252395c879 none null local
ff1019402a0f test_default bridge local
[docker-user@docker-host test]$

無いものを自動生成してくれるのはありがたいが、勝手に名前が付くとdockerコマンドで作ったものなのか、自動生成されたものなか、何で使われているのかをいちいち調べるのが面倒!!


すべての名前を明確に定義する方法(結論)

いろいろ過去の経緯を書こうと思ったが、面倒なので結論だけ書きます。

以下、サービス名とコンテナ名/ホスト名、docker-compose.yml上のボリューム識別子・ネットワーク識別子などは名前を同じにした方が理想的ですが、わかりやすくするためにあえて、別の名前にしています。


docker-compose.yml

version: '3.5'

services:
web:
image: nginx:stable-alpine
# コンテナ名を明示的に指定する
container_name: web-container
# ホスト名を明示的に指定する
hostname: web-server
ports:
- 80:80
restart: always
# 明示的に所属するネットワークを指定する
networks:
# ここに指定するのは実際のネットワーク名ではなく、↓のnetworksの識別子
- container-link

db:
image: postgres:alpine
# コンテナ名を明示的に指定する
container_name: db-container
# ホスト名を明示的に指定する
hostname: db-server
ports:
- 5432:5432
restart: always
# 明示的に所属するネットワークを指定する
networks:
# ここに指定するのは実際のネットワーク名ではなく、↓のnetworksの識別子
- container-link
volumes:
# ここに指定するのは実際のボリューム名ではなく、↓のvolumesの識別子
- postgres-data-volume:/var/lib/postgresql/data:rw

# ネットワーク定義
networks:
# docker-composeで勝手にデフォルトネットワークが生成される予防。(自動で全コンテナが所属するbridgeを指定)
default:
external:
name: bridge
# コンテナ間通信用のネットワークセグメント
container-link:
# これが作成されるネットワーク名(同名がなければ自動生成される)
name: docker.internal
# 以下は書かなくてもよい(サンプルとして)
driver: bridge
ipam:
driver: default
config:
- subnet: "172.20.100.0/24"

volumes:
# postgresコンテナのデータ永続化用のデータボリューム(同名がなければ自動生成される)
postgres-data-volume:
name: postgres-data
driver: local


作成結果を確認する。

起動する。

[docker-user@docker-host test]$ docker-compose up -d

Creating network "docker.internal" with driver "bridge"
Creating volume "postgres-data" with local driver
Creating web-container ... done
Creating db-container ... done

コンテナ・ネットワーク・データボリュームが作られた。

コンテナを確認する。

[docker-user@docker-host test]$ docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Networks}}\t{{.Mounts}}"

CONTAINER ID NAMES IMAGE NETWORKS MOUNTS
12749a07b048 web-container nginx:stable-alpine docker.internal
9e6356b75522 db-container postgres:alpine docker.internal postgres-data

コンテナのホスト名を確認する。

[docker-user@docker-host test]$ docker exec web-container hostname

web-server
[docker-user@docker-host test]$ docker exec db-container hostname
db-server

データボリュームを確認する。

[docker-user@docker-host test]$ docker volume ls

DRIVER VOLUME NAME
local postgres-data
[docker-user@docker-host test]$ docker volume inspect postgres-data
[
{
"CreatedAt": "2019-05-23T13:04:36+09:00",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "test",
"com.docker.compose.version": "1.24.0",
"com.docker.compose.volume": "postgres-data"
},
"Mountpoint": "/var/lib/docker/volumes/postgres-data/_data",
"Name": "postgres-data",
"Options": null,
"Scope": "local"
}
]

ネットワークを確認する。

[vagrant@docker-host test]$ docker network ls

NETWORK ID NAME DRIVER SCOPE
18b99de55ca4 bridge bridge local
60ecb2f64e55 docker.internal bridge local
09fbaf5da94d host host local
b5252395c879 none null local
[vagrant@docker-host test]$ docker network inspect docker.internal | jq .[0].Containers
{
"12749a07b048f8135e0f6e0d80269f04c5ed8f7f6652703566076d478d31ef37": {
"Name": "web-container",
"EndpointID": "c93123b6c2e1005857753f4508a7bdb40c5a73d5211932de9e0cc80854809f00",
"MacAddress": "02:42:ac:14:64:03",
"IPv4Address": "172.20.100.3/24",
"IPv6Address": ""
},
"9e6356b75522ed423ec561a0d2c9dc4a1d3b5056c00f5f781800b1891d0e4a11": {
"Name": "db-container",
"EndpointID": "6c83fd8ec9b3080d928cc73cda6f26da639172be40116ef7118bc2806be19879",
"MacAddress": "02:42:ac:14:64:02",
"IPv4Address": "172.20.100.2/24",
"IPv6Address": ""
}
}

コンテナ間通信を確認する。

[vagrant@docker-host test]$ docker exec web-container ping -c 1 db-container.docker.internal

PING db-container.docker.internal (172.20.100.2): 56 data bytes
64 bytes from 172.20.100.2: seq=0 ttl=64 time=0.062 ms

--- db-container.docker.internal ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.062/0.062/0.062 ms
[vagrant@docker-host test]$ docker exec db-container ping -c 1 web-container.docker.internal
PING web-container.docker.internal (172.20.100.3): 56 data bytes
64 bytes from 172.20.100.3: seq=0 ttl=64 time=0.060 ms

--- web-container.docker.internal ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.060/0.060/0.060 ms