在这篇博文中,我将向您展示如何从您的 github 存储库创建 Docker 映像并将其发布到 Docker 中心容器注册表。因此,无论何时您剪切一个新版本提交到master分支,Github 操作都会构建您的镜像并将其推送到注册表。

为什么?

为什么要将存储库发布为 Linux 容器映像?好问题。并非所有项目都应作为 Linux 容器映像发布。经验法则是,如果您的代码可以用作独立的软件(前端和后端应用程序、服务器、数据库、命令行程序),那么它可以并且应该打包为 Linux 容器。

通过将代码发布到容器注册表(它不必是 Docker 注册表),您可以通过将已发布的容器拉到托管服务提供商、停止旧容器并运行新容器(我'将在以后的文章中向您展示如何做到这一点)。

计划

本教程将与软件语言无关,因为我们不会专注于打包代码本身的过程,但我们将专注于设置持续集成并将它们捆绑在一起(尽管示例存储库是Node.js 服务器应用程序)。

代码

在构建软件时,一个非常重要的规则是master分支应该始终是可部署的。所以我们只会从master分支发布 Docker 镜像,尽管您可以从不同的分支发布并创建不同的镜像,例如canarybeta等......

所以我们对于master分支有两个选择。我们可以在每次提交时将图像发布给主节点,或者我们只能在create/publish a new release时发布图像。

如果您不确定 Github 版本是什么以及如何使用它们,可以查阅Github 文档。

这是 github 操作工作流所需的所有代码。

name: Build and publish Docker image
on:
  release:
    types: [published]
# on:
#   push:
#     branches:
#       - master
jobs:
  push_to_registry:
    name: Build and publish
    runs-on: ubuntu-latest
    steps:
      - name: Get release tag
        id: tag_name
        run: echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/}
      - name: Check out the repo
        uses: actions/checkout@v2
      - name: Npm Install
        run: npm ci
      - name: Npm Build
        run: npm run build
      - name: Login to DockerHub
        run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
      - name: Build image
        env:
          SOURCE_TAG: ${{ steps.tag_name.outputs.SOURCE_TAG }}
        run: ./docker-image/build.sh
      - name: Docker Hub Description
        uses: peter-evans/dockerhub-description@v2
        env:
          DOCKERHUB_USERNAME: ${{ secrets.DOCKER_USERNAME }}
          DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
          DOCKERHUB_REPOSITORY: ivandotv/grant-server

进入全屏模式 退出全屏模式

现在,我将分别解释每个步骤。

首先,我们需要响应在存储库上触发的event。在我们的例子中,我们响应类型为publishedrelease事件。这意味着只有在此事件发生时才会触发工作流。有几种方法可以触发存储库上的release事件,您可以自动化它(通过创建另一个为您执行此操作的工作流),或者您可以手动。您可以从官方文档中阅读更多关于 github 工作流事件的信息。

on:
  release:
    types: [published]

进入全屏模式 退出全屏模式

或者,如果您想响应对master分支的每次推送,您可以使用此代码(在原文中注释掉):

 on:
   push:
     branches:
       - master

进入全屏模式 退出全屏模式

接下来,我们需要设置一个可以完成所有繁重工作的工作。作业 ID 是push_to_registry,而name是“构建和发布”。它将在Ubuntu 20.04上运行

jobs:
  push_to_registry:
    name: Build and publish
    runs-on: ubuntu-20.04
    steps:
    # see next step

进入全屏模式 退出全屏模式

台阶

1 - 由于我们是在新版本之后构建映像(它总是应该有一个 git 标签),我们将检索该标签,稍后将在步骤 6 中使用它。如果您使用的是push to master事件,那么您应该使用最新的提交数据而不是标签,例如git rev-parse --short HEAD

- name: Get release tag
  id: tag_name
  run: echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/}

进入全屏模式 退出全屏模式

2 - 检查存储库。这意味着我们将拥有完整的存储库(所有文件)以在我们的工作流程中使用。

- name: Check out the repo
  uses: actions/checkout@v2

进入全屏模式 退出全屏模式

3 - 由于示例是一个 Node.js 应用程序,我们将安装我们需要的所有节点包依赖项:

- name: Npm Install
  run: npm ci

进入全屏模式 退出全屏模式

4 - 通过从package.json运行build脚本来构建应用程序。

请注意,构建脚本可以运行其他任务,例如linttest,但在这一点上,我们指望应用程序按预期工作,因为所有测试都应该在您在将提交推送到分支时设置的一些先前工作流中完成.

- name: Npm Build
  run: npm run build

进入全屏模式 退出全屏模式

5 - 登录到 Docker 集线器。对于此步骤,您需要设置 github 机密(将在工作流中可用)。我们需要docker usernamedocker password。如何创建秘密在Github docs中有说明

- name: Login to DockerHub
  run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin

进入全屏模式 退出全屏模式

6 - 构建图像。构建 Docker 映像涉及一些命令行调用,因此最好的办法是创建一个脚本,将所有这些命令组合在一个文件中,您可以轻松运行该文件。我们正在设置我们从上一步(steps.tag_name- 步骤 1)中引用的SOURCE_TAG环境变量,该变量将被脚本./docker-image/build.sh(这是存储库本身内的文件)拾取并用于标记 docker 映像在推送到 Docker 集线器之前。

- name: Build image
  env:
    SOURCE_TAG: ${{ steps.tag_name.outputs.SOURCE_TAG }}
  run: ./docker-image/build.sh

进入全屏模式 退出全屏模式

7 - 可选。由于 Docker hub 镜像也有README文件的概念,我们将从存储库中取出README.md并将其放在 Docker hub 上。这样一来,我们就只有一个文档来源,包括 Github 存储库和 Docker 中心。

- name: Docker Hub Description
   uses: peter-evans/dockerhub-description@v2
   env:
    DOCKERHUB_USERNAME: ${{ secrets.DOCKER_USERNAME }}
    DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
    DOCKERHUB_REPOSITORY: ivandotv/grant-server

进入全屏模式 退出全屏模式

这就是将容器映像自动发布到 Docker 集线器所需的全部内容。

现在,如果您查看存储库(下面提供的链接),您将在.github/workflows目录中找到工作流文件。

.github/
└── workflows
    ├── CI.yml
    └── docker-build.yml

进入全屏模式 退出全屏模式

有两个文件:CI.ymldocker-build.yml。本教程中引用的代码来自后面的文件,前一个用于测试代码,发布到 NPM 并创建并标记发布。该文件触发本教程中的工作流 (docker-build.yml) 用于启动发布过程的release事件。如果您正在开发 JavaScript 应用程序,您可能还想查看该文件。

接下来,我们有docker-image目录,里面有两个文件

docker-image/
├── build.sh
└── Dockerfile

进入全屏模式 退出全屏模式

我没有在本教程中介绍这些文件,因为它们用于构建实际的 Docker 映像本身,build.sh文件包含有关如何准备构建过程的命令行说明,而Dockerfile包含构建映像的说明。

存储库:ivandotv/grant-server

Docker 中心页面:授予服务器

感谢您的阅读。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