這是一篇為您定製的 Docker Compose 終極實戰指南。
如果您覺得 docker run 命令太長、太難記,或者需要同時啓動“前端+後端+數據庫”的一整套服務,那麼 Docker Compose 就是您的救星。它是 Docker 生態中用於定義和運行多容器應用的工具。
Docker Compose 實戰指南:從單兵作戰到軍團指揮
📚 前置摘要 (TL;DR)
- 核心定位:
docker run是管理一個容器,Docker Compose是管理一組容器(一個項目)。 - 安裝現狀: 如果您安裝了 Docker Desktop (Mac/Win) 或最新版 Docker Engine (Linux),它已經包含在內了。
- 關鍵語法: 命令已從舊版的
docker-compose(Python編寫) 升級為docker compose(Go重寫,Docker原生插件)。推薦使用新版 V2 命令。 - 核心文件: 一切配置皆在
docker-compose.yml。
1. 為什麼需要它?(The "Why")
想象您要部署一個博客系統,需要:
- 啓動 PostgreSQL 數據庫。
- 啓動 Redis 緩存。
- 啓動 Spring Boot 應用,並配置環境變量連上 DB 和 Redis。
- 啓動 Nginx 做反向代理。
如果不由 Compose 管理,您需要手動執行 4 條巨長的 docker run 命令,還要處理容器間的網絡互通(Link/Network)。
Docker Compose 允許您在一個 YAML 文件中定義這 4 個服務,然後通過一條命令 docker compose up 一鍵啓動整個“全家桶”。
2. 安裝 (Installation)
macOS / Windows
直接安裝 Docker Desktop 即可,自帶 Compose V2。
Linux (Ubuntu/Debian)
如果您安裝的是最新版的 docker-ce,通常只需安裝插件:
sudo apt-get update
sudo apt-get install docker-compose-plugin
# 驗證安裝 (注意沒有中間的橫槓)
docker compose version
3. 核心概念與 YAML 結構
docker-compose.yml 是核心。它主要包含三個頂級概念:
- Services (服務): 定義各個容器(如 web, db, redis)。
- Networks (網絡): 定義服務之間的通信通道。
- Volumes (卷): 定義數據持久化存儲。
示例:構建一個 Python Web + Redis 的應用
假設目錄結構如下:
my-project/
├── app.py # Python 代碼
├── requirements.txt
├── Dockerfile # 構建 Web 鏡像
└── docker-compose.yml
docker-compose.yml 內容:
version: '3.8' # 推薦使用較新版本
services:
# 服務 1: Web 應用
web:
build: . # 從當前目錄的 Dockerfile 構建鏡像
ports:
- "8000:5000" # 宿主機8000 -> 容器5000
volumes:
- .:/code # 代碼熱重載:把當前目錄掛載進去
environment:
- FLASK_ENV=development
depends_on: # 依賴順序:先啓 redis 再啓 web
- redis
networks:
- backend-net
# 服務 2: Redis 數據庫
redis:
image: "redis:alpine" # 直接拉取官方鏡像
networks:
- backend-net
# 定義網絡 (可選,默認會自動創建一個)
networks:
backend-net:
# 定義數據卷 (用於持久化 DB 數據)
volumes:
db-data:
4. 常用命令速查 (Cheat Sheet)
請注意,現在的標準用法是 docker compose (空格),而不是 docker-compose (橫槓)。
|
命令
|
描述
|
場景
|
|
|
後台啓動所有服務 |
最常用的命令,相當於“一鍵部署”
|
|
|
停止並移除容器和網絡 |
清理環境
|
|
|
查看當前項目的容器狀態
|
檢查誰掛了
|
|
|
實時查看所有服務的日誌
|
調試神器,類似 |
|
|
只看 web 服務的日誌
|
精準調試
|
|
|
進入 web 容器內部
|
類似 ssh 進入容器
|
|
|
重啓某個服務
|
修改代碼或配置後生效
|
|
|
重新構建鏡像
|
當 Dockerfile 發生變化時使用
|
5. 進階實戰技巧 (Best Practices)
作為全棧開發者,以下技巧能讓您的配置達到生產級標準:
A. 服務發現 (Service Discovery)
在 Docker Compose 中,服務名就是主機名。
- 問題: Web 應用怎麼連接 Redis?IP 是多少?
- 解答: 不需要知道 IP。在 Python/Java 代碼中,直接填
redis作為 host 即可。Docker 內置 DNS 會自動解析redis->172.x.x.x。
B. 環境變量管理 (.env)
不要把密碼硬編碼在 YAML 裏。Compose 會自動讀取同級目錄下的 .env 文件。
.env 文件:
POSTGRES_PASSWORD=secret123
POSTGRES_USER=admin
docker-compose.yml:
services:
db:
image: postgres
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # 引用變量
POSTGRES_USER: ${POSTGRES_USER}
C. 擴容 (Scaling)
想測試負載均衡?可以一鍵啓動 3 個 web 容器:
docker compose up -d --scale web=3
注意:這需要你的 web 服務不綁定固定的宿主機端口(或者使用 Nginx 做前置負載均衡)。
D. 保持容器運行 (Restart Policy)
生產環境務必配置重啓策略,防止程序崩潰或服務器重啓後服務掛掉。
services:
web:
# ...
restart: always # 或者 unless-stopped
6. 常見大坑與排查
depends_on的誤解:
depends_on: - db只是保證啓動順序(先發 db 的啓動指令,再發 web 的)。- 它不保證 db 已經完全初始化完畢(Ready)。如果 Web 應用啓動太快,連數據庫可能會報錯。
- 解決: 在 Web 容器裏使用
wait-for-it.sh腳本,或者編寫健康檢查 (Healthcheck)。
- 文件權限問題:
- 將宿主機目錄掛載到數據庫容器(如 MySQL/PG)時,常出現
Permission denied。這是因為宿主機用户 ID 與容器內用户 ID 不一致。
- YAML 縮進:
- YAML 對縮進極其敏感,嚴禁使用 Tab 鍵,必須使用空格(通常是 2 個或 4 個)。
結語
Docker Compose 是單機編排的王者。對於開發環境搭建、CI/CD 流水線測試、以及中小型項目的單機部署,它是效率最高的工具。