GitHub Actions 与 Docker 简介

本指南介绍了如何使用 Docker 和 GitHub Actions 构建 CI(持续集成)流水线。你将学习如何使用 Docker 官方的 GitHub Actions 将你的应用构建为 Docker 镜像并推送到 Docker Hub。通过本指南的学习,你将获得一个简单且功能齐全的用于 Docker 构建的 GitHub Actions 配置。你可以直接使用它,或根据需要进行扩展。

先决条件

如果你想跟着本指南操作,请确保你具备以下条件:

  • 一个 Docker 账户。
  • 熟悉 Dockerfile。

本指南假定你对 Docker 概念有基本的了解,但提供了在 GitHub Actions 工作流程中使用 Docker 的解释。

获取示例应用

本指南与具体项目无关,并假定你有一个包含 Dockerfile 的应用。

如果你需要一个示例项目来跟着操作,可以使用这个示例应用,它包含一个用于构建应用容器化版本的 Dockerfile。另外,你也可以使用你自己的 GitHub 项目或从模板创建一个新的仓库。

#syntax=docker/dockerfile:1

# builder installs dependencies and builds the node app
FROM node:lts-alpine AS builder
WORKDIR /src
RUN --mount=src=package.json,target=package.json \
    --mount=src=package-lock.json,target=package-lock.json \
    --mount=type=cache,target=/root/.npm \
    npm ci
COPY . .
RUN --mount=type=cache,target=/root/.npm \
    npm run build

# release creates the runtime image
FROM node:lts-alpine AS release
WORKDIR /app
COPY --from=builder /src/build .
EXPOSE 3000
CMD ["node", "."]

配置你的 GitHub 仓库

本指南中的工作流程将你构建的镜像推送到 Docker Hub。为此,你必须在 GitHub Actions 工作流程中通过你的 Docker 凭据(用户名和访问令牌)进行认证。

有关如何创建 Docker 访问令牌的说明,请参阅创建和管理访问令牌

准备好你的 Docker 凭据后,将凭据添加到你的 GitHub 仓库,以便在 GitHub Actions 中使用它们

  1. 打开你的仓库的 Settings(设置)。
  2. Security(安全)下,转到 Secrets and variables > Actions(密钥和变量 > Actions)。
  3. Secrets(密钥)下,创建一个名为 DOCKER_PASSWORD 的新仓库密钥,其中包含你的 Docker 访问令牌。
  4. 接下来,在 Variables(变量)下,创建一个包含你的 Docker Hub 用户名的 DOCKER_USERNAME 仓库变量。

设置你的 GitHub Actions 工作流程

GitHub Actions 工作流程定义了一系列步骤,用于响应诸如提交或拉取请求等触发器,自动化执行诸如构建和推送 Docker 镜像之类的任务。本指南中的工作流程侧重于自动化 Docker 构建和测试,确保你的容器化应用在发布前能正常工作。

在你的仓库的 .github/workflows/ 目录下创建一个名为 docker-ci.yml 的文件。从基本的工作流程配置开始:

name: Build and Push Docker Image

on:
  push:
    branches:
      - main
  pull_request:

此配置会在推送到主分支和拉取请求时运行工作流程。通过包含这两个触发器,你可以确保在拉取请求合并之前正确构建镜像。

提取用于标签和注解的元数据

在你的工作流程的第一步中,使用 docker/metadata-action 为你的镜像生成元数据。此操作提取有关你的 Git 仓库的信息,例如分支名称和提交 SHA,并生成镜像元数据,例如标签和注解。

将以下 YAML 添加到你的工作流程文件:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Extract Docker image metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ vars.DOCKER_USERNAME }}/my-image

这些步骤准备元数据,以便在构建和推送过程中标记和注解你的镜像。

  • Checkout(检出)步骤克隆 Git 仓库。
  • Extract Docker image metadata(提取 Docker 镜像元数据)步骤提取 Git 元数据,并为 Docker 构建生成镜像标签和注解。

认证到你的注册表

在构建镜像之前,认证到你的注册表,以确保你可以将构建好的镜像推送到注册表。

要与 Docker Hub 进行认证,请将以下步骤添加到你的工作流程:

      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ vars.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

此步骤使用在仓库设置中配置的 Docker 凭据。

构建并推送镜像

最后,构建最终的生产镜像并将其推送到你的注册表。以下配置构建镜像并将其直接推送到注册表。

      - name: Build and push Docker image
        uses: docker/build-push-action@v6
        with:
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          annotations: ${{ steps.meta.outputs.annotations }}

在此配置中:

  • push: ${{ github.event_name != 'pull_request' }} 确保仅在事件不是拉取请求时才推送镜像。这样,工作流程会为拉取请求构建和测试镜像,但仅为推送到主分支的提交推送镜像。
  • tagsannotations 使用元数据操作的输出自动为镜像应用一致的标签和注解

证明

SBOM(软件物料清单)和出处证明可提高安全性和可追溯性,确保你的镜像符合现代软件供应链的要求。

通过少量额外配置,你可以配置 docker/build-push-action 在构建时为镜像生成软件物料清单 (SBOM) 和出处证明。

要生成这些额外的元数据,你需要对你的工作流程进行两处更改:

  • 在构建步骤之前,添加一个使用 docker/setup-buildx-action 的步骤。此操作会为你的 Docker 构建客户端配置默认客户端不支持的额外功能。
  • 然后,更新 Build and push Docker image(构建并推送 Docker 镜像)步骤,以同时启用 SBOM 和出处证明。

以下是更新后的片段:

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      
      - name: Build and push Docker image
        uses: docker/build-push-action@v6
        with:
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          annotations: ${{ steps.meta.outputs.annotations }}
          provenance: true
          sbom: true

有关证明的更多详细信息,请参阅文档

结论

综合前一节中概述的所有步骤,以下是完整的工作流程配置:

name: Build and Push Docker Image

on:
  push:
    branches:
      - main
  pull_request:

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

      - name: Extract Docker image metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ vars.DOCKER_USERNAME }}/my-image

      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ vars.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      
      - name: Build and push Docker image
        uses: docker/build-push-action@v6
        with:
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          annotations: ${{ steps.meta.outputs.annotations }}
          provenance: true
          sbom: true

此工作流程实现了使用 GitHub Actions 构建和推送 Docker 镜像的最佳实践。此配置可以原样使用,也可以根据你的项目需求扩展额外功能,例如多平台

延伸阅读

页面选项