Docker networkって何?一言でいうと「コンテナ同士をつなぐ“専用LAN”」
Docker network は、コンテナ同士をつなぐための「仮想ネットワーク」です。
同じネットワークに属するコンテナは、お互いを IP や名前で呼び合えます。
逆に、ネットワークが違えば、基本的にはお互い見えません。
Python の世界だと、
FastAPI コンテナから DB コンテナに接続する
Web アプリから Redis に接続する
といった場面で、Docker network が必ず関わってきます。
「どのコンテナが、どのコンテナと話せるのか」を決めるのが Docker network です。
まずはイメージ:FastAPI と PostgreSQL を同じネットワークに乗せる
docker-compose での典型的な例
よくある docker-compose.yml を思い出してみます。
version: "3.9"
services:
web:
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://myuser:mypass@db:5432/mydb
depends_on:
- db
db:
image: postgres:16
environment:
- POSTGRES_USER=myuser
- POSTGRES_PASSWORD=mypass
- POSTGRES_DB=mydb
YAMLここには networks: を書いていませんが、
実は docker-compose が自動で「1つのネットワーク」を作って、web と db をそこに参加させています。
その結果、
web から db という名前で PostgreSQL に接続できるDATABASE_URL の @db:5432 の db は、サービス名そのもの
という状態になります。
「同じ compose ファイルの services にいるコンテナは、同じネットワークにいて、サービス名で名前解決できる」
これがまず押さえておきたい基本ルールです。
重要ポイント1:コンテナ同士は「サービス名(コンテナ名)」でつながる
なぜ localhost ではなく db なのか
初心者が最初にハマるポイントがここです。
FastAPI の設定で、ついこう書きたくなります。
DATABASE_URL = "postgresql://myuser:mypass@localhost:5432/mydb"
Pythonでも、コンテナの中から見た localhost は「そのコンテナ自身」です。
FastAPI コンテナから見た localhost は FastAPI コンテナであって、PostgreSQL コンテナではありません。
だから、Docker network を使うときは、
localhost ではなく、DB コンテナの名前(サービス名)を書く
必要があります。
さっきの compose なら、
DATABASE_URL = "postgresql://myuser:mypass@db:5432/mydb"
Pythonが正解です。
ここでの db は、Docker network の中で解決される「ホスト名」です。
DNS みたいなものが、Docker の中にあるイメージです。
重要ポイント2:ネットワークを分けると「誰と誰が話せるか」を制御できる
明示的にネットワークを定義してみる
docker-compose では、ネットワークを自分で定義することもできます。
version: "3.9"
services:
web:
build: .
ports:
- "8000:8000"
networks:
- app-net
environment:
- DATABASE_URL=postgresql://myuser:mypass@db:5432/mydb
db:
image: postgres:16
networks:
- app-net
networks:
app-net:
driver: bridge
YAMLここでは、
app-net という名前のネットワークを定義web と db をそのネットワークに参加させる
ということをしています。
結果として、
web と db はお互いに見えるapp-net に参加していないコンテナからは見えない
という状態になります。
ネットワークを分ける意味
ネットワークを分けると、
「このコンテナは、このグループの中のコンテナとだけ話せる」
という境界線を引けます。
例えば、
外向きの Nginx コンテナは「public-net」と「app-net」の両方に参加
アプリコンテナは「app-net」にだけ参加
DB コンテナも「app-net」にだけ参加
とすると、
外から直接 DB にアクセスされることはなく、
Nginx → アプリ → DB という経路だけが許される、という構成にできます。
DevOps・運用の観点では、「ネットワークで分離する」はセキュリティの基本テクニックです。
Docker network は、その「分離」をコンテナ単位でやるための仕組みです。
重要ポイント3:ホストとの通信とコンテナ同士の通信を分けて考える
ports は「ホストとコンテナの橋」
compose の ports は、ホストとコンテナの間の話です。
services:
web:
ports:
- "8000:8000"
YAMLこれは、
ホストの 8000 番ポート
コンテナの 8000 番ポート
をつなぐ、という意味です。
ブラウザから http://localhost:8000 にアクセスすると、
Docker が「ホストの 8000 → web コンテナの 8000」に転送してくれます。
これは Docker network とは別のレイヤーの話です。
Docker network は「コンテナ同士」、ports は「ホストとコンテナ」と覚えると整理しやすいです。
コンテナ同士の通信には ports はいらない
よくある勘違いが、
「web から db にアクセスするには、db に ports: "5432:5432" が必要」
と思ってしまうことです。
コンテナ同士の通信には、ports は不要です。
同じネットワークにいて、コンテナ内でポートが開いていれば、それで十分です。
ports は「ホストから見えるようにするための穴」なので、
内部だけで完結する DB には、本番では ports を開けない方が安全です。
重要ポイント4:ネットワークを意識すると「本番に近いローカル環境」が作りやすくなる
ローカルでも「本番と同じ名前」でつなぐ
本番環境で、
DATABASE_URL=postgresql://myuser:mypass@db:5432/mydb
のように設定しているなら、
ローカルの docker-compose でも同じように @db:5432 でつなぐと、
環境差が減ります。
ローカルでは localhost、本番では db.internal みたいに変えてしまうと、
設定の切り替えやバグの原因になります。
Docker network を使えば、
「どの環境でも、アプリから見える DB のホスト名は db」
という世界を作れます。
CI でも同じネットワーク構成を再現できる
GitHub Actions などの CI でも、
docker-compose を使ってテスト環境を立ち上げることができます。
そのとき、
アプリコンテナ
DB コンテナ
を同じネットワークに乗せて、
アプリからは db で接続する、という構成にしておけば、
ローカル
CI
本番
で「ネットワークの前提」が揃います。
DevOps 的には、「環境ごとの違いを減らす」ことがとても重要で、
Docker network はそのための土台になります。
初心者向けの練習ステップ
ステップ1:FastAPI + PostgreSQL を compose で立てて、@db でつなぐ
実際に、
DATABASE_URL=postgresql://myuser:mypass@db:5432/mydb
で FastAPI から DB に接続してみる。localhost ではなく db を使う感覚を体で覚える。
ステップ2:ネットワークを明示的に定義してみる
networks: を自分で書いて、
web と db を同じネットワークに乗せる
別のサービスを別ネットワークに分けてみる
などを試して、「誰と誰が話せるか」を意識してみる。
まとめ(Docker network は「コンテナ同士の世界を区切り、名前でつなぐための仮想LAN」)
初心者目線で整理すると、Docker network はこういうものです。
同じネットワークに属するコンテナ同士は、サービス名(コンテナ名)でお互いに通信でき、docker-compose では「同じ services にいるコンテナは同じネットワークに乗る」のが基本。localhost ではなく db のようなサービス名で接続することで、ローカル・CI・本番で同じ接続文字列を使えるようになり、ネットワークを分けることで「誰と誰が話せるか」を制御できる。
