在 Docker 的生態系統中,有三個工具被廣大開發者親切地稱為“Docker 三劍客”:Docker Machine、Docker Compose 和 Docker Swarm。它們分別解決了不同層面的問題:
- Docker Machine:負責在各種環境(本地、雲服務器)中快速創建和配置 Docker 主機。
- Docker Swarm:Docker 原生的容器編排工具,用於管理集羣和調度服務。
- Docker Compose:今天的主角,它的核心使命是定義和運行多容器的 Docker 應用。
隨着 Docker Swarm 模式被集成進 Docker Engine,現在通常所説的“三劍客”更多是指 Docker 在單機和多容器應用編排上的核心工具集,而 Docker Compose 無疑是其中使用最頻繁、最接地氣的一個。
一、什麼是 Docker Compose?為什麼需要它?
想象一下,一個典型的 Web 應用可能包含以下組件:
- 一個用 Python/Node.js 編寫的應用容器。
- 一個 Nginx 容器作為反向代理。
- 一個 Redis 容器作為緩存。
- 一個 PostgreSQL 容器作為數據庫。
如果使用基礎的 docker run 命令,你需要為每個容器手動設置網絡、卷、環境變量、依賴關係等。這不僅命令冗長複雜,而且難以維護和重現。
Docker Compose 應運而生。它是一個用於定義和運行多容器 Docker 應用程序的工具。通過一個單獨的 docker-compose.yml 配置文件,你可以使用 YAML 語言來配置應用程序的所有服務。然後,只需一個簡單的命令,就能創建並啓動所有服務。
它的核心價值在於:
- 簡化操作:一條命令替代一系列複雜的
docker run指令。 - 環境標準化:確保開發、測試、生產環境的一致性。
- 高效管理:輕鬆管理整個應用的生命週期(啓動、停止、重建)。
- 快速搭建開發環境:新成員只需拉取代碼和配置文件,執行
docker-compose up即可獲得一個完整、隔離的開發環境。
二、Docker Compose 的核心概念與工作原理
1. 核心概念
- 項目:一個由多個服務組成的完整應用。默認情況下,項目名稱取自其所在目錄的名稱。
- 服務:一個應用容器的一個運行實例,對應
docker-compose.yml文件中的一個service。例如,一個web服務,一個db服務。 - 容器:服務的實際運行實例。一個服務通常對應一個容器,但也可以通過
scale命令擴展到多個容器實例。
2. 工作原理
Docker Compose 的核心是一個名為 docker-compose.yml 的 YAML 文件。當你執行 docker-compose up 時:
- 解析 YAML:Compose 讀取
docker-compose.yml文件,解析其中定義的服務、網絡、卷等資源。 - 創建項目默認網絡:Compose 會自動為整個項目創建一個獨立的網絡,使得所有服務可以通過服務名作為主機名互相發現和通信。
- 構建鏡像(如需要):如果配置中指定了
build路徑,Compose 會根據 Dockerfile 構建鏡像。 - 創建並啓動容器:根據配置為每個服務創建並啓動容器,自動處理容器間的依賴關係(
depends_on)、數據卷掛載、端口映射等。 - 聚合日誌:將所有服務的日誌輸出聚合到同一個終端流中,方便查看。
三、詳解 docker-compose.yml 文件
這是一個標準的 docker-compose.yml 文件的結構示例和常用指令:
# 指定 Compose 文件的版本。建議使用 3.x 版本以兼容新特性。
version: '3.8'
# 定義本項目中的所有服務(容器)
services:
# 服務一:Web 應用
web:
# 構建鏡像的上下文路徑,Compose 會使用該路徑下的 Dockerfile
build: .
# alternatively, 可以直接使用已有的鏡像
# image: my-python-app:latest
# 將主機端口映射到容器端口 (主機端口:容器端口)
ports:
- "8000:5000"
# 將主機目錄或卷掛載到容器中
volumes:
- .:/code
- static_volume:/static_files
# 設置環境變量
environment:
- DEBUG=1
- DATABASE_URL=postgresql://user:password@db:5432/mydb
# 或者使用環境變量文件
# env_file:
# - .env
# 定義服務間的依賴關係,Compose 會先啓動 db 再啓動 web
depends_on:
- db
- redis
# 容器啓動後執行的命令(會覆蓋 Dockerfile 中的 CMD)
command: python app.py
# 服務二:數據庫
db:
image: postgres:13
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydb
# 將命名卷掛載到容器內的數據庫存儲路徑,實現數據持久化
volumes:
- postgres_data:/var/lib/postgresql/data
# 服務三:緩存
redis:
image: redis:alpine
# 限制容器使用的最大內存
mem_limit: 128m
# 定義本項目中使用到的所有數據卷,需要在 services 之外聲明
volumes:
postgres_data:
static_volume:
常用指令説明:
build&image:指定服務的鏡像來源。ports:端口映射。volumes:數據卷掛載,用於數據持久化和代碼同步。environment&env_file:環境配置。depends_on:表達服務間的啓動依賴(注意:它不等待服務“就緒”,僅等待“運行”)。networks:自定義網絡(默認會自動創建)。command:覆蓋默認的啓動命令。
四、常用 Docker Compose 命令
掌握了 YAML 文件的編寫,操作就變得非常簡單:
- 啓動所有服務:
docker-compose up- 後台啓動:
docker-compose up -d
- 後台啓動:
- 停止並移除所有容器、網絡:
docker-compose down- 同時移除數據卷:
docker-compose down -v
- 同時移除數據卷:
- 查看服務狀態:
docker-compose ps - 查看服務日誌:
docker-compose logs- 查看特定服務日誌:
docker-compose logs -f web
- 查看特定服務日誌:
- 在運行中的服務中執行命令:
docker-compose exec <service_name> <command>- 例如:
docker-compose exec db psql -U user mydb
- 例如:
- 重新構建並啓動服務:
docker-compose up --build - 擴展服務實例數量:
docker-compose up --scale web=3(需要配合負載均衡器) - 停止服務(不刪除容器):
docker-compose stop - 啓動已停止的服務:
docker-compose start
五、實戰:搭建一個簡單的 Flask + Redis 計數器應用
讓我們通過一個完整的例子來鞏固所學。
1. 創建項目目錄
mkdir flask-redis-counter && cd flask-redis-counter
2. 創建 app.py (Flask 應用)
from flask import Flask
import redis
import os
app = Flask(__name__)
# 通過服務名 "redis" 連接,這是 Compose 網絡的核心特性
redis_client = redis.Redis(host='redis', port=6379, decode_responses=True)
@app.route('/')
def hello():
count = redis_client.incr('hits')
return f'Hello World! 本頁面已被訪問 {count} 次。\n'
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
3. 創建 Dockerfile
FROM python:3.9-alpine
WORKDIR /code
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]
4. 創建 requirements.txt
flask
redis
5. 創建 docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "8000:5000"
# 依賴於 redis 服務
depends_on:
- redis
# 掛載代碼目錄,便於開發時熱更新
volumes:
- .:/code
environment:
- FLASK_DEBUG=1
redis:
image: "redis:alpine"
6. 運行並測試 在項目根目錄下執行:
docker-compose up --build
訪問 http://localhost:8000,每次刷新頁面,計數器都會增加!
六、總結
Docker Compose 極大地簡化了多容器應用的管理複雜度,是 Docker 學習路徑上不可或缺的一環。它將“基礎設施即代碼”的理念落到了實處,讓開發者能夠通過一個簡單的配置文件,輕鬆駕馭複雜的容器化應用。
無論是用於本地開發、自動化測試,還是作為 CI/CD 流水線的一部分,Docker Compose 都能顯著提升效率和可維護性。熟練掌握它,你就真正握有了開啓現代化應用部署大門的鑰匙。