コンテナを2つ起動したのに、お互いに通信できない。そんな経験はありませんか。
Dockerのネットワークは、bridge・host・noneという3種類の仕組みを理解すれば迷わなくなります。
コンテナ同士はカスタムbridgeに参加させればコンテナ名で通信でき、ホストのブラウザから開くには-p ホスト:コンテナでポートフォワードします。繋がらないときは、ネットワークの参加状況とポートの割り当て(docker ps・docker port)を順に確認すれば原因を絞り込めます。
読み終える頃には、ネットワーク周りのエラーに落ち着いて対処できるようになっているはずです。
この記事でわかること
- bridge・host・noneネットワークの違いと使い分け
docker networkコマンドの基本操作-p・EXPOSE・portsの違いと、ポートフォワード(ポートマッピング)の書き方・確認方法- コンテナ同士が繋がらない・localhostにアクセスできないときの対処法
- Docker Composeでのネットワーク・ポート設定と、本番環境でのポート設計
PARTS LIST /目次
Dockerネットワークとは?コンテナ間通信の仕組み
Dockerネットワークとは、コンテナ同士やコンテナとホストが通信するための仮想的な通信経路です。
コンテナは通常、ホストOSから隔離された環境で動きます。そのままではコンテナ同士は互いの存在を知りません。
ネットワークという共通の土台を用意することで、初めてコンテナ間の通信が成立します。
なぜコンテナにネットワークが必要なのか
複数のコンテナで1つのアプリケーションを構築する場面は珍しくありません。Webサーバーとデータベースを別コンテナで動かす構成が代表例です。
この場合、WebサーバーのコンテナからデータベースのコンテナへSQLを送る通信経路が必要になります。
ネットワークが無ければ、コンテナはそれぞれ孤立した箱のままです。
Dockerが自動作成する3種類のネットワーク
Dockerをインストールすると、bridge・host・noneという3種類のネットワークが最初から用意されます。
docker network lsコマンドを実行すれば、この3つが確認できます。
何も指定せずにコンテナを起動すると、自動的にbridgeネットワークに接続される仕組みです。
docker network ls
bridgeデフォルト(何も指定しないとここ)hostnonedocker network ls でこの3つを確認できます。実務で使うのはほぼ bridge(自分で作るカスタムbridge)です。bridgeネットワークの仕組みと使い方
bridgeは、Dockerで最もよく使うネットワークモードです。
コンテナごとに仮想的なIPアドレスが割り当てられ、同じbridgeネットワーク内のコンテナ同士が通信できます。
docker0と仮想NIC(veth)の仕組み
bridgeネットワークの正体は、ホスト上に作られる仮想的なスイッチです。デフォルトbridgeの場合、Linuxホストにはdocker0という名前の仮想ブリッジが作られます。
コンテナを起動すると、vethと呼ばれる仮想NICのペアが1組作られます。片方はコンテナ内のeth0になり、もう片方はdocker0に接続されます。LANケーブルでスイッチにつなぐイメージです。
- IPアドレス:デフォルトbridgeでは、通常
172.17.0.0/16の範囲からコンテナにIPが割り当てられます。 - コンテナから外への通信:ホストのNAT(iptablesのルール)を経由して、インターネットなどへ出ていきます。
- 外からコンテナへの通信:
-pで開けたポートだけが、ホストからコンテナへ転送されます。
Linuxホストなら、次のコマンドでdocker0の存在とIPアドレスを確認できます。Docker Desktop(Mac・Windows)では、docker0はDockerが内部で動かしている仮想マシンの中にあるため、ホスト側からは見えません。
ip addr show docker0
デフォルトbridgeとカスタムbridgeの違い
Dockerインストール時に自動生成されるbridgeネットワークは「デフォルトbridge」と呼ばれます。
一方、docker network createで自分で作成するネットワークは「カスタムbridge」です。
両者の最大の違いは名前解決の可否にあります。
デフォルトbridgeではコンテナ名での通信ができませんが、カスタムbridgeなら可能です。実務ではほぼ確実にカスタムbridgeを使います。
コンテナ名で通信できる内蔵DNSの仕組み
カスタムbridgeネットワークには、Dockerの内蔵DNSサーバーが組み込まれています。
同じネットワークに参加しているコンテナは、IPアドレスを意識せずコンテナ名だけで相手に到達できます。
たとえばwebコンテナからdbコンテナへ接続する場合、IPアドレスの代わりにdbという名前を指定するだけで済みます。
この仕組みのおかげで、コンテナを作り直してIPアドレスが変わっても、接続先の設定を書き換える必要がありません。
docker network create my-network
docker run -d --name db --network my-network mysql:8
docker run -d --name web --network my-network nginx
bridgeDockerインストール時に自動でできるネットワーク✕ コンテナ名では名前解決できない(内蔵DNSが働かない)my-networkdocker network create で自分で作るネットワーク○ web から db:3306 のようにコンテナ名で接続できる(内蔵DNSが名前解決)host・none・overlayネットワークの使いどころ
bridge以外の2つのモードは、使う場面が限定的です。それぞれの特性を理解しておくと、想定外の挙動に振り回されずに済みます。
hostネットワークが向いている場面
hostネットワークは、コンテナがホストOSのネットワークをそのまま共有するモードです。
ポートマッピング(-pオプション)が不要になり、通信のオーバーヘッドも減ります。
高いパフォーマンスが求められる場面や、ポート番号を細かく制御したい場面に向いています。
ただし複数のコンテナで同じポートを使えなくなる制約があるため、常用には向きません。
noneネットワークを使う理由
noneネットワークは、ネットワーク機能を一切持たないモードです。
外部との通信を完全に遮断したいバッチ処理や、セキュリティ検証用のコンテナで使われます。
用途は限られますが、「外に一切繋げたくない」という要件がある場合の選択肢として覚えておく価値があります。
overlayネットワーク
overlayは、複数のDockerホストにまたがるコンテナ同士を通信させるモードです。1台のマシン内で完結するbridgeとは異なります。
Docker Swarmのようなクラスタ環境で、複数サーバー上のコンテナを連携させる場面に向いています。Kubernetesはこのoverlayではなく、CNIプラグインという別の仕組みでネットワークを作ります。
単一ホストでの開発では出番が少ないため、まずbridgeの理解を優先し、複数ホスト構成が必要になった段階で検討すれば十分です。
Dockerのポート設定|-p・EXPOSE・portsの違い
ネットワークが繋がっていても、ホストPCのブラウザなど外からコンテナに届かせるには、ポートの設定が必要です。Dockerのポートとは、コンテナとホストPCをつなぐ窓口のことです。ここでは、-pとEXPOSEの違いから、ポートの指定方法までを整理します。
なぜポート設定が必要なのか|ホストポートとコンテナポート
コンテナは、デフォルトでは外部から隔離され、独自のネットワーク空間を持っています。コンテナ内でNginxなどを起動しても、そのままではPCのブラウザからアクセスできません。
そこで、コンテナの窓口とPCの窓口を意図的につなぎます。この作業を「ポートフォワーディング」または「ポートマッピング」と呼びます。
- ホストポート:あなたのPCが持つポート番号です。
localhost:8080の8080がこれにあたり、ホストPC上で重複できません。 - コンテナポート:コンテナ内のアプリが待ち受けているポート番号です。HTTPの80番やHTTPSの443番などで、イメージによって決まっていることが多いです。
ポート設定とは、この2つを「ホスト:コンテナ」の形で紐付ける作業です。
-p 8080:80でWebコンテナを公開したときの通信経路を図にすると、次のようになります。ホストから入る通信だけがポートフォワードを通り、同じネットワーク内のコンテナ同士はコンテナポートへ直接つながる点がポイントです。
localhost:8080-p 8080:80 でコンテナの80番へ転送http://web:80 で直接つながる(-p 不要)✕ localhost:80 では届かない(ホスト側は80番を公開していない)
EXPOSE・-p・--publishの違い
ポート設定で混乱しやすいのが、この3つのキーワードです。似ているようで、役割がはっきり違います。
- EXPOSE:Dockerfileに書く命令です。「このコンテナはこのポートで通信する予定です」という意思表示にすぎず、書いただけではホストからアクセスできるようになりません。
- -p:
docker runのオプションで、実際にホストポートとコンテナポートをマッピングします。EXPOSEがなくても、-pを使えば公開できます。 - --publish:
-pの正式名称(ロング形式)です。機能はまったく同じです。
コンテナを外部に公開したいときは、-p(または--publish)を使います。Composeではportsがこれにあたります。EXPOSEは、あくまで設計上の目安です。
docker runの-pでポートフォワードする書き方
OPTION / docker run のオプション
-p 80801:802
↓ ホストの8080番への通信を、コンテナの80番へ転送する
MEANING / それぞれの意味
基本の書式は、-p <ホストポート>:<コンテナポート>です。「ホストPCの指定ポートへのアクセスを、コンテナの指定ポートへ転送する」という意味になります。
docker run -d -p 8080:80 nginx
実行後にブラウザでhttp://localhost:8080を開くと、Nginxの「Welcome to nginx!」ページが表示されます。-p 3000:80ならhttp://localhost:3000です。ホストポートは、空いていればどの番号でも構いません。
ポート番号やIPを省いた書き方もあります。
-p 80・-p :80:コンテナポートだけを指定します。ホスト側のポートは、Dockerが空いている番号(通常は32768以上)から自動で割り当てます。割り当てられた番号はdocker psで確認します。-P(大文字):EXPOSEされているポートを、すべてホスト側の自動割り当てで公開します。複数のコンテナを同時に起動するテストで、ポート競合を避けたいときに便利です。-p 127.0.0.1:8080:80:ホストのIPを指定します。この例では、ホストPCのlocalhostからだけコンテナにつながります。IPを省略すると0.0.0.0(すべてのIP)になり、外部ネットワークからもアクセスできます。- 複数ポート:
-pを複数回指定します。docker run -d -p 8080:80 -p 8443:443 my-web-serverのように書きます。ホストポートは、すべて異なる番号にします。
$ docker ps
CONTAINER ID IMAGE ... PORTS
a1b2c3d4e5f6 nginx ... 0.0.0.0:32768->80/tcp
公開ポートを確認する(docker port)
起動中のコンテナで、どのホストポートがどのコンテナポートにつながっているかはdocker portで確認できます。docker psは全コンテナの一覧ですが、docker portは1つのコンテナのポートフォワードだけを見られます。
docker port my-nginx
docker port my-nginx 80
1行目はそのコンテナのすべてのマッピングを、2行目はコンテナの80番がホストのどこにつながっているかだけを表示します。出力は次のような形式です。
80/tcp -> 0.0.0.0:8080
80/tcp -> [::]:8080
IPv6が有効な環境では、[::]の行も一緒に表示されます。-Pや-p 80でホストポートを自動割り当てにしたときも、このコマンドで実際の番号を調べられます。何も表示されなければ、そのコンテナはポートを公開していません。
docker networkコマンドの基本操作
ネットワークの操作はすべてdocker networkコマンドから行います。
確認・作成・削除の3パターンを押さえれば、日常的な作業はほぼカバーできます。
ネットワークの確認(ls・inspect)
docker network lsで存在するネットワークの一覧を確認できます。
特定のネットワークに参加しているコンテナやIPアドレスの詳細を見たい場合は、docker network inspectを使います。
トラブルシューティングの際、まず最初に叩くコマンドです。
docker network ls
docker network inspect my-network
ネットワークの作成・接続(create・connect)
新しいネットワークはdocker network createで作成します。
既に起動しているコンテナを後からネットワークに参加させたい場合はdocker network connectを使います。
コンテナを作り直さずにネットワーク構成を変えられるため、運用中のサービスにも安全に適用できます。
docker network create app-network
docker network connect app-network web
不要なネットワークの削除(rm・prune)
使わなくなったネットワークはdocker network rmで個別に削除できます。
コンテナが1つも接続していない未使用ネットワークをまとめて掃除したい場合は、docker network pruneが便利です。
開発環境で検証用のネットワークが溜まってきたときに使うと、一気に整理できます。
docker network rm app-network
docker network prune
検証用にコンテナを1つ起動するだけの場合でも、最初からカスタムbridgeを作っておくのがおすすめです。あとから複数コンテナ構成に発展させる場面が多く、最初にデフォルトbridgeで動かすと、名前解決ができず構成を作り直すことになるためです。
Dockerが繋がらないときの対処法
繋がらない原因の多くは、ネットワーク未接続か名前解決の失敗のどちらかです。順を追って確認すれば、たいてい数分で原因が特定できます。
IPアドレスとDNS名解決を確認する手順
まずdocker network inspectで、両方のコンテナが同じネットワークに参加しているかを確認します。
参加していれば、片方のコンテナからpingやコンテナ名でのアクセスを試し、名前解決ができているかを見ます。
名前解決が失敗する場合は、デフォルトbridgeを使っている可能性が高いです。
デフォルトbridgeは内蔵DNSが働かないため、カスタムbridgeへの切り替えで解決することがほとんどです。
localhostにアクセスできないときの原因
docker run -p 8080:80 ...を実行したのに、ブラウザでhttp://localhost:8080を開いても繋がらない。これは最も多いトラブルです。原因は、次のどれかであることがほとんどです。
- コンテナ内のアプリが起動していない:ポートマッピングが正常でも、Webサーバーが起動に失敗していることがあります。
docker logs <コンテナ名>でログを確認します。 - アプリが127.0.0.1で待ち受けている:ポートフォワーディングは、コンテナの外から中への通信です。アプリがコンテナ内の
127.0.0.1でしか待っていないと、外からの通信を受け付けません。0.0.0.0で待ち受けるよう設定します(Flaskならapp.run(host='0.0.0.0')、Node.jsならserver.listen(PORT, '0.0.0.0'))。 - ファイアウォールがブロックしている:ホストPCのファイアウォールが、ホストポートへのアクセスを止めている場合があります。切り分けのため一時的に無効にして試し、繋がるなら許可ルールを追加します。
まずdocker psを実行し、PORTS欄が意図したマッピング(例:0.0.0.0:8080->80/tcp)になっているかを確認します。80/tcpのようにホスト側の表示がなければ、マッピングされていません。
-p 8080:800.0.0.00.0.0.0-p 8080:80アプリが 127.0.0.1127.0.0.10.0.0.0 で待ち受ける必要があります。ポート番号は記事中の例(-p 8080:80)です。ポートがすでに使われているときの対処法
docker runで、次のようなエラーが出ることがあります。ホストポートの8080番を、すでに別のコンテナが使っているという意味です。
docker: Error response from daemon: driver failed programming external connectivity ...
Bind for 0.0.0.0:8080 failed: port is already allocated.
コンテナではなく、Dockerが動いているホスト上の別のプロセス(Webサーバーなど)が8080番を使っている場合は、末尾がError starting userland proxy: listen tcp4 0.0.0.0:8080: bind: address already in use.という文言になります(Docker 26.1で確認)。どちらも対処は同じです。
- 使用中のプロセスを特定して止める:macOS・Linuxなら
sudo lsof -i :8080、Windowsならnetstat -aon | findstr ":8080"で調べます。停止し忘れた別のコンテナが原因なら、docker psで確認して止めます。 - 別のホストポートを使う:止められない場合は、
-p 8081:80のようにホストポート(左側)を変更します。この場合、アクセス先はhttp://localhost:8081になります。
ポートを後から変更したい・反映されないとき
-pで指定したポートマッピングは、コンテナの作成時に決まります。docker stopしてからdocker startで再起動しても、ポート設定は変わりません。
設定を変えたいときは、古いコンテナをdocker rmで削除し、新しい設定でdocker runし直します。docker runは、常に新しいコンテナを作るコマンドだと意識しておくと迷いません。
よくある設定ミスと対処法
実務でよく見る設定ミスを一覧にまとめます。
Docker Composeでのネットワーク・ポート設定
docker-compose.ymlで複数サービスを定義すると、Composeが自動的に専用のカスタムbridgeネットワークを作成します。
同じComposeファイル内のサービス同士は、サービス名だけで通信できます。
個別にdocker network createを実行する必要はありません。
既存の外部ネットワークに参加させたい場合は、networksセクションでexternal: trueを指定します。
services:
web:
image: nginx
networks:
- app-network
db:
image: mysql:8
networks:
- app-network
networks:
app-network:
driver: bridge
portsセクションの書き方
ポートマッピングは、各サービスの下にports:を追加して書きます。docker run -pとほぼ同じ書式を、YAMLのリスト形式で記述します。ポート番号は、引用符で囲んで書くのが安全です。
services:
web:
image: nginx
ports:
- "8080:80" # ホスト8080 → コンテナ80
- "127.0.0.1:8443:443" # localhostからのみ
portsとexposeの違い
docker-compose.ymlにはexpose:もあり、DockerfileのEXPOSEに似た役割を持ちます。
- ports:ホストPCとコンテナを接続します。ホストのポートを占有し、ホストPCからアクセスできるようになります。
- expose:同じネットワーク内の他のコンテナ向けに「このポートを使う」と宣言します。ホストのポートは占有せず、ホストPCからは直接アクセスできません。なお、同じネットワーク内であれば、
exposeを書かなくてもコンテナ同士は通信できます。
たとえばdbサービスにexpose: ["3306"]だけを設定しても、ホストPCからは届きません。webコンテナからdb:3306で届くのは、exposeを書かなくても同じネットワークなら同じです。ブラウザからアクセスさせたいポートはports、コンテナ同士だけで使うポートはportsを書かず、必要ならexposeで用途を示すだけにします。
環境ごとにポート番号を切り替える
開発環境では8080番、ステージング環境では9000番、といった切り替えは、環境変数で行うのが一般的です。プロジェクトのルートに.envを作り、変数を定義します。
WEB_HOST_PORT=8080
docker-compose.ymlのports:では、${変数名}で参照します。
services:
web:
image: nginx
ports:
- "${WEB_HOST_PORT}:80"
docker compose upを実行すると、Composeが.envを自動で読み込み、8080:80として解釈します。環境ごとの.envを差し替えるだけで、docker-compose.yml本体は直さずに済みます。
本番環境でのポート設計と競合の防ぎ方
開発環境ではlocalhost:8080のような設定で足りますが、本番環境では、セキュリティと拡張性を考えたポート設計が欠かせません。ここでは、不要なポートを開けない原則と、リバースプロキシの構成、複数プロジェクトでのポート競合の防ぎ方をまとめます。
不要なポートを開けない
本番環境の最大の原則は、不要なポートを公開しないことです。デバッグ用のポート(9229など)や、データベース(3306・5432)、キャッシュ(6379)のポートを、portsで本番サーバーのグローバルIPに公開してはいけません。攻撃者の格好の標的になります。
- portsは必要最小限に:ユーザーにWebページを見せるHTTP(80)とHTTPS(443)以外は、原則としてホストにマッピングしません。
- exposeと内部ネットワークを使う:データベースやキャッシュは
portsを書かず、Composeが作る内部ネットワーク内だけで通信させます(exposeは用途を示す宣言です)。 - ホストIPを指定する:どうしてもホストに出す必要があるポートは、
0.0.0.0ではなくports: ["127.0.0.1:2222:22"]のようにIPをバインドします。
Nginxなどのリバースプロキシで入口を1つにする
本番環境では、アプリのコンテナ(Node.js・Python・Rubyなど)を直接インターネットに公開することは稀です。手前にNginxやApacheを「リバースプロキシ」として置き、外からのHTTP・HTTPSをすべて受けます。
- プロキシ(Nginx)のコンテナ:
ports: ["80:80", "443:443"]で、インターネットへの唯一の窓口にします。 - アプリのコンテナ:
portsは使いません。portsを書かなければ、内部ネットワークのNginxからだけapp:3000で届きます(expose: ["3000"]は用途を示す宣言として書けます)。 - Nginxの設定:
nginx.confで、リクエストをhttp://app:3000(appはComposeのサービス名)へプロキシします。
この構成なら、アプリのコンテナは外部ネットワークから隠れます。SSLの処理や負荷分散も、プロキシに集約できます。
複数プロジェクトでのポート競合を防ぐコツ
1台のマシンで複数のプロジェクトを動かすと、ホストポートの競合が頻発します。防ぐ方法は、次の3つです。
- .envでポートを管理する:ホストポートを
docker-compose.ymlに直書きせず、${WEB_PORT}で参照します。プロジェクトAは8080、Bは8081のように、.envだけで変えます。 - ポート番号に規則を持たせる:プロジェクトAは10000番台、Bは11000番台のように決めると、番号を見るだけでどのプロジェクトか分かります。
- リバースプロキシに集約する:開発環境でも、全体の前にプロキシを1つだけ置き、
a.localhost・b.localhostのようにホスト名で振り分けます。各プロジェクトはホストポートを公開しないので、競合は根本からなくなります。
Dockerネットワーク・ポート設定に関するよくある質問
Q1. どちらのbridgeを使うべき?
A1. 基本的にはカスタムbridgeを使ってください。コンテナ名での名前解決ができるため、IPアドレスの変動を気にせず運用できます。
Q2. 複数のネットワークに参加できる?
A2. できます。docker network connectを複数回実行すれば、1つのコンテナを複数のネットワークに同時に参加させられます。フロントエンド用とバックエンド用でネットワークを分離したい場合に使う手法です。
Q3. overlayとbridgeの違いは?
A3. bridgeは1台のDockerホスト内で完結する通信方式です。overlayは複数のDockerホストにまたがるコンテナ同士を通信させる方式で、Docker Swarmのようなクラスタ環境で使います(Kubernetesは別の仕組みのCNIプラグインを使います)。単一ホストでの開発では、まずbridgeの理解を優先してください。
Q4. pruneで消える対象は?
A4. どのコンテナにも接続されていない未使用ネットワークだけが削除されます。稼働中のコンテナが参加しているネットワークは対象外なので、通常の運用中に実行しても問題ありません。
Q5. localhostでアクセスできないのはなぜ?
A5. コンテナはホストとは別のネットワーク空間で動くため、ポートマッピング(-p)を指定しない限り、ホストのlocalhostからは届きません。-p 8080:80のように、ホスト側とコンテナ側のポートを明示的に紐付けます。マッピング済みなのに繋がらない場合は、コンテナ内アプリの起動失敗、127.0.0.1での待ち受け、ファイアウォールのブロックを疑います。
Q6. Dockerの-pオプションの書式は何ですか?
A6. 「-p ホストポート:コンテナポート」の形式です。たとえばdocker run -p 8080:80 nginxなら、ホストの8080番へのアクセスがコンテナの80番に転送されます。
Q7. EXPOSEと-pの違いは何ですか?
A7. EXPOSEはDockerfile内で「このポートを使う予定です」と示すヒントで、実際のポートマッピングは行いません。-p(docker runのオプション)が、実際にホストとコンテナを接続します。
Q8. ポートがすでに使われているエラーが出たらどうすればいいですか?
A8. 使用中のプロセスを特定して停止するか、-pで指定するホストポート(左側)を、別の空いている番号に変更します。
Q9. Docker Composeでportsとexposeはどう使い分けますか?
A9. ホストPCからアクセスさせたい場合はports、コンテナ同士の通信にしか使わないポートはportsを書かず、必要ならexposeで用途を示します。exposeはホストのポートを占有しません。
Q10. ポート設定を変更したのに反映されないのはなぜですか?
A10. -pで指定したポートマッピングはコンテナの作成時に決まるため、docker stopとdocker startで再起動しただけでは反映されません。docker rmで削除してから、docker runで再作成します。
Dockerのネットワークとポートは、後回しにされがちな設定です。ただ、最初のコンテナを起動する時点で構成を決めておくと、あとから繋ぎ直す手間を減らせます。コンテナ名やIPアドレスの依存関係を洗い出す作業は、意外と大変だからです。
まとめ|Dockerネットワークとポート設定の要点
最後に、この記事の要点をまとめます。
- 基本はカスタムbridge:コンテナ名で通信できる内蔵DNSが使える
- 外に出すのは-p(ports):
EXPOSEは目安で、公開はしない。ポートは「ホスト:コンテナ」で紐付ける - 繋がらないときはまずinspectとps:
docker network inspectで同じネットワークか、docker psのPORTS欄でマッピングを確認する - Composeなら自動化される:サービス名だけで通信でき、ポートは
portsとexposeで使い分ける
ネットワークやポートのエラーは、原因が分かれば対処は単純です。コンテナが繋がらなくなったら、まずdocker network inspectとdocker psで状況を確認するところから始めてみてください。
| REV. | DATE | 内容 |
|---|---|---|
| 3 | 2026-10-16 | 図解を描き直し(図面のデザインにそろえた) |
| 2 | 2026-10-06 | 記載内容の事実確認と修正 |
| 1 | 2026-08-26 | 初版 |





