跳轉到內容

Docker Compose 實戰教程:從零掌握多容器應用編排(2026版)

本文為你係統介紹 Docker Compose 的基礎概念、YAML 語法、多容器編排技巧及生產環境最佳實踐,讓你快速掌握容器化應用部署。

💡 提示:本文已更新到 2026 年 5 月,包含 Docker Compose V2 的最新特性和實際項目案例。

瞭解 Docker Compose 的基本概念

Docker Compose 是 Docker 官方提供的 多容器應用編排工具,通過單個 YAML 文件定義複雜的應用架構,實現一鍵部署和管理。

什麼是容器編排?

容器編排(Container Orchestration) 是指自動化管理多個容器的生命週期:

傳統方式:手動管理每個容器

    docker run container1
    docker run container2
    docker run container3
    ...(繁瑣且易出錯)

容器編排:統一管理和調度

    docker-compose up
    ✅ 自動啟動所有容器
    ✅ 自動配置網絡
    ✅ 自動掛載數據卷
    ✅ 自動處理依賴關係

Docker Compose 的核心價值:

  • 簡化部署:一條命令啟動整個應用棧
  • 環境一致性:開發、測試、生產環境完全一致
  • 版本控制:配置文件可納入 Git 管理
  • 易於協作:團隊成員共享相同的配置

核心特點

  • 聲明式配置:用 YAML 描述期望狀態

    • 清晰易讀
    • 版本可控
    • 便於審查
  • 多容器管理:同時管理多個相關容器

    • Web 應用 + 數據庫 + 緩存
    • 微服務架構
    • 完整的技術棧
  • 依賴管理:自動處理容器啟動順序

    • 先啟動數據庫
    • 再啟動應用服務
    • 最後啟動反向代理
  • 環境隔離:不同項目互不干擾

    • 獨立網絡空間
    • 獨立數據卷
    • 獨立資源限制

發展歷程

版本發佈時間主要特點
Compose V12014 年Python 編寫,docker-compose 命令
Compose V22021 年Go 重寫,docker compose 子命令
Compose Spec2020 年標準化規範,跨平臺兼容
Compose V2.20+2024 年性能優化,Watch 模式

目前主流使用的是 Docker Compose V2,作為 Docker CLI 的子命令集成,性能更優,功能更強。

Docker 生態簡介

公司名稱:Docker Inc.
成立時間:2013 年
創始人:Solomon Hykes
總部:美國舊金山
主要產品:Docker Engine, Docker Desktop, Docker Hub, Docker Compose
使命:讓開發者能夠輕鬆構建、分享和運行任何應用
用戶規模:全球超過 1300 萬開發者

安裝與配置

系統要求

最低配置:

  • CPU:2 核心
  • 內存:4 GB
  • 磁盤:20 GB 可用空間
  • 操作系統:Linux / macOS / Windows 10+

推薦配置:

  • CPU:4 核心+
  • 內存:8 GB+
  • 磁盤:SSD 50 GB+
  • 網絡:穩定的互聯網連接

前置條件

在開始之前,確保已安裝:

bash
# 檢查 Docker 是否安裝
docker --version
# 輸出:Docker version 24.0.7, build afdd53b

# 檢查 Docker 是否運行
docker info
# 應該顯示系統信息,無錯誤

# 檢查 Docker Compose 是否已集成(V2)
docker compose version
# 輸出:Docker Compose version v2.21.0

⚠️ 注意:Docker Desktop 默認包含 Compose V2。如果使用舊版 docker-compose 命令,建議升級到 V2。

各平臺安裝方法

Linux 系統

bash
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install docker-compose-plugin

# CentOS/RHEL
sudo yum install docker-compose-plugin

# 驗證安裝
docker compose version

macOS 系統

bash
# 通過 Docker Desktop 安裝(推薦)
# 1. 下載 Docker Desktop for Mac
# 2. 安裝後自動包含 Compose V2

# 或通過 Homebrew
brew install --cask docker

# 驗證
docker compose version

Windows 系統

powershell
# 通過 Docker Desktop 安裝(推薦)
# 1. 下載 Docker Desktop for Windows
# 2. 啟用 WSL 2 後端
# 3. 安裝後自動包含 Compose V2

# 驗證
docker compose version

從 V1 遷移到 V2

