Compose におけるネットワーク機能

読む時間の目安: 2 分

このページに示す内容は Compose ファイルフォーマットの バージョン 2それ以降 に適用されます。 ネットワーク機能は(非推奨の)バージョン 1 ではサポートされません。

デフォルトで Compose は、アプリ向けに単一の ネットワーク を設定します。 1 つのサービスを構成する各コンテナーは、そのデフォルトのネットワークに参加するので、ネットワーク上の他のコンテナーからのアクセスが可能です。 さらにコンテナー名と同等のホスト名を用いてコンテナーの識別が可能となります。

メモ

アプリのネットワークには「プロジェクト名」に基づいた名前がつけられます。 そしてプロジェクト名はこれが稼動しているディレクトリ名に基づいて定まります。 プロジェクト名は --project-nameフラグ あるいは COMPOSE_PROJECT_NAME環境変数 を使って上書きすることができます。

たとえばアプリがmyappというディレクトリにあって、docker-compose.ymlが以下のような内容であるとします。

version: "3.9"
services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres
    ports:
      - "8001:5432"

docker-compose upを実行すると以下の結果になります。

  1. myapp_defaultというネットワークが生成されます。
  2. webに関する設定に従って 1 つのコンテナーが生成されます。 そしてそのコンテナーはwebという名前でネットワークmyapp_defaultに参加します。
  3. dbに関する設定に従って 1 つのコンテナーが生成されます。 そしてそのコンテナーはdbという名前でネットワークmyapp_defaultに参加します。

v2.1 以降、overlay ネットワークは常にattachable

Compose ファイルフォーマット 2.1 から、overlay ネットワークは常にattachableとして生成されるようになりましたが、これを変更することはできません。 attachableとして生成されるため、スタンドアロンのコンテナーでも overlay ネットワークに接続することができます。 Compose ファイルフォーマット 3.x においては、必要に応じてattachableプロパティにfalseを設定できます。

各コンテナーはこれ以降、ホスト名webdbを認識できるようになり、コンテナーの IP アドレスも適切に取得できるようになります。 たとえばwebのアプリケーションコードでは、URLpostgres://db:5432を使ってのアクセスが可能となり、Postgres データベースの利用ができるようになります。

HOST_PORTCONTAINER_PORTの違いについては理解しておくことが重要です。 上の例のdbでは、HOST_PORT8001、コンテナーポートが 5432(postgres のデフォルト) になっています。 ネットワークにより接続されているサービス間の通信はCONTAINER_PORTを利用します。 HOST_PORTを定義すると、このサービスはスウォームの外からもアクセスが可能になります。

webコンテナー内では、dbへの接続文字列はpostgres://db:5432といったものになります。 そしてホストマシン上からは、その接続文字列はpostgres://{DOCKER_IP}:8001となります。

コンテナーの更新

サービスに対する設定を変更してdocker-compose upにより更新を行うと、それまでのコンテナーは削除されて新しいコンテナーがネットワークに接続されます。 このとき IP アドレスは異なることになりますが、ホスト名は変わりません。 コンテナーの実行によってホスト名による名前解決を行い、新たな IP アドレスへ接続します。 それまでの古い IP アドレスは利用できなくなります。

古いコンテナーに対して接続を行っていたコンテナーがあれば、その接続は切断されます。 この状況を検出するのは各コンテナーの責任であって、ホスト名を探して再接続が行われます。

links は自サービスが他のサービスからアクセスできるように、追加でエイリアスを定義するものです。 これはサービス間の通信を行うために必要となるわけではありません。 デフォルトにおいてサービスは、サービス名を使って他サービスにアクセスできます。 以下の例においては、dbwebからアクセス可能であり、ホスト名dbあるいはdatabaseを使ってアクセスできます。

version: "3.9"
services:

  web:
    build: .
    links:
      - "db:database"
  db:
    image: postgres

詳細は links リファレンス を参照してください。

複数ホストによるネットワーク

Docker Engine 上において Swarm モードの有効化 を行い、Compose アプリケーションをデプロイする際には、ビルトインされているoverlayドライバーを利用して、複数ホスト間での通信が利用可能です。

Swarm モードの節 を参考にして、Swarm クラスターの設定方法を確認してください。 また マルチホストネットワーク を参考にして、マルチホストによる overlay ネットワークについて確認してください。

独自のネットワーク設定

デフォルトのアプリ用ネットワークを利用するのではなく、独自のネットワークを指定することができます。 これは最上位のnetworksキーを使って行います。 これを使えば、より複雑なネットワークトポロジーを生成したり、独自のネットワークドライバー とそのオプションを設定したりすることができます。 さらには、Compose が管理していない、外部に生成されたネットワークに対してサービスを接続することもできます。

サービスレベルの定義となるnetworksキーを利用すれば、サービスごとにどのネットワークに接続するかを指定できます。 指定する値はサービス名のリストであり、最上位のnetworksキーに指定されている値を参照するものです。

以下において Compose ファイルは、独自のネットワークを 2 つ定義しています。 proxyサービスはdbサービスから切り離されています。 というのも両者はネットワークを共有しないためです。 そしてappだけがその両者と通信を行います。

version: "3.9"

services:
  proxy:
    build: ./proxy
    networks:
      - frontend
  app:
    build: ./app
    networks:
      - frontend
      - backend
  db:
    image: postgres
    networks:
      - backend

networks:
  frontend:
    # 独自ドライバーの利用
    driver: custom-driver-1
  backend:
    # 所定のオプションを用いる独自ドライバーの利用
    driver: custom-driver-2
    driver_opts:
      foo: "1"
      bar: "2"

接続するネットワークのそれぞれは、ipv4_address または ipv6_address を使ってスタティック IP アドレスを設定することができます。

ネットワークには 独自の名前 も設定することができます。 (バージョン 3.5 から)

version: "3.9"
services:
  # ...
networks:
  frontend:
    name: custom_frontend
    driver: custom-driver-1

ネットワーク設定に関して利用可能なオプションについては、以下のリファレンスを参照してください。

デフォルトネットワークの設定

独自のネットワーク設定は行わずに、あるいはそれを行った上でさらに、アプリに対するデフォルトネットワークの設定を変更することができます。 これはnetworksのもとにdefaultという項目を定義して行います。

version: "3.9"
services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres

networks:
  default:
    # 独自のドライバーを利用
    driver: custom-driver-1

既存ネットワークの利用

コンテナーを既存のネットワークに接続したい場合は externalオプション を利用します。

services:
  # ...
networks:
  default:
    external:
      name: my-pre-existing-network

Compose は[projectname]_defaultという名前のネットワークを生成しようとはせず、my-pre-existing-networkというネットワークを探し出して、アプリのコンテナーをそこに接続します。

documentation, docs, docker, compose, orchestration, containers, networking