メインコンテンツまでスキップ

第09章:ポート公開と「外から繋ぐ」感覚を掴む🌐🚪

この章は「コンテナの中で動いてるサービスに、Windows(ホスト)側から繋げる」状態を作る回です✨ ブラウザでAPIを開けたり、DBクライアントでPostgresに繋げたりできるようになります🧑‍💻🧠


1) まずは“ポート公開”の超ざっくり図解🧩

  • コンテナ内ポート:コンテナの中のアプリが待ち受けてる入口(例:APIが 3000
  • ホスト側ポート:Windows側で外に見せる入口(例:ブラウザが叩く localhost:3000
  • ポート公開(publish):この2つを“トンネル”で繋ぐこと🚇
Windows(ホスト)                 Docker(コンテナ)
http://localhost:3000 ---> APIが 0.0.0.0:3000 で待受
↑ publish(ports) ↓

ポイント:Composeで ports: を書くと、ホストから繋げるようになります🌟(外からアクセスするための設定)(Docker Documentation)


2) ports:expose: の違いはここだけ押さえればOK✅

  • ports: 👉 ホスト(Windows)から繋ぎたいときに使う(公開する)
  • expose: 👉 同じCompose内の他サービスからだけ繋げたいときに使う(ホストには公開しない)

expose は「他サービスには見えるけど、ホストには公開しない」仕様です。(Docker Documentation)


3) 実践:compose.yaml にポート公開を足す🛠️✨

ここでは例として、

  • API(TypeScript/Node): 3000
  • Postgres: 5432
  • Redis: 6379

を想定します🚀 **“ホストから触りたいものだけ ports を付ける”**のが基本です🙂

✅ 例:ホストから“安全に”繋ぐ(まずは localhost 限定)🔒

services:
api:
# 例: build: ./api など(第11章以降で整備)
ports:
- "127.0.0.1:3000:3000"

db:
image: postgres:18
ports:
- "127.0.0.1:5432:5432"

redis:
image: redis:7
ports:
- "127.0.0.1:6379:6379"

💡 なぜ 127.0.0.1: を付けたの?

ports のHOST部分を省略すると、デフォルトで全インターフェース(0.0.0.0)にバインドされます。つまり、LAN内の別端末から届く可能性が出ます🫣 なので最初は 127.0.0.1 固定が安心です。(Docker Documentation)


4) 起動して確認する👀✅

docker compose up -d
docker compose ps

🔎 “今どこで待ち受けてる?”を確認したいとき

docker compose port が便利です(公開ポートを表示してくれます)🧾✨(Docker Documentation)

docker compose port api 3000
docker compose port db 5432

5) ホスト(Windows)から繋いでみよう🌐🎉

🌍 API:ブラウザで開く

  • ブラウザで http://localhost:3000 (または http://127.0.0.1:3000

Docker Desktopは -p(公開)したポートをホストへ転送する仕組みを持っています。(Docker Documentation)


🐘 Postgres:DBクライアントで繋ぐ(例)

  • Host: localhost
  • Port: 5432
  • User / Password / DB名:第8章で .env にしたもの

もし psql を使うなら(入ってる前提なら)こんな感じ👇

psql "postgresql://USER:PASSWORD@localhost:5432/DBNAME"

まだWindowsに psql 入れてない人は、VS CodeのDB拡張やGUIクライアント(DBeaver等)でもOKです🙆‍♂️


🟥 Redis:繋ぐ(例)

  • Host: localhost
  • Port: 6379

(Redis GUIツールや redis-cli など。まずは “繋げる状態” を作れたら勝ちです🏆)


6) “コンテナ同士の接続”は別世界👀(ここで混乱しがち)

ここ超大事です📌 **コンテナの中から見た localhost は「そのコンテナ自身」**です。

なので、APIコンテナがDBに繋ぐときはこう👇

  • localhost:5432
  • db:5432(サービス名)

つまり、**サービス間通信は“サービス名 + コンテナ内ポート”**で繋ぎます🕸️ ホストから触るための ports: は、サービス間通信には本来いりません(デバッグ・開発の都合で付けることが多いだけ)🙂


7) よくある詰まりポイント3連発🧯😵‍💫

① “ポート公開したのにアクセスできない” → アプリが 127.0.0.1 で待ち受けてる

Node/Express系でありがちです⚠️ コンテナ内アプリが 127.0.0.1 にしかbindしてないと、外から届きません。

コンテナ内では 0.0.0.0 で listen するのが基本!

// 例: Express
const port = Number(process.env.PORT ?? 3000);
app.listen(port, "0.0.0.0", () => {
console.log(`listening on ${port}`);
});

② “port が衝突した!” → ホスト側ポートをずらす🧩

Windows側で既に 5432 を使ってる(ローカルPostgres等)と衝突します💥

db:
ports:
- "127.0.0.1:15432:5432"

この場合、ホストからは localhost:15432 に繋ぎます🔁


③ “LANの別端末から繋がっちゃう/繋げたい” → 0.0.0.0 の意味を理解する

Docker Desktopでは -p 公開すると、ホストやローカルネットワークから到達できる形になり得ます。(Docker Documentation) そして HOST を省略した ports:0.0.0.0にbindが基本です。(Docker Documentation)

  • ローカルだけでいい 👉 127.0.0.1:... にする🔒
  • LANからも触りたい 👉 127.0.0.1 を外す(その代わりWindowsファイアウォール等も意識)🧯

8) まとめ:この章で掴む“外から繋ぐ感覚”🎯✨

  • ports:ホスト↔コンテナのトンネル🚇(外から触るため)(Docker Documentation)
  • expose:コンテナ↔コンテナのため(ホストには出ない)(Docker Documentation)
  • 127.0.0.1: を付けると “ローカル限定公開” になって安心🔒(Docker Documentation)
  • docker compose port で “結局どこに出てる?” を確認できる🧾(Docker Documentation)

ミニ演習🎮📝(3分でOK)

  1. APIに 127.0.0.1:3000:3000 を設定して、ブラウザで開けるか確認🌐
  2. DBのホスト側ポートを 15432 にずらしても繋げるか確認🐘
  3. APIからDBへの接続先が localhost ではなく db になっているか確認🕸️

次の第10章はRedis追加で「キャッシュ/キューの土台」を作っていきます🟥⚡ (ここまでの “繋げる感覚” があると、Redis導入がめちゃ楽になりますよ〜😄🚀)