如果你仍在使用舊版 docker-compose

bash
# 舊命令(V1)
docker-compose up -d

# 新命令(V2)
docker compose up -d

# 兼容性提示
# V2 完全兼容 V1 的配置文件格式
# 只需將命令中的連字符改為空格

編寫 docker-compose.yml 文件

YAML 基礎語法

YAML(YAML Ain't Markup Language)是一種人類可讀的數據序列化格式。

基本規則:

yaml
# 註釋以 # 開頭
key: value          # 鍵值對
list:               # 列表
  - item1
  - item2
nested:             # 嵌套對象
  key1: value1
  key2: value2

注意事項:

  • ✅ 使用空格縮進(通常 2 個空格)
  • ❌ 不要使用 Tab 縮進
  • ✅ 字符串可以不加引號
  • ✅ 特殊字符需要加引號

配置文件結構

一個標準的 docker-compose.yml 包含以下部分:

yaml
version: '3.8'              # 配置文件版本(可選,V2 可省略)

services:                   # 服務定義(必需)
  web:                      # 服務名稱
    image: nginx:latest     # 使用的鏡像
    ports:                  # 端口映射
      - "80:80"
    volumes:                # 數據卷掛載
      - ./html:/usr/share/nginx/html
    networks:               # 網絡連接
      - frontend
    depends_on:             # 依賴關係
      - db
    environment:            # 環境變量
      - NGINX_HOST=localhost

  db:                       # 第二個服務
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - backend

volumes:                    # 命名數據卷定義
  db_data:

networks:                   # 自定義網絡定義
  frontend:
  backend:

核心配置項詳解

1. services(服務定義)

每個服務代表一個容器:

yaml
services:
  # 基本服務
  app:
    image: node:18-alpine
    command: npm start
    working_dir: /app
    
  # 從 Dockerfile 構建
  api:
    build:
      context: ./api           # 構建上下文
      dockerfile: Dockerfile   # Dockerfile 路徑
      args:                    # 構建參數
        NODE_ENV: production

2. image(鏡像指定)

yaml
services:
  # 使用官方鏡像
  web:
    image: nginx:latest
    
  # 指定版本
  db:
    image: postgres:15.4
    
  # 使用私有倉庫
  app:
    image: registry.example.com/myapp:v1.0

3. build(從 Dockerfile 構建)

yaml
services:
  app:
    build:
      context: .                    # 當前目錄
      dockerfile: Dockerfile.prod   # 指定 Dockerfile
      target: production            # 多階段構建的目標階段
      args:                         # 構建時變量
        VERSION: 1.0.0

對應的 Dockerfile

dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine AS production
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

4. ports(端口映射)

yaml
services:
  web:
    ports:
      - "80:80"              # host:container
      - "443:443"
      - "8080-8090:8080-8090"  # 端口範圍
      
  # 只暴露給其他容器(不映射到主機)
  db:
    expose:
      - "3306"

端口映射說明:

"8080:80" 表示:
  主機端口 8080 → 容器端口 80
  
訪問 http://localhost:8080 
實際訪問的是容器內的 80 端口

5. volumes(數據卷掛載)

yaml
services:
  app:
    volumes:
      # 綁定掛載(Bind Mount)
      - ./src:/app/src
      
      # 命名卷(Named Volume)
      - app_data:/app/data
      
      # 只讀掛載
      - ./config:/app/config:ro

volumes:
  app_data:    # 定義命名卷

數據卷類型對比:

類型語法適用場景持久化
綁定掛載./host:/container開發環境代碼同步取決於主機
命名卷volume_name:/container數據庫數據✅ 是
tmpfstype: tmpfs臨時文件❌ 否

6. environment(環境變量)

yaml
services:
  app:
    environment:
      # 方式一:列表格式
      - NODE_ENV=production
      - DB_HOST=db
      - DB_PORT=3306
      
      # 方式二:字典格式
      # NODE_ENV: production
      # DB_HOST: db
      
  db:
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}  # 從 .env 文件讀取
      MYSQL_DATABASE: myapp

7. networks(網絡配置)

yaml
services:
  web:
    networks:
      - frontend
      
  api:
    networks:
      - frontend
      - backend
      
  db:
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true    # 內部網絡,外部無法訪問

8. depends_on(依賴關係)

