這是一篇為您定製的 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")

想象您要部署一個博客系統,需要:

  1. 啓動 PostgreSQL 數據庫。
  2. 啓動 Redis 緩存。
  3. 啓動 Spring Boot 應用,並配置環境變量連上 DB 和 Redis。
  4. 啓動 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 是核心。它主要包含三個頂級概念:

  1. Services (服務): 定義各個容器(如 web, db, redis)。
  2. Networks (網絡): 定義服務之間的通信通道。
  3. 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 (橫槓)。

命令

描述

場景

docker compose up -d

後台啓動所有服務

最常用的命令,相當於“一鍵部署”

docker compose down

停止並移除容器和網絡

清理環境

docker compose ps

查看當前項目的容器狀態

檢查誰掛了

docker compose logs -f

實時查看所有服務的日誌

調試神器,類似 tail -f

docker compose logs -f web

只看 web 服務的日誌

精準調試

docker compose exec web sh

進入 web 容器內部

類似 ssh 進入容器

docker compose restart web

重啓某個服務

修改代碼或配置後生效

docker compose build

重新構建鏡像

當 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. 常見大坑與排查

  1. depends_on 的誤解:
  • depends_on: - db 只是保證啓動順序(先發 db 的啓動指令,再發 web 的)。
  • 不保證 db 已經完全初始化完畢(Ready)。如果 Web 應用啓動太快,連數據庫可能會報錯。
  • 解決: 在 Web 容器裏使用 wait-for-it.sh 腳本,或者編寫健康檢查 (Healthcheck)。
  1. 文件權限問題:
  • 將宿主機目錄掛載到數據庫容器(如 MySQL/PG)時,常出現 Permission denied。這是因為宿主機用户 ID 與容器內用户 ID 不一致。
  1. YAML 縮進:
  • YAML 對縮進極其敏感,嚴禁使用 Tab 鍵,必須使用空格(通常是 2 個或 4 個)。

結語

Docker Compose 是單機編排的王者。對於開發環境搭建、CI/CD 流水線測試、以及中小型項目的單機部署,它是效率最高的工具。