Dockerのネットワーク設計入門|コンテナ間通信とbridge・host・noneの使い分け

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Docker > Dockerのネットワーク設計入門|コンテナ間通信とbridge・host・noneの使い分け
「複数のコンテナを起動したのに、コンテナ同士が通信できない」
「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を別ネットワークに分離するのが基本設計


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

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

Dockerをインストールした直後は、上記の3つのネットワークが自動で作成されています。

デフォルトの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" } } ]

デフォルトbridgeのサブネットは172.17.0.0/16です。ここで重要なのは、このデフォルトbridgeに接続したコンテナはIPアドレスでしか互いに通信できないという点です。コンテナ名での名前解決はできません。

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'

ユーザー定義ネットワークでは、コンテナ名「db」が自動でIPアドレス(172.20.0.3)に解決されています。これがデフォルトbridgeとの最大の違いです。

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

このcompose.ymlで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))

ポートがLISTENされているにもかかわらずアクセスできない場合は、ファイアウォール(firewalldやufwのルール)の設定も確認してください。ポート確認の詳細なコマンドについては以下の記事を参照してください。

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の基礎から実践活用まで、ハンズオン形式で習得できます。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。