yaml
services:
  web:
    depends_on:
      - api
      
  api:
    depends_on:
      db:
        condition: service_healthy    # 等待健康檢查通過
      redis:
        condition: service_started    # 等待容器啟動
        
  db:
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

9. restart(重啟策略)

yaml
services:
  app:
    restart: unless-stopped    # 除非手動停止,否則總是重啟
    
  # 其他選項:
  # no: 不自動重啟(默認)
  # always: 總是重啟
  # on-failure: 只在失敗時重啟
  # on-failure:3: 最多重試 3 次

10. resources(資源限制)

yaml
services:
  app:
    deploy:
      resources:
        limits:
          cpus: '0.5'        # 最多使用 0.5 個 CPU
          memory: 512M       # 最多使用 512MB 內存
        reservations:
          cpus: '0.25'       # 預留 0.25 個 CPU
          memory: 256M       # 預留 256MB 內存

完整示例:WordPress 博客

yaml
version: '3.8'

services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wp_content:/var/www/html/wp-content
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - wp_network

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
    volumes:
      - db_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    networks:
      - wp_network

volumes:
  wp_content:
  db_data:

networks:
  wp_network:
    driver: bridge

配套的 .env 文件:

bash
DB_PASSWORD=my_secure_password
DB_ROOT_PASSWORD=my_root_password

管理容器生命週期

常用命令

啟動服務

bash
# 前臺啟動(日誌輸出到終端)
docker compose up

# 後臺啟動(推薦)
docker compose up -d

# 重新構建並啟動
docker compose up -d --build

# 僅啟動特定服務
docker compose up -d web db

# 強制重新創建容器
docker compose up -d --force-recreate

查看狀態

bash
# 查看所有服務狀態
docker compose ps

# 輸出示例:
# NAME                IMAGE          COMMAND                  STATUS
# myapp-web-1         nginx:latest   "/docker-entrypoint.…"   Up 2 hours
# myapp-db-1          mysql:8.0      "docker-entrypoint.s…"   Up 2 hours (healthy)

# 查看實時日誌
docker compose logs -f

# 查看特定服務的日誌
docker compose logs -f web

# 查看資源使用情況
docker compose stats

停止服務

bash
# 停止服務(保留容器和數據)
docker compose stop

# 停止並刪除容器
docker compose down

# 停止並刪除容器、網絡、數據卷
docker compose down -v

# 停止並刪除所有內容(包括鏡像)
docker compose down --rmi all

重啟服務

bash
# 重啟所有服務
docker compose restart

# 重啟特定服務
docker compose restart web

# 重啟並重新構建
docker compose up -d --build

執行命令

bash
# 在運行中的容器內執行命令
docker compose exec web bash

# 進入數據庫容器
docker compose exec db mysql -u root -p

# 運行一次性命令
docker compose run --rm web npm test

# 在新容器中執行(不依賴正在運行的服務)
docker compose run app python manage.py migrate

實用技巧

1. 查看配置

bash
# 查看解析後的配置
docker compose config

# 查看服務列表
docker compose config --services

# 驗證配置文件
docker compose config --quiet && echo "配置有效"

2. 擴展服務

bash
# 橫向擴展(增加容器實例)
docker compose up -d --scale web=3

# 查看擴展後的狀態
docker compose ps
# 會顯示 web-1, web-2, web-3

3. 暫停和恢復

bash
# 暫停服務
docker compose pause

# 恢復服務
docker compose unpause

4. 拉取最新鏡像

bash
# 拉取所有服務的最新鏡像
docker compose pull

# 拉取特定服務的鏡像
docker compose pull web

網絡配置與數據卷管理

網絡模式

Docker Compose 支持多種網絡模式:

1. 默認橋接網絡

yaml
services:
  web:
    image: nginx
  db:
    image: mysql

特點:

  • 自動創建默認網絡
  • 服務間可通過服務名互相訪問
  • 外部需要通過端口映射訪問

2. 自定義網絡

yaml
services:
  frontend:
    networks:
      - public
      
  backend:
    networks:
      - public
      - private
      
  database:
    networks:
      - private

networks:
  public:
    driver: bridge
  private:
    driver: bridge
    internal: true    # 內部網絡,外部不可達

優勢:

  • 網絡隔離,提高安全性
  • 精細控制服務間通信
  • 模擬真實生產環境

3. Host 網絡

yaml
services:
  app:
    network_mode: host

特點:

  • 容器直接使用主機網絡
  • 無需端口映射
  • 性能最好,但隔離性差

4. None 網絡

yaml
services:
  isolated_service:
    network_mode: none

特點:

  • 完全隔離,無網絡連接
  • 適用於不需要網絡的批處理任務

服務間通信

yaml
services:
  web:
    image: nginx
    networks:
      - frontend
      
  api:
    image: node:18
    networks:
      - frontend
      - backend
      
  db:
    image: postgres
    networks:
      - backend

networks:
  frontend:
  backend:

訪問方式:

javascript
// 在 web 容器中訪問 api
fetch('http://api:3000/data')

// 在 api 容器中訪問 db
const pg = new Client({
  host: 'db',      // 使用服務名作為主機名
  port: 5432,
  database: 'mydb'
})

數據卷類型

1. 命名卷(推薦用於數據持久化)

yaml
services:
  db:
    image: postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:
    driver: local

優點:

  • Docker 管理,位置透明
  • 備份和遷移方便
  • 性能較好

2. 綁定掛載(適合開發)

yaml
services:
  app:
    image: node:18
    volumes:
      - ./src:/app/src      # 代碼熱重載
      - ./config:/app/config:ro  # 只讀配置

優點:

  • 主機文件實時同步
  • 便於調試和開發
  • 可直接編輯文件

3. tmpfs(臨時存儲)

yaml
services:
  app:
    image: node:18
    tmpfs:
      - /tmp
      - /cache

優點:

  • 存儲在內存中,速度快
  • 容器停止後自動清除
  • 適合緩存和臨時文件

數據卷操作

bash
# 列出所有數據卷
docker volume ls

# 查看數據卷詳情
docker volume inspect myapp_postgres_data

# 備份數據卷
docker run --rm \
  -v myapp_postgres_data:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/db-backup.tar.gz -C /data .

# 恢復數據卷
docker run --rm \
  -v myapp_postgres_data:/data \
  -v $(pwd):/backup \
  alpine tar xzf /backup/db-backup.tar.gz -C /data

# 刪除未使用的數據卷
docker volume prune

環境變量管理

.env 文件

在項目根目錄創建 .env 文件:

bash
# 數據庫配置
DB_HOST=localhost
DB_PORT=3306
DB_NAME=myapp
DB_USER=admin
DB_PASSWORD=secret123

# 應用配置
APP_ENV=production
APP_DEBUG=false
APP_PORT=8080

# API 密鑰
API_KEY=your_api_key_here
SECRET_KEY=your_secret_key

docker-compose.yml 中使用:

yaml
services:
  app:
    image: myapp:latest
    environment:
      - DB_HOST=${DB_HOST}
      - DB_PORT=${DB_PORT}
      - DB_NAME=${DB_NAME}
      - APP_ENV=${APP_ENV}

多環境配置

方案一:多個 .env 文件

bash
# .env.development
APP_ENV=development
DEBUG=true
DB_HOST=localhost

# .env.production
APP_ENV=production
DEBUG=false
DB_HOST=db.production.com

使用時指定:

bash
# 開發環境
docker compose --env-file .env.development up -d

# 生產環境
docker compose --env-file .env.production up -d

方案二:覆蓋配置文件

yaml
# docker-compose.yml(基礎配置)
services:
  app:
    image: myapp:latest
    environment:
      - APP_ENV=development

# docker-compose.prod.yml(生產覆蓋)
services:
  app:
    environment:
      - APP_ENV=production
    deploy:
      resources:
        limits:
          memory: 1G

合併使用:

bash
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

變量替換和默認值

yaml
services:
  app:
    environment:
      # 使用默認值
      - APP_PORT=${APP_PORT:-8080}
      
      # 必需變量(未設置會報錯)
      - SECRET_KEY=${SECRET_KEY:?必須設置 SECRET_KEY}
      
      # 可選變量
      - OPTIONAL_VAR=${OPTIONAL_VAR:-}

敏感信息管理

❌ 不安全的方式:

yaml
# 不要直接在配置文件中寫密碼
environment:
  - DB_PASSWORD=super_secret

✅ 推薦的方式:

方式一:使用 Docker Secrets(Swarm 模式)

yaml
services:
  app:
    secrets:
      - db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

方式二:使用外部密鑰管理服務

yaml
services:
  app:
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password
    volumes:
      - /path/to/secrets:/run/secrets:ro

方式三:使用 HashiCorp Vault

yaml
services:
  vault-agent:
    image: hashicorp/vault
    environment:
      VAULT_ADDR: https://vault.example.com

生產環境最佳實踐

安全加固

1. 非 root 用戶運行

yaml
services:
  app:
    image: myapp:latest
    user: "1000:1000"    # UID:GID

在 Dockerfile 中:

dockerfile
RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser

2. 只讀文件系統

yaml
services:
  app:
    read_only: true
    tmpfs:
      - /tmp
      - /var/cache
    volumes:
      - app_data:/app/data:rw    # 僅需要寫入的目錄

3. 移除不必要的權限

yaml
services:
  app:
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE    # 僅添加需要的權限

4. 健康檢查

yaml
services:
  web:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
      
  db:
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

5. 資源限制

yaml
services:
  app:
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M

性能優化

1. 使用多階段構建

dockerfile
# 構建階段
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --production=false
COPY . .
RUN npm run build

# 生產階段
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

2. 使用 .dockerignore

gitignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
dist

3. 緩存優化

yaml
services:
  app:
    build:
      context: .
      cache_from:
        - myapp:latest
        - myapp:cache

4. 日誌管理

yaml
services:
  app:
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

監控和日誌

1. 集成 Prometheus

yaml
services:
  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
      
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    depends_on:
      - prometheus

2. 集中式日誌

yaml
services:
  app:
    logging:
      driver: fluentd
      options:
        fluentd-address: localhost:24224
        tag: docker.app
        
  fluentd:
    image: fluent/fluentd
    ports:
      - "24224:24224"
    volumes:
      - ./fluent.conf:/fluentd/etc/fluent.conf

備份策略

自動備份腳本

bash
#!/bin/bash
# backup.sh

BACKUP_DIR="./backups"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR

# 備份數據庫
docker compose exec -T db pg_dump -U postgres mydb > $BACKUP_DIR/db_$DATE.sql

# 備份數據卷
docker run --rm \
  -v myapp_app_data:/data \
  -v $(pwd)/$BACKUP_DIR:/backup \
  alpine tar czf /backup/app_data_$DATE.tar.gz -C /data .

# 保留最近 7 天的備份
find $BACKUP_DIR -name "*.sql" -mtime +7 -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete

echo "備份完成:$DATE"

設置定時任務:

bash
# 每天凌晨 2 點執行備份
crontab -e
0 2 * * * /path/to/backup.sh

CI/CD 集成

GitHub Actions 示例

yaml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
          
      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          push: true
          tags: myapp:latest
          
      - name: Deploy to server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            cd /opt/myapp
            docker compose pull
            docker compose up -d
            docker system prune -f

實際項目案例

案例 1:全棧應用(React + Node.js + PostgreSQL)

yaml
version: '3.8'

services:
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    ports:
      - "3000:80"
    depends_on:
      backend:
        condition: service_healthy
    networks:
      - app_network
    restart: unless-stopped

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}
      - REDIS_URL=redis://redis:6379
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - app_network
    restart: unless-stopped

  db:
    image: postgres:15
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - app_network
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    networks:
      - app_network
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - frontend
      - backend
    networks:
      - app_network
    restart: unless-stopped

volumes:
  postgres_data:
  redis_data:

networks:
  app_network:
    driver: bridge

案例 2:微服務架構

yaml
version: '3.8'

services:
  api-gateway:
    image: kong:latest
    ports:
      - "8000:8000"
      - "8443:8443"
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-db
    depends_on:
      kong-db:
        condition: service_healthy
    networks:
      - gateway_network

  user-service:
    build: ./services/user
    environment:
      - SERVICE_NAME=user-service
      - PORT=3001
    networks:
      - services_network

  order-service:
    build: ./services/order
    environment:
      - SERVICE_NAME=order-service
      - PORT=3002
    networks:
      - services_network

  product-service:
    build: ./services/product
    environment:
      - SERVICE_NAME=product-service
      - PORT=3003
    networks:
      - services_network

  message-queue:
    image: rabbitmq:3-management
    ports:
      - "5672:5672"
      - "15672:15672"
    networks:
      - services_network

  kong-db:
    image: postgres:15
    environment:
      POSTGRES_DB: kong
      POSTGRES_USER: kong
      POSTGRES_PASSWORD: kong
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U kong"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - gateway_network

