使用 Docker 与 Packages

GitHub 的容器注册表是 ghcr.io。容器镜像可以由组织或个人账户拥有,但你可以自定义每个镜像的访问权限。默认情况下,镜像会继承工作流运行的仓库的可见性和权限模型。

如果你想自己尝试,可以按照这里的逐步指南进行操作: GitHub容器示例。按照以下步骤来理解构建过程:

  1. 创建一个新的仓库,命名为 container-demo,并添加一个非常简单的 Dockerfile(无扩展名):

    FROM alpine
    CMD ["echo", "Hello World!"]

    该 Docker 镜像继承自 Alpine 发行版,并将 "Hello World!" 输出到你的控制台。如果你是 Docker 新手并想尝试,可以克隆该仓库并切换到本地仓库的根目录。构建镜像:

    $ docker build -t container-demo

    然后运行容器:

    $ docker run --rm container-demo

    --rm 参数会在容器完成后自动删除它。这应该会在控制台上输出 "Hello World!"。

  2. 现在,在 .github/workflows/ 中创建一个名为 release-container.yml 的工作流文件。每次创建新发布时,工作流将会被触发:

    name: Publish Docker image
    on:
     release:
       types: [published]

    注册表和镜像名称设置为环境变量。这里我使用仓库名称作为镜像名称,你也可以在这里设置固定的名称:

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

    该作业需要包写入权限,并且需要克隆仓库:

    jobs:
     build-and-push-image:
       runs-on: ubuntu-latest
       permissions:
         contents: read
         packages: write
       steps:
         - name: Checkout repository
           uses: actions/checkout@v2

    docker/login-action 使用 GITHUB_TOKEN 进行身份验证,这是推荐的方式:

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

    metadata-action 提取 Git 上下文的元数据,并将标签应用于 Docker 镜像。当我们创建发布时,会推送一个标签(refs/tags/<tagname>)。该操作将使用与 Git 标签相同的名称创建 Docker 标签,并为镜像创建 latest 标签。请注意,元数据作为输出变量传递到下一个步骤!因此,我为此步骤设置了一个 id

         - name: Extract metadata (tags, labels)
           id: meta
           uses: docker/metadata-action@v3.5.0
           with:
             images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

    build-push-action 构建镜像并将其推送到容器注册表。标签和标签是从元数据步骤的输出中提取的:

         - name: Build and push Docker image
           uses: docker/build-push-action@v2.7.0
           with:
             context: .
             push: true
             tags: ${{ steps.meta.outputs.tags }}
             labels: ${{ steps.meta.outputs.labels }}
  3. 创建一个新的发布和标签以触发工作流。工作流完成后,你可以在 Code | Packages 中找到包的详细信息和设置(见图 8.4)。

    image 2024 12 27 13 19 05 003
    Figure 1. 图 8.4 – 容器包的详细信息和设置

    GitHub 现在会创建一个新的 Docker 镜像,并将其添加到注册表中,每当你创建新的发布时。

  4. 你可以从注册表中本地拉取容器并运行:

    $ docker pull ghcr.io/<user>/container-demo:latest
    $ docker run --rm ghcr.io/<user>/container-demo:latest
    > Hello World!

    请注意,如果你的包不是公开的,在拉取镜像之前,你必须使用 docker login ghcr.io 进行身份验证。

GitHub 的容器注册表是发布软件的一个很好的方式。从命令行工具到完整的微服务,你可以发布带有所有依赖项的软件,供其他人使用。