如何使用GitHub Actions将Node.js Docker镜像发布到Docker Hub注册处

411 阅读4分钟

生态 系统工程

如何使用GitHub Actions将Node.js Docker镜像发布到Docker Hub注册中心

Liran Tal 2021年8月9日

在上一篇文章中,我们介绍了如何使用GitHub Actions将Node.js Docker镜像发布到GitHub Packages注册处的分步教程。在这篇文章中,我们将重点介绍如何将我们构建的Docker镜像发布到公共的Docker Hub注册表上。

你可能会问这有什么用?Docker命令行应用程序docker 有一个默认的注册表设置docker.io ,它指向Docker Hub注册表。如果你想把Snyk CLI作为Docker镜像使用,这就提供了一个很好的开发者体验,即通过<user>/<repository> 惯例来拉取镜像,比如下面这个例子。

docker pull snyk/snyk-cli

在这篇文章中,我们将通过一步步的演练来配置另一个Docker镜像的构建和发布工作流程,它可以与我们之前介绍的GitHub包注册表的工作流程并列运行。

就像上一篇文章一样,这篇文章跟进了Dockly,这个开源的Node.js命令行工具用于从CLI管理docker容器,并展示了如何将Docker镜像推送到Docker Hub。你可以在Dockly的GitHub仓库中查看最终的工作流程

创建一个GitHub Actions工作流

要添加一个新的工作流,你可以简单地在.github/workflows/ 目录中创建一个新文件,或者浏览到你在GitHub上的开源仓库,点击Actions标签,然后点击New Workflow,开始一个新的工作流。

A GitHub Actions workflow status

选择Docker Hub发布工作流文件的文件名,如:docker-publish-to-dockerhub.yml

如果你是在GitHub的用户界面上进行操作,它可能会预先填充工作流文件,在这种情况下,只需删除它并添加以下内容。

name: "Docker: Docker Hub"

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

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

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

我们已经在上一篇文章中详细介绍了这些内容,但要回顾一下。

  • 这个Docker Hub工作流将在每次推送、标签发布和对仓库主分支的拉取请求中运行。
  • 全局环境变量将REGISTRY 定义为docker.io ,这意味着我们的镜像将从Docker Hub推送和提供,而IMAGE_NAME 则设置为GitHub的用户名和仓库名称。如果你有一个不同的Docker Hub用户名,那么你可能需要对这个进行调整。

接下来,我们将定义我们的作业,在其中建立一个构建Docker镜像的过程,然后发布它。

登录到Docker Hub,构建并发布Docker镜像

接下来,我们将需要执行以下操作。

  1. 登录Docker Hub,为此我们需要在Docker Hub中创建一个令牌,并在GitHub仓库设置中把它设置为仓库秘密。
  2. 提取我们构建的Docker镜像的元数据,这样它就可以供镜像的构建过程使用。
  3. 将构建的Docker镜像推送到Docker Hub。

上述内容是通过以下代码段建立的,需要将其添加到我们在上一步创建的工作流内容中。

jobs:
  build_and_publish:
  
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v2


      - name: Log into registry ${{ env.REGISTRY }}
        if: github.event_name != 'pull_request'
        uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Extract Docker metadata
        id: meta
        uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          flavor: |
            latest=true
            prefix=
            suffix=

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

一旦你应用了工作流文件,并将其合并到主分支,你应该有希望最终成功构建,导致一个新的Docker镜像被推送到Docker Hub注册中心。

A successful deploy of a Docker base image to the Docker Hub registry, from a GitHub Actions workflow

一个已知的注意事项是,在这个时候,你发布镜像的Docker Hub仓库不会自动弹出适当的描述和README内容,因为官方docker/build-and-push GitHub行动中没有这个内容。

如果你想寻求这种能力,维护者推荐市场上的GitHub ActionDocker Hub描述,并在他们的文档中指出一个例子参考,你可以采用。

从Docker Hub注册表中提取Docker镜像

要从Docker Hub获取新的Docker镜像,你所需要做的就是运行熟悉的docker pull 命令,比如说。

$ docker pull <user>/<repository>
Using default tag: latest
latest: Pulling from <user>/<repository>
b4d181a07f80: Pulling fs layer
de8ecf497b75: Pulling fs layer
69b92f9e5e70: Pulling fs layer
1f2b8e2c8ad8: Waiting
d0f4259cb643: Waiting
9ae47f3f99ba: Waiting
87270829eb60: Waiting
905fc634546c: Waiting

你在推送脆弱的Docker镜像吗?

为什么停在这里?你可以通过Snyk查找、监控,甚至修复Docker镜像中的漏洞。你可以采用最适合的工作流程,不管你是喜欢CLI,还是直接从Docker Hub导入Docker镜像,这样你就可以监控它们的安全漏洞。
你知道docker scan 命令是由Snyk提供的吗?我的同事Eric Smalling写了一份详细的最佳实践指南,关于开发者驱动的工作流程--Docker文件和镜像扫描、优先级和修复,如果你想加深这方面的知识。
最后,有一个Snyk GitHubAction,你可以在GitHub Actions生态系统中使用,以扫描开源库和容器镜像的安全漏洞。

更深入

如果你想进一步探索构建Docker镜像的最佳实践,我建议你看以下内容。

  1. 用Docker将Node.js网络应用容器化的10个最佳实践
  2. 面向Node.js开发者的Docker。你需要知道的5件事,不要让你的安全失败

如果你没有读过前面的文章,想把Docker镜像发布到GitHub包中,那么请阅读如何 使用GitHub Actions把Node.js Docker镜像发布到GitHub包 注册中心。

免费保护你的SDLC

注册Snyk来保护你的代码、依赖关系、容器和IaC。

免费注册

加入我们在2021年的SnykCon

我们将在为期3天的免费虚拟活动中把开发和安全结合起来,专注于帮助团队安全地构建。

现在注册