networks:
  gateway_network:
  services_network:

案例 3:開發環境

yaml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - .:/app
      - /app/node_modules
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
      - WATCHPACK_POLLING=true
    command: npm run dev
    stdin_open: true
    tty: true

  db:
    image: postgres:15
    environment:
      POSTGRES_DB: devdb
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: dev
    ports:
      - "5432:5432"
    volumes:
      - dev_db_data:/var/lib/postgresql/data

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

  mailhog:
    image: mailhog/mailhog
    ports:
      - "1025:1025"
      - "8025:8025"

volumes:
  dev_db_data:

常見問題 FAQ

Q1: Docker Compose 和 Kubernetes 有什麼區別?

A:

  • Docker Compose:適合單機部署,簡單易用,適合開發和小型項目
  • Kubernetes:適合集群部署,功能強大,適合大規模生產環境

選擇建議:

  • 單機應用 → Docker Compose
  • 多節點集群 → Kubernetes
  • 從小規模開始 → 先用 Compose,後期遷移到 K8s

Q2: 如何調試容器?

A:

bash
# 查看日誌
docker compose logs -f service_name

# 進入容器
docker compose exec service_name bash

# 查看容器詳細信息
docker inspect container_id

# 查看資源使用
docker stats

Q3: 數據卷滿了怎麼辦?

A:

bash
# 清理未使用的數據卷
docker volume prune

# 查看數據卷大小
docker system df -v

# 手動清理
docker compose down -v    # 刪除所有數據卷(謹慎使用)

Q4: 如何更新服務?

A:

bash
# 拉取最新鏡像
docker compose pull

# 重新創建容器
docker compose up -d

# 或者一步完成
docker compose up -d --pull always

Q5: 如何實現零停機更新?

A:

yaml
services:
  app:
    deploy:
      replicas: 3
      update_config:
        parallelism: 1      # 每次更新 1 個
        delay: 10s          # 更新間隔
        order: start-first  # 先啟動新容器

⚠️ 注意:這需要 Docker Swarm 模式,普通 Compose 不支持。可以使用負載均衡器實現類似效果。

總結

通過本文的介紹,相信你已經全面掌握了 Docker Compose 的核心知識:

核心要點回顧

Docker Compose 是什麼

  • 多容器應用編排工具
  • 通過 YAML 文件定義應用架構
  • 一鍵部署和管理複雜應用

核心功能

  • 服務定義和配置
  • 網絡和存儲管理
  • 環境變量管理
  • 容器生命週期控制

最佳實踐

  • 安全加固(非 root、只讀文件系統)
  • 性能優化(多階段構建、緩存)
  • 監控和日誌
  • 備份策略

實際應用

  • 全棧應用部署
  • 微服務架構
  • 開發環境配置

下一步行動

如果你準備好開始使用 Docker Compose:

👉 立即實踐:Docker 入門教程

這裡有 Docker 的基礎知識,幫助你更好地理解容器化技術!

相關資源

官方文檔:

📚 Docker Compose 官方文檔
   https://docs.docker.com/compose/

📚 Docker 最佳實踐
   https://docs.docker.com/develop/

📚 Compose 文件參考
   https://docs.docker.com/compose/compose-file/

本站相關教程:

📖 [Docker 安裝指南](/tw/fe/docker/install.md)
📖 [Docker 容器管理](/tw/fe/docker/container.md)
📖 [Docker 鏡像管理](/tw/fe/docker/mirror.md)
📖 [Jellyfin 媒體服務器部署](/tw/vps/serve/jellyfin-docker.md)
📖 [Vaultwarden 密碼管理器](/tw/vps/serve/vaultwarden-guide.md)

希望這份教程能幫助你高效使用 Docker Compose!如有任何問題,歡迎查看我們的其他相關教程。


延伸阅读

免责声明

本文仅供技术交流和学习参考。涉及第三方服务的链接可能包含 sponsored 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。

最後更新於: