「Docker Composeで組んだWebとDBがつながらず、名前解決でエラーが出る」
こういったトラブルは、Dockerネットワークの仕組みを理解していないことが原因のほとんどです。
Dockerはコンテナ起動時に自動でネットワークへ接続しますが、デフォルトのbridgeネットワークでは「コンテナ名での名前解決」ができません。ここで詰まるエンジニアは非常に多い。
この記事では、Dockerの4つのネットワークモード(bridge・ユーザー定義bridge・host・none)の違いと使い分け、コンテナ間通信の実践手順、Docker Composeでのネットワーク分離設計を、Ubuntu 24.04 LTS / RHEL 9.4の実機出力を交えて解説します。
この記事のポイント
・Dockerデフォルトのbridgeではコンテナ名での名前解決ができない
・コンテナ間を名前で繋ぐには「ユーザー定義bridgeネットワーク」が必須
・Docker Composeは自動でユーザー定義ネットワークを作成しサービス名で通信できる
・本番環境ではfrontend/backendを別ネットワークに分離するのが基本設計
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
Dockerネットワークの基本構造を理解する
コンテナが起動すると、Dockerは内部でveth(仮想Ethernetペア)を作成し、片方をコンテナのネットワーク名前空間に、もう片方をdocker0ブリッジに接続します。このdocker0ブリッジがDockerのデフォルトネットワーク「bridge」です。まずDockerに存在するネットワーク一覧を確認してみましょう。
# Dockerのネットワーク一覧を表示する $ docker network ls NETWORK ID NAME DRIVER SCOPE 3a7b9d2c1e4f bridge bridge local 8f0d4e3b2a1c host host local c1d2e3f4a5b6 none null local
デフォルトのbridgeネットワークの詳細を確認します。
# bridgeネットワークの詳細を確認する $ docker network inspect bridge [ { "Name": "bridge", "Driver": "bridge", "IPAM": { "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Options": { "com.docker.network.bridge.name": "docker0" } } ]
4つのネットワークモードの違いと使い分け
Dockerには主に4種類のネットワークモードがあります。それぞれの特徴を理解して使い分けることが、安定した構成の第一歩です。1. bridge(デフォルト)
Dockerが自動で作成する共有ネットワーク(docker0ブリッジ)です。・全コンテナが同じネットワークに接続される
・コンテナにはIPアドレスが自動で割り当てられる(172.17.0.0/16から)
・コンテナ間の通信はIPアドレス指定が必要(コンテナ名では不可)
・コンテナからインターネットへはNATで出て行ける
用途:動作確認・学習目的。本番環境では後述のユーザー定義bridgeを使うこと。
2. ユーザー定義bridgeネットワーク
docker network createコマンドで作成するカスタムネットワークです。・コンテナ名でDNS名前解決が自動で使える(Docker内蔵DNSサーバーが働く)
・ネットワークを分けることでコンテナグループを論理的に分離できる
・同一ネットワーク内のコンテナだけが通信できるセキュリティ境界を作れる
用途:開発・本番環境での標準的な選択。コンテナ間通信が必要な場合は必ずこれを使う。
3. host
コンテナがホストのネットワーク名前空間を共有するモードです。・コンテナのポートがホストのポートとして直接公開される(-pオプション不要)
・仮想NICやNATのオーバーヘッドがなく、ネットワーク性能が最大限出せる
・Linux専用(macOSやWindowsのDockerでは動作しない)
用途:高スループットが必要な監視エージェント・ネットワークツール・パフォーマンス要件の厳しいサービス。ポートの競合が起きやすいため乱用は避ける。
4. none
コンテナを完全にネットワークから切り離すモードです。・コンテナには
lo(ループバック)のみが設定される・外部との通信が一切できない完全隔離環境になる
用途:ネットワーク不要なバッチ処理、セキュリティテスト、完全オフライン環境でのデータ変換など。
ユーザー定義bridgeでコンテナ間通信を実践する
実際にユーザー定義bridgeネットワークを作成し、コンテナ同士がサービス名で通信できることを確認します。動作確認環境はUbuntu 24.04 LTS + Docker 26.1.4です。1. ユーザー定義ネットワークを作成する
# ユーザー定義bridgeネットワークを作成する $ docker network create my-app-net 9e2f1a3b4c5d8e7f6a2b1c0d9e8f7a6b # 作成を確認する $ docker network ls NETWORK ID NAME DRIVER SCOPE 3a7b9d2c1e4f bridge bridge local 8f0d4e3b2a1c host host local 9e2f1a3b4c5d my-app-net bridge local c1d2e3f4a5b6 none null local
2. コンテナをユーザー定義ネットワークに接続して起動する
# Webコンテナをmy-app-netに接続して起動する $ docker run -d --name web --network my-app-net nginx:alpine # DBコンテナをmy-app-netに接続して起動する $ docker run -d --name db --network my-app-net \ -e POSTGRES_PASSWORD=secret \ postgres:16-alpine # 起動を確認する $ docker ps CONTAINER ID IMAGE CREATED STATUS NAMES a1b2c3d4e5f6 postgres:16-alpine 10 seconds ago Up 9 seconds db f6e5d4c3b2a1 nginx:alpine 20 seconds ago Up 19 seconds web
3. コンテナ名(サービス名)で通信できるか確認する
# webコンテナからdbコンテナへpingする(コンテナ名で通信) $ docker exec web ping db -c 3 PING db (172.20.0.3): 56 data bytes 64 bytes from 172.20.0.3: seq=0 ttl=64 time=0.124 ms 64 bytes from 172.20.0.3: seq=1 ttl=64 time=0.089 ms 64 bytes from 172.20.0.3: seq=2 ttl=64 time=0.102 ms --- db ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss # 参考:デフォルトbridgeではコンテナ名で通信できない # (上記と同じ操作をデフォルトbridgeで試すとエラーになる) # ping: bad address 'db'
Docker Composeでのネットワーク設計
Docker Composeは内部でユーザー定義bridgeネットワークを自動作成するため、サービス名でのDNS名前解決がデフォルトで使えます。1. デフォルトネットワークとサービス名解決
Composeでcompose.ymlを実行すると、プロジェクト名_defaultというネットワークが自動で作成されます。# compose.yml(最小構成:webとdbの2サービス) services: web: image: nginx:alpine ports: - "8080:80" db: image: postgres:16-alpine environment: POSTGRES_PASSWORD: secret
docker compose up -dを実行すると、webサービスはDBに接続する際に「db」というホスト名でアクセスできます。アプリの接続文字列にはhost=dbと書けばよいため、IPアドレスを調べる必要がありません。ネットワークの自動作成を確認します。
$ docker compose up -d [+] Running 3/3 ✔ Network myapp_default Created 0.1s ✔ Container myapp-db-1 Started 1.2s ✔ Container myapp-web-1 Started 1.3s $ docker network ls | grep myapp a2b3c4d5e6f7 myapp_default bridge local
2. フロントとバックを分けるネットワーク分離設計
本番環境では、外部に公開するフロントエンドネットワークと、DBなど内部処理のバックエンドネットワークを分離するのが基本設計です。以下の構成にすると、dbサービスはfrontendネットワークに属さないため、外部からは直接到達できません。
# compose.yml(ネットワーク分離設計) services: web: image: nginx:alpine ports: - "80:80" networks: - frontend - backend app: image: myapp:latest networks: - backend db: image: postgres:16-alpine environment: POSTGRES_PASSWORD: secret networks: - backend networks: frontend: driver: bridge backend: driver: bridge
・web(リバースプロキシ):frontendとbackend両方に参加し、外部リクエストをappへ転送する
・app(アプリケーション):backendネットワークのみ参加。DBにアクセスできる
・db:backendネットワークのみ参加。外部(frontend側)からは直接到達できない
この設計にすることで、dbとappが外部ネットワークに露出するリスクを最小化できます。セミナーでも「Composeを使い始めたらまずnetworksセクションを書く習慣を」と伝えています。
【注意】networkを指定し忘れた場合の罠
compose.ymlでnetworksセクションを定義していても、各serviceのnetworksキーで明示的に指定し忘れると、そのサービスはデフォルトネットワーク(プロジェクト名_default)にのみ接続されてしまいます。
docker compose up後にdocker network inspectでコンテナの接続先を必ず確認する習慣をつけてください。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、コンテナの概念を理解したら、実際に手を動かすのが一番の近道です。Dockerのインストールから実践的な活用方法まで体系的に学ぶには、Docker実践講座(linuxmaster.jp)をご活用ください。現役エンジニアが教える、現場で使える技術を習得できます。
「コンテナ間で通信できない」時のトラブルシュート
コンテナがどのネットワークに接続されているか確認する
まずコンテナのネットワーク接続状態を確認します。# コンテナのネットワーク接続状態を確認する $ docker inspect --format '{{range $k, $v := .NetworkSettings.Networks}}{{$k}} {{end}}' コンテナ名 my-app-net # ネットワーク側からコンテナ一覧を確認する $ docker network inspect my-app-net --format '{{range .Containers}}{{.Name}} {{end}}' web db
コンテナをユーザー定義ネットワークに追加する
既存のコンテナをユーザー定義ネットワークに後から追加するにはdocker network connectを使います。# 既存コンテナをユーザー定義ネットワークに追加する $ docker network connect my-app-net コンテナ名 # 不要なネットワークから切り離す場合 $ docker network disconnect bridge コンテナ名
ポートが外部からアクセスできない時の確認手順
ポート公開の設定と実際のLISTEN状態を確認します。# コンテナのポートマッピングを確認する $ docker port コンテナ名 80/tcp -> 0.0.0.0:8080 # ホスト側でポートがLISTENされているか確認する $ ss -tlnp | grep 8080 LISTEN 0 4096 0.0.0.0:8080 0.0.0.0:* users:(("docker-proxy",pid=12345,fd=4))
・Linux ポート確認の全コマンド|ss・lsof・netstatの使い分け
本記事のまとめ
Dockerのネットワークモードと用途の早見表です。| ネットワークモード | コンテナ名での名前解決 | 主な用途 |
|---|---|---|
| bridge(デフォルト) | 不可 | 学習・動作確認 |
| ユーザー定義bridge | 可 | 開発・本番環境の標準構成 |
| host | 不要(ホストと共有) | 高パフォーマンス・監視ツール |
| none | 不可(完全分離) | バッチ・セキュリティテスト |
・デフォルトbridgeではコンテナ名通信はできないと覚えておく
・
docker network createでユーザー定義ネットワークを作成して接続する・Docker Composeを使うと自動でユーザー定義ネットワークが作られてサービス名が使える
・本番環境はfrontend/backendネットワーク分離でDBを外部から保護する
次に読む記事
・Linux DNS 設定の基本|resolv.confとnmcliの設定方法
・Linux ポート確認の全コマンド|ss・lsof・netstatの使い分け
Dockerをゼロから体系的に学びたい方は、Docker実践講座(linuxmaster.jp)をご覧ください。現役エンジニアが現場目線で教えるDockerの基礎から実践活用まで、ハンズオン形式で習得できます。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 次のページへ:docker execコマンドでコンテナ内を調査・デバッグする方法|docker logs・docker inspectの実践例も
- 前のページへ:Dockerボリュームとバインドマウントでデータを永続化する方法|コンテナを消してもデータを守る設計
- この記事の属するカテゴリ:Dockerへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます