概述

构建和发布 Docker 镜像一直是开发和运维工作中的重要环节,但是完全手动的流程往往效率低下,容易出错。使用 GitHub Actions 可以大大简化这个过程,实现自动化和持续化。本文将提供一个详细的指南,讲解如何通过GitHub Actions 的工作流实现自动构建 Docker 镜像并发布到仓库。

目录

  1. 构建 Docker 镜像
    • 使用 GitHub Actions 自动化构建
    • 版本控制和标记 Docker 镜像
  2. 推送 Docker 镜像到容器注册表
    • 推送到 GHCR
    • 推送到 Docker Hub
    • 推送到 Harbor

1. 构建 Docker 镜像

在使用 GitHub Actions 自动化构建 Docker 镜像之前,您需要将现有的构建命令替换为工作流 YAML 文件中的对应命令。下面是一个示例工作流 YAML 文件的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
name: 构建 Docker 镜像
on:
push:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v3

- name: 构建并标记镜像
run: docker build -t ${{ github.repository }}:${{ github.sha }} -f path/to/Dockerfile .

1.1 使用 GitHub Actions 自动化构建

使用 GitHub Actions 自动化构建 Docker 镜像可以确保构建配置的一致性。在工作流 YAML 文件中,镜像的名称是使用 GITHUB_REPOSITORY 环境变量命名的,格式为 ${{ github.repository }}

1.2 版本控制和标记 Docker 镜像

在构建和推送 Docker 镜像时,不要依赖 latest 标签来进行版本控制。推荐使用以下两种版本控制约定之一来为镜像打标签:

  • 使用 GitHub 提交哈希
  • 遵循语义化版本规范

1.2.1 使用 GitHub 提交哈希

GitHub Actions 设置了一些默认的环境变量,您可以在工作流中访问这些变量。其中之一是 GITHUB_SHA,它是触发工作流的提交的哈希值。这是一种非常有价值的版本控制方法,因为您可以将每个镜像追溯到对应的提交。一般来说,我们使用哈希的前七位数字作为版本号。以下是如何访问并提取这些数字的示例代码:

1
2
3
4
- name: 构建并标记镜像
run: |
COMMIT_SHA=$(echo $GITHUB_SHA | cut -c1-7)
docker build -t ${{ github.repository }}:$COMMIT_SHA -f path/to/Dockerfile .

1.2.2 语义化版本控制

使用版本号时,最佳实践是遵循语义化版本规范。这样,当发布新的更新和补丁时,您可以按照一致的结构递增版本号。假设您将应用程序的版本存储在名为 version.txt 的根文件中,您可以从该文件中提取版本号,并在两个单独的步骤中为镜像打标签:

1
2
3
4
5
6
7
- name: 获取版本号
run: |
export VERSION=$(cat version.txt)
echo "版本号: $VERSION"

- name: 构建并标记镜像
run: docker build -t ${{ github.repository }}:$VERSION -f path/to/Dockerfile .

2. 推送 Docker 镜像到容器注册表

您可以在两到三个步骤中轻松地构建、标记和推送 Docker 镜像到您选择的私有容器注册表。以下是一个高级概述,介绍您将要进行的操作:

  • 手动设置身份验证令牌或访问凭证作为仓库机密。
  • 使用 echo 命令将凭证传递给标准输入,以进行注册表身份验证。这样,用户无需执行任何操作。
  • 根据您的注册表文档,填充工作流程中的自定义构建命令。请记住遵循注册表的标记约定。
  • 添加 push 命令。您可以在注册表的文档中找到正确的语法。

为了更好地追踪工作流失败的情况,您可能希望将每个步骤拆分为单独的操作。

2.1 推送到 GHCR

2.1.1 设置 GHCR 凭据

为了访问 GitHub API,您需要生成一个个人访问令牌。您可以通过转到 Settings -> Developer -> New personal access token (classic) 来生成一个自定义令牌,以允许访问包。请确保在 Select scopes 部分选择 write:packages

将此令牌存储为名为 GHCR_TOKEN 的仓库机密。

2.1.2 推送到 GHCR 的操作示例

您可以将以下操作添加到 GitHub Actions 工作流中,这些操作将登录到 GHCR,构建并推送您的 Docker 镜像。

1
2
3
4
5
6
7
8
9
10
- name: 登录到 ghcr.io
run: echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin

- name: 构建并标记镜像
run: |
COMMIT_SHA=$(echo $GITHUB_SHA | cut -c1-7)
docker build -t ghcr.io/${{ github.repository_owner }}/${{ github.repository }}:$COMMIT_SHA -f path/to/Dockerfile .

- name: 推送镜像到 GHCR
run: docker push ghcr.io/${{ github.repository_owner }}/${{ github.repository }}:$COMMIT_SHA

2.2 推送到 Docker Hub

2.2.1 存储 Docker Hub 凭据

使用您的 Docker Hub 登录凭据,设置以下仓库机密:

  • DOCKERHUB_USERNAME
  • DOCKERHUB_PASSWORD

注意:在推送镜像之前,您需要在 Docker Hub 上设置一个仓库。

2.2.2 推送到 Docker Hub 的操作示例

将以下操作添加到工作流中,将自动登录到 Docker Hub,构建和标记镜像,并将其推送到 Docker Hub:

1
2
3
4
5
6
7
8
9
10
11
- name: 登录到 Docker Hub
run: |
echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin

- name: 构建并标记镜像
run: |
COMMIT_SHA=$(echo $GITHUB_SHA | cut -c1-7)
docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.repository }}:$COMMIT_SHA -f path/to/Dockerfile .

- name: 推送镜像到 Docker Hub
run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.repository }}:$COMMIT_SHA

2.3 推送到 Harbor

2.3.1 存储 Harbor 访问凭据

创建两个新的仓库机密来存储以下信息:

  • HARBOR_CREDENTIALS:您的 Harbor 用户名和密码,格式为 username:password
  • HARBOR_REGISTRY_URL:与您个人的 Harbor 注册表对应的 URL

注意:在推送镜像到 Harbor 之前,您需要创建一个 Harbor 项目。

2.3.2 推送到 Harbor 的操作示例

下面的操作将进行 Harbor 身份验证、构建并标记镜像,然后推送镜像到 Harbor:

1
2
3
4
5
6
7
8
9
10
11
- name: 登录到 Harbor
run: |
echo ${{ secrets.HARBOR_CREDENTIALS }} | base64 --decode | docker login -u $(cut -d ':' -f1 <<< "${{ secrets.HARBOR_CREDENTIALS }}") --password-stdin ${{ secrets.HARBOR_REGISTRY_URL }}

- name: 构建并标记镜像
run: |
COMMIT_SHA=$(echo $GITHUB_SHA | cut -c1-7)
docker build -t ${{ secrets.HARBOR_REGISTRY_URL }}/project-name/${{ github.repository }}:$COMMIT_SHA -f path/to/Dockerfile .

- name: 推送镜像到 Harbor
run: docker push ${{ secrets.HARBOR_REGISTRY_URL }}/project-name/${{ github.repository }}:$COMMIT_SHA

结语

希望本文能够帮助您了解如何使用 GitHub Actions 构建和推送 Docker 镜像到容器注册表。通过自动化这一过程,您可以提高开发人员的工作效率,并确保构建的一致性和可追溯性。如果您想了解更多关于 GitHub Actions 的内容,请继续关注我的博客。感谢阅读!