Docker 容器化進階:自動化部署與 CI/CD 實戰指南 本文承接從零開始的 Docker 容器化指南 ,主要討論如何實現全自動化的 Docker 部署流程。透過整合 GitHub Actions、Docker Hub 和自動化工具,我們可以實現程式碼推送後自動更新生產環境的目標。
目錄
自動化部署概述 完整的自動化部署流程包含以下步驟:
開發者推送程式碼到 GitHub
GitHub Actions 自動執行測試和建置
建立新的 Docker 映像檔並推送至 Docker Hub
生產環境自動偵測並更新容器
健康檢查確認部署狀態
部署流程圖 graph TD
A[開發者推送程式碼] --> B[GitHub Actions 觸發]
B --> C[執行測試]
C --> D[建立 Docker 映像檔]
D --> E[推送至 Docker Hub]
E --> F[生產環境更新]
F --> G[健康檢查]
G -->|成功| H[部署完成]
G -->|失敗| I[自動回滾]
GitHub Actions 設定 1. 基礎設定 建立 .github/workflows/deploy.yml 檔案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 name: Deploy to Production on: push: branches: [ main ] workflow_dispatch: jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Cache Docker layers uses: actions/cache@v2 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx- - name: Login to Docker Hub uses: docker/login-action@v1 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - name: Build and push uses: docker/build-push-action@v2 with: context: . push: true tags: | user/myapp:latest user/myapp:${{ github.sha }} cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new - name: Move cache run: | rm -rf /tmp/.buildx-cache mv /tmp/.buildx-cache-new /tmp/.buildx-cache
2. 部署到伺服器 添加遠端部署步驟:
1 2 3 4 5 6 7 8 9 - name: Deploy to Production uses: appleboy/ssh-action@master with: host: ${{ secrets.SERVER_HOST }} username: ${{ secrets.SERVER_USER }} key: ${{ secrets.SERVER_SSH_KEY }} script: | cd /path/to/project ./deploy.sh ${{ github.sha }}
自動更新容器設定 1. Watchtower 設定 Watchtower 可以自動監測和更新 Docker 容器:
1 2 3 4 5 6 7 8 9 10 11 12 13 services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - WATCHTOWER_CLEANUP=true - WATCHTOWER_LABEL_ENABLE=true - WATCHTOWER_NOTIFICATION_URL=slack://hook-url labels: - "com.centurylinklabs.watchtower.enable=true" command: --interval 300
2. 容器標籤設定 為需要自動更新的服務加上標籤:
1 2 3 4 services: api: labels: - "com.centurylinklabs.watchtower.enable=true"
零停機部署策略 1. 藍綠部署 建立部署腳本 deploy.sh:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #!/bin/bash APP_NAME="myapp" BLUE_PORT="8080" GREEN_PORT="8081" PROXY_PORT="80" VERSION=$1 ACTIVE_COLOR=$(docker ps --filter "name=${APP_NAME} -" --format "{{.Names}}" | grep -o 'blue\|green' ) if [ "$ACTIVE_COLOR " == "blue" ]; then NEW_COLOR="green" NEW_PORT=$GREEN_PORT else NEW_COLOR="blue" NEW_PORT=$BLUE_PORT fi echo "Starting $NEW_COLOR deployment..." docker-compose -f docker-compose.$NEW_COLOR .yml up -d --build sleep 10if curl -f "http://localhost:$NEW_PORT /health" ; then echo "Switching traffic to $NEW_COLOR deployment" docker-compose -f docker-compose.proxy.yml up -d --force-recreate if [ -n "$ACTIVE_COLOR " ]; then docker-compose -f docker-compose.$ACTIVE_COLOR .yml down fi echo "Deployment successful!" else echo "Health check failed! Rolling back..." docker-compose -f docker-compose.$NEW_COLOR .yml down exit 1 fi
2. 健康檢查設定 在服務中設定健康檢查:
1 2 3 4 5 6 7 8 services: api: healthcheck: test: ["CMD" , "curl" , "-f" , "http://localhost/health" ] interval: 30s timeout: 10s retries: 3 start_period: 40s
備份與還原機制 1. 自動備份設定 建立備份腳本 backup.sh:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #!/bin/bash BACKUP_DIR="/backups" TIMESTAMP=$(date +%Y%m%d_%H%M%S) mkdir -p $BACKUP_DIR docker-compose config > $BACKUP_DIR /docker-compose-$TIMESTAMP .yml docker-compose exec -T db sh -c 'mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" --all-databases' > $BACKUP_DIR /db-$TIMESTAMP .sql find $BACKUP_DIR -type f -mtime +7 -delete
2. 還原流程 建立還原腳本 restore.sh:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #!/bin/bash if [ -z "$1 " ]; then echo "Please provide backup timestamp" exit 1 fi TIMESTAMP=$1 BACKUP_DIR="/backups" if [ ! -f "$BACKUP_DIR /docker-compose-$TIMESTAMP .yml" ] || [ ! -f "$BACKUP_DIR /db-$TIMESTAMP .sql" ]; then echo "Backup files not found" exit 1 fi docker-compose down cp $BACKUP_DIR /docker-compose-$TIMESTAMP .yml docker-compose.ymldocker-compose up -d docker-compose exec -T db sh -c "mysql -u root -p\"$MYSQL_ROOT_PASSWORD \"" < $BACKUP_DIR /db-$TIMESTAMP .sql
監控與告警設定 1. Prometheus 設定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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. 告警設定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 alerting: alertmanagers: - static_configs: - targets: - alertmanager:9093 rule_files: - alert.rules.yml scrape_configs: - job_name: 'docker' static_configs: - targets: ['localhost:9323' ]
故障排除與回滾流程 1. 常見問題處理
映像檔拉取失敗
容器啟動失敗
健康檢查失敗
資料庫連線問題
2. 回滾流程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #!/bin/bash VERSION=$1 if [ -z "$VERSION " ]; then echo "Please specify version to rollback" exit 1 fi docker-compose pull export APP_VERSION=$VERSION docker-compose down docker-compose up -d
最佳實踐建議
版本管理
使用語意化版本號
保留歷史版本映像檔
定期清理舊版本
監控策略
設定關鍵指標監控
建立適當的告警閾值
保留足夠的日誌資訊
部署安全
使用加密的環境變數
實施適當的存取控制
定期更新基礎映像檔
效能優化
結論 透過本文介紹的自動化部署流程,我們可以大幅減少人工操作,提高部署效率和可靠性。記得根據實際需求調整配置,並持續優化部署流程。
參考資源