GitHub Actions 自动化 Node.js 程序

2020-10-25

发明了新的料理,不来尝一下嘛

关于前言

关于前置知识

  • 一点点 node
  • 一点点 docker
  • 一点点 git

关于本文的内容:

  • 使用 Docker 部署应用
  • 使用 GitHub Action 持续集成 Node 应用到 Docker Hub

请预先准备一个 node 的 hello world 的程序,node 官网有提供最简单的例子

关于 node 的 docker 镜像

docker 镜像化现有应用, 需要一个 dockerfile.dockerignore,以下是例子内的 dockerfile

# 使用父镜像
FROM node:current-slim
# 设置工作目录
WORKDIR /usr/src/app
# 将文件从主机复制到当前位置
COPY package.json .
# 影像文件中运行命令
RUN npm install
# 描述容器运行时监听的端口
EXPOSE 6060
# 在容器中运行的命令
CMD [ "npm", "start" ]
# 将应用程序的其余源代码从您的主机复制到映像文件系统
COPY . ./

dockerfile 复制了 package.json ,运行 npm install ,并启动了端口号 6060 的 node 服务

可以使用以下 docker 指令来生成 http://localhost:6060 的服务

Terminal window
# 生成 docker image
docker build -t na-example .
# 运行 docker image
docker run -dp 6060:6060 --name na-example na-example

关于 Github Action 自动化的流程

大致期望的流程如下:

  1. git push 最新代码
  2. GitHub Action 开始运行
  3. docker build 最新代码镜像
  4. docker login 默认登陆 https://hub.docker.com/
  5. docker push 推送镜像

GitHub Action 可以自己项目内 Action 项目内选择开源的 workflow 生成,选择 docker 的 workflow ,会在项目内生成 .github/workflows/docker.yml 文件,本项目是从 docker 的 workflow 衍生的

name: Docker
on:
push:
# Publish `main` as Docker `latest` image.
branches:
- main
# Publish `v1.2.3` tags as releases.
tags:
- v*
# Run tests for any PRs.
pull_request:
branches:
- main
env:
IMAGE_NAME: na-example
DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}}
DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build image
run: docker build -t $IMAGE_NAME .
- name: Log into DockHub
run: docker login -u ${{secrets.DOCKER_USERNAME}} -p ${{secrets.DOCKER_PASSWORD}}
- name: Push image to DockHub
run: |
IMAGE_ID=$DOCKER_USERNAME/$IMAGE_NAME
# 转换成小写
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
# 从版本中删除 github-ref Or github-sha 前缀
VERSION=$(echo "${{ github.sha }}" | sed -e 's,.*/\(.*\),\1,')
# 从标签名称中删除 v 前缀
# [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
# Use Docker `latest` tag convention
[ "${{ github.ref }}" == "main" ] && VERSION=latest
# 保留前 7 位
VERSION=${VERSION:0:7}
# 打印 IMAGE_ID
echo IMAGE_ID=$IMAGE_ID
# 打印 VERSION
echo VERSION=$VERSION
docker tag $IMAGE_NAME ${IMAGE_ID}:$VERSION
docker push $IMAGE_ID:$VERSION

解析以下这个文件

line 1-10:当推送代码至 main 分支或 tag 中有关键字 v 的时候,就会触发工作流

line 12-15:工程流内拉取的分支即是 main

line 17-20:定义工作流内的自定义环境变量

line 24runs-on 工作流的运行环境

line 26-27:工作流步骤,以及工作流运行环境

line 28-32:生成 docker 镜像以及登陆 docker.hub

line 34-60:运行 shell 脚本,条件定义 imagetag,然后上传至 docker.hub

Secrets

使用 Secrets 作为 env 变量,需要通过 GitHub 进行设置,项目内 Setting -> Secrets 进行创建即可

PS:比较优秀的事是,即便是相关字符串,在 GitHub Action 内也是 * 号显示的

关于遇到的问题

Q:关于 node 项目使用 127.0.0.1 或 localhost 作为启动 IP 生成 docker image 化后,运行后无法访问

A:由于 127.0.0.1 或 localhost 是指向镜像内的 IP,非对外 IP,如果需要对外访问,可把启动 IP 修改位 0.0.0.0

Q:关于 GitHub Action 默认的环境变量

A:可参考 Context and expression syntax for GitHub Actionsenvironment-variables

关于小结

本文项目所有代码均从 na-example 粘贴而来

感谢阅读


关于参考

Random Read