使用 Docker 与 Packages
GitHub 的容器注册表是 ghcr.io
。容器镜像可以由组织或个人账户拥有,但你可以自定义每个镜像的访问权限。默认情况下,镜像会继承工作流运行的仓库的可见性和权限模型。
如果你想自己尝试,可以按照这里的逐步指南进行操作: GitHub容器示例。按照以下步骤来理解构建过程:
-
创建一个新的仓库,命名为
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!"。 -
现在,在
.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 }}
-
创建一个新的发布和标签以触发工作流。工作流完成后,你可以在 Code | Packages 中找到包的详细信息和设置(见图 8.4)。
Figure 1. 图 8.4 – 容器包的详细信息和设置GitHub 现在会创建一个新的 Docker 镜像,并将其添加到注册表中,每当你创建新的发布时。
-
你可以从注册表中本地拉取容器并运行:
$ docker pull ghcr.io/<user>/container-demo:latest $ docker run --rm ghcr.io/<user>/container-demo:latest > Hello World!
请注意,如果你的包不是公开的,在拉取镜像之前,你必须使用
docker login ghcr.io
进行身份验证。
GitHub 的容器注册表是发布软件的一个很好的方式。从命令行工具到完整的微服务,你可以发布带有所有依赖项的软件,供其他人使用。