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

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

More than 1 year has passed since last update.

背景

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
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
ユーザーは見つかりませんでした