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 左右,比官方的 ubuntu、debian 小一個數量級。對於大多數語言(如 Python, Node.js, Go),都有基於 Alpine 的官方鏡像。
python:3.9-alpinenode: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定義,它們會共享一個虛擬網絡,可以直接通過服務名作為主機名相互訪問,無需映射端口到宿主機。這在微服務架構中非常有用。
總結:讓開發更輕鬆的核心思路
- 緩存思維:構建鏡像時,最大化利用緩存。
- 最小化原則:最終鏡像只包含運行所需,安全、高效。
- 持久化數據:重要數據(如數據庫文件)務必使用 Volume,避免容器銷燬後數據丟失。
- 組合使用:日常開發中,
Dockerfile+docker-compose.yml+.dockerignore是黃金組合。
將這些技巧融入你的日常開發流程,你會發現 Docker 不再是負擔,而是一個強大且順手的開發利器!