Docker 已經成為現代開發的基石,但如果沒有一些技巧,可能會覺得笨重或繁瑣。掌握一些實用小技巧,能極大提升開發效率和舒適度。

下面我將從開發流程的不同階段,為你總結一些非常實用的 Docker 技巧。


一、 鏡像構建優化:更快、更小、更安全

這是最能體現 Docker 技巧的地方,直接影響構建速度和部署效率。

1. 巧用 .dockerignore 文件.gitignore 類似,它告訴 Docker 在構建時忽略哪些文件和目錄。這能避免發送不必要的文件到 Docker 守護進程,減少構建上下文大小,顯著加速構建過程。

# 示例 .dockerignore
.git
node_modules
npm-debug.log
README.md
.env
.idea
*.tmp
.DS_Store

2. 充分利用構建緩存(多階段構建) Docker 會按 Dockerfile 的指令順序逐層構建,並緩存每一層。改變某一層及其之後的所有層緩存都會失效。

  • 技巧: 將變化最少的層放在前面(如安裝依賴),變化頻繁的層(如複製源代碼)放在後面。
  • 高級技巧: 使用多階段構建,最終鏡像只包含運行所需的最少內容,極大減小鏡像體積。
    # 階段一:構建階段
    FROM golang:1.19 AS builder
    WORKDIR /app
    COPY . .
    RUN go mod download
    RUN go build -o /myapp
    
    # 階段二:運行階段(使用極小的基礎鏡像)
    FROM alpine:latest
    WORKDIR /root/
    COPY --from=builder /myapp . # 只從上一階段拷貝編譯好的二進制文件
    CMD ["./myapp"]
    

3. 使用更小的基礎鏡像 Alpine Linux 鏡像通常只有 5MB 左右,比官方的 ubuntudebian 小一個數量級。對於大多數語言(如 Python, Node.js, Go),都有基於 Alpine 的官方鏡像。

  • python:3.9-alpine
  • node:16-alpine

二、 容器運行與調試:更順手

1. 使用 docker exec -it 進入運行中的容器 這是最常用的調試命令,可以像 SSH 一樣進入容器內部。

docker exec -it <container_name_or_id> /bin/bash
# 或者 /bin/sh (如果基礎鏡像是 Alpine)

2. 清理空間:定期 Prune Docker 會佔用大量磁盤空間,定期清理非常必要。

# 刪除所有已停止的容器、所有未被使用的網絡、所有懸空鏡像
docker system prune

# 更徹底的清理(包括構建緩存)
docker system prune -a

# 只刪除懸空鏡像
docker image prune

3. 查看容器日誌 無需進入容器,實時查看應用日誌。

# 查看最新日誌
docker logs <container_name>

# 實時跟蹤日誌(類似 tail -f)
docker logs -f <container_name>

# 查看最近30分鐘的日誌
docker logs --since 30m <container_name>

三、 Docker Compose 開發流:管理複雜應用

對於多服務應用(如 Web 前端 + API 後端 + 數據庫),Docker Compose 是神器。

1. 使用 Volume 掛載代碼,實現熱重載 在開發時,將本地代碼目錄掛載到容器中。這樣你修改本地代碼,容器內的代碼也會實時更新,結合你框架的熱重載功能(如 Nodemon, Flask debug mode),開發體驗無縫銜接。

docker-compose.yml 示例:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      # 關鍵!將當前目錄掛載到容器的 /app, :ro 表示只讀(可選)
      - .:/app
    environment:
      - NODE_ENV=development
  redis:
    image: "redis:alpine"

2. 使用 depends_on 控制啓動順序 確保服務按依賴順序啓動(例如,數據庫先於 Web 應用啓動)。

services:
  web:
    depends_on:
      - db
      - redis
  db:
    image: postgres
  redis:
    image: redis

注意: depends_on 只控制容器啓動順序,不保證服務已準備就緒。對於更復雜的就緒檢查,需要使用 healthcheck

3. 一鍵啓停整個環境

# 啓動所有服務(在後台運行)
docker-compose up -d

# 查看所有服務的日誌
docker-compose logs -f

# 停止並移除所有容器、網絡
docker-compose down

# 重啓特定服務
docker-compose restart web

四、 網絡與數據管理:知其所以然

1. 給容器起個有意義的別名 使用 --name 參數,便於管理和引用。

docker run -d --name my_redis_container redis:alpine
# 之後就可以用 my_redis_container 來操作,比容器ID方便多了
docker exec -it my_redis_container redis-cli

2. 端口映射與網絡模式

  • -p 8080:80:將宿主機的 8080 端口映射到容器的 80 端口。
  • 在 Docker Compose 中,多個服務可以使用相同的 networks 定義,它們會共享一個虛擬網絡,可以直接通過服務名作為主機名相互訪問,無需映射端口到宿主機。這在微服務架構中非常有用。

總結:讓開發更輕鬆的核心思路

  1. 緩存思維:構建鏡像時,最大化利用緩存。
  2. 最小化原則:最終鏡像只包含運行所需,安全、高效。
  3. 持久化數據:重要數據(如數據庫文件)務必使用 Volume,避免容器銷燬後數據丟失。
  4. 組合使用:日常開發中,Dockerfile + docker-compose.yml + .dockerignore 是黃金組合。

將這些技巧融入你的日常開發流程,你會發現 Docker 不再是負擔,而是一個強大且順手的開發利器!