GitHub Actions 容器部署 #

Docker容器是现代应用部署的标准方式。本节介绍如何使用GitHub Actions构建和部署Docker镜像。

Docker部署概述 #

容器部署流程 #

text
代码 → 构建 → 测试 → 构建镜像 → 推送镜像 → 部署

镜像仓库 #

仓库 描述
Docker Hub 公共镜像仓库
GitHub Container Registry GitHub提供的仓库
AWS ECR AWS容器仓库
Google GCR Google容器仓库

登录镜像仓库 #

Docker Hub #

yaml
- uses: docker/login-action@v3
  with:
    username: ${{ secrets.DOCKER_USERNAME }}
    password: ${{ secrets.DOCKER_PASSWORD }}

GitHub Container Registry #

yaml
- uses: docker/login-action@v3
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

AWS ECR #

yaml
- uses: aws-actions/configure-aws-credentials@v4
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: us-east-1

- uses: docker/login-action@v3
  with:
    registry: ${{ steps.login-ecr.outputs.registry }}

构建Docker镜像 #

基本构建 #

yaml
- uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: user/app:latest

多平台构建 #

yaml
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3

- uses: docker/build-push-action@v5
  with:
    context: .
    platforms: linux/amd64,linux/arm64
    push: true
    tags: user/app:latest

多标签 #

yaml
- uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: |
      user/app:latest
      user/app:1.0.0
      user/app:${{ github.sha }}

使用缓存 #

yaml
- uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: user/app:latest
    cache-from: type=gha
    cache-to: type=gha,mode=max

完整工作流示例 #

基本CI/CD #

yaml
name: Docker CI/CD

on:
  push:
    branches: [main]
    tags: ['v*']
  pull_request:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

带测试的CI/CD #

yaml
name: Docker CI/CD

on:
  push:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npm test

  build:
    needs: test
    runs-on: ubuntu-latest
    outputs:
      image: ${{ steps.build.outputs.image }}
    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push
        id: build
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: Deploy to production
        run: |
          echo "Deploying image ${{ needs.build.outputs.image }}"

多平台构建 #

yaml
name: Multi-platform Build

on:
  push:
    tags: ['v*']

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: |
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}

部署到Kubernetes #

使用kubectl #

yaml
- uses: azure/k8s-set-context@v3
  with:
    kubeconfig: ${{ secrets.KUBE_CONFIG }}

- uses: azure/k8s-deploy@v4
  with:
    namespace: default
    manifests: |
      kubernetes/deployment.yaml
      kubernetes/service.yaml
    images: |
      ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}

使用Helm #

yaml
- uses: azure/k8s-set-context@v3
  with:
    kubeconfig: ${{ secrets.KUBE_CONFIG }}

- name: Deploy with Helm
  run: |
    helm upgrade --install myapp ./chart \
      --set image.tag=${{ github.sha }} \
      --namespace default

部署到云服务 #

AWS ECS #

yaml
- uses: aws-actions/configure-aws-credentials@v4
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: us-east-1

- uses: aws-actions/amazon-ecs-deploy-task-definition@v1
  with:
    task-definition: task-definition.json
    service: my-service
    cluster: my-cluster

Google Cloud Run #

yaml
- uses: google-github-actions/setup-gcloud@v2
  with:
    project_id: ${{ secrets.GCP_PROJECT_ID }}
    service_account_key: ${{ secrets.GCP_SA_KEY }}

- name: Deploy to Cloud Run
  run: |
    gcloud run deploy myapp \
      --image gcr.io/${{ secrets.GCP_PROJECT_ID }}/myapp:${{ github.sha }} \
      --platform managed \
      --region us-central1

Azure Container Instances #

yaml
- uses: azure/login@v1
  with:
    creds: ${{ secrets.AZURE_CREDENTIALS }}

- uses: azure/aci-deploy@v1
  with:
    resource-group: myResourceGroup
    dns-name-label: myapp
    image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
    name: myapp
    location: eastus

最佳实践 #

1. 使用镜像标签策略 #

yaml
tags: |
  user/app:latest
  user/app:${{ github.sha }}
  user/app:${{ github.ref_name }}

2. 使用缓存加速 #

yaml
cache-from: type=gha
cache-to: type=gha,mode=max

3. 扫描漏洞 #

yaml
- uses: aquasecurity/trivy-action@master
  with:
    image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
    severity: CRITICAL,HIGH

4. 使用环境保护 #

yaml
environment: production

5. 多阶段构建 #

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

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]

下一步学习 #

小结 #

  • 使用docker/login-action登录镜像仓库
  • 使用docker/build-push-action构建镜像
  • 支持多平台构建
  • 使用缓存加速构建
  • 可以部署到Kubernetes和云服务
  • 使用镜像标签策略管理版本
最后更新:2026-03-28