2.3 網路連接與埠對映#
容器是隔離的:連網路也隔離#
容器有自己的網路空間——容器內監聽 80 埠,主機上沒有人能直接連到它。要讓外部(你的瀏覽器、其他程式)連到容器內的服務,就要做埠對映(port mapping):把主機的某個埠轉發到容器的埠。
-p:埠對映#
docker run -d -p 8080:80 nginx
# ↑ └─┬─┘
# 背景執行 主機 8080 埠 → 容器 80 埠
語法:-p <主機埠>:<容器埠>。之後在瀏覽器打開 http://localhost:8080,就會看到 Nginx 的歡迎頁。
幾個實用的變化:
-p 8080:80 # 主機 8080 → 容器 80(最常用)
-p 127.0.0.1:8080:80 # 只允許本機連(不對外暴露,更安全)
-p 8080 # 只指定主機埠,容器埠隨機分配(少用)
初學者常見困惑:「為什麼瀏覽器連不上?」依序檢查:(1) 有沒有加
-p?(2) 埠號寫對了嗎(左邊是主機埠)?(3) 主機埠有沒有被其他程式佔用(錯誤訊息會說port is already allocated)?
查看埠對映#
docker ps # PORTS 欄位顯示 0.0.0.0:8080->80/tcp
docker port my-nginx # 直接列出某容器的對映
實戰:一秒啟動 Nginx / Redis / PostgreSQL#
有了埠對映,任何主流服務都能一行指令啟動,不用在本機安裝任何東西:
# Nginx 網頁伺服器:http://localhost:8080
docker run -d -p 8080:80 --name web nginx
# Redis 快取:主機 6379 埠
docker run -d -p 6379:6379 --name cache redis
# PostgreSQL 資料庫:需要環境變數設密碼
docker run -d -p 5432:5432 --name db \
-e POSTGRES_PASSWORD=mysecret \
postgres
測試一下:
# 測 Redis
docker exec -it cache redis-cli ping
# PONG
# 測 PostgreSQL
docker exec -it db psql -U postgres -c "SELECT version();"
這就是容器最香的用法:本機不用裝 Redis、PostgreSQL、Nginx,需要時一行指令啟動、用完 docker rm -f 刪除,主機乾乾淨淨。
埠衝突:同一個服務跑多個#
埠對映讓你可以把同一個 Image 的多個實例映射到不同主機埠:
docker run -d -p 8081:80 --name web1 nginx
docker run -d -p 8082:80 --name web2 nginx
# localhost:8081 和 localhost:8082 各是一個獨立的 Nginx
但注意:容器之間若要互相訪問,不該靠埠對映,而該用 Docker 網路(見 4.2 節)。
本章小結#
- 容器網路是隔離的,
-p 主機埠:容器埠做埠轉發 - 連不上依序檢查:有無
-p、埠號順序、埠是否被佔用 - 一行指令啟動 Nginx/Redis/PostgreSQL,本機零安裝
- 同一 Image 可映射到不同主機埠跑多個實例
- 容器間通訊用 Docker 網路,不靠埠對映(第四章)
想一想#
docker run -d -p 8080:80 nginx中,兩個 80 各代表什麼?瀏覽器該連哪個埠?- 想在本機同時測試「新舊兩個版本的後端」,埠該怎麼映射?
- 為什麼
-p 127.0.0.1:8080:80比-p 8080:80更安全?