前端工程化之——自动化部署(GitLab Runner)

900 阅读2分钟

前言

如果你是用 Github ,那你应该选择 Github Actions (Github 官方提供的 CI/CD 流程工具,提供简单易用的持续集成工作流能力)

如果你是用 Gitlab ,想促进前端工程化,想实现自动化部署,那这篇文章会对你有用。

${你GitLab的IP}/help/ci/quick_start/README.md 可以让你稍微先了解 GitLab CI/CD,有个基本的概念。

本文是安装在 Docker 上实现,所以先让我们了解下 Docker 的基本概念。

介绍 Docker

Docker 对我们前端来说是陌生的,但是使用过后,你会明白它的好处。

  • Docker:运行在 Linux/Windows/macOS 中开源的虚拟化引擎,用于创建、管理和编排容器。

  • 镜像(Image):用于创建容器环境的基础虚拟化模板,通过一个镜像可以创建多个容器实例。(依赖项管理,可以当作我们前端中 package.json 的依赖)

  • 容器(Container):Docker 中的核心功能。通常一个容器内包含了一个或多个应用程序以及运行它们所需要的完整相关环境依赖。(可以当作代码的独立运行环境)

在容器内执行命令生成的数据会在容器删除的同时被清除,无法持久化保留。如果要解决持久化保留数据,可以采取两种方式:

  • 数据挂载:挂载容器的宿主环境(即执行启动容器命令所在的服务器)的目录。

  • 数据卷:可以理解为通过 Docker 引擎创建的宿主环境下的独立磁盘空间,用于在容器内读写数据,生命周期独立,不受容器生命周期的影响。

使用 Docker 的优势:

  • 每个项目在独立的容器内执行,保证容器与宿主环境之间,容器与容器之间的环境隔离,防止共用一台服务器时可能产生的互相影响(例:修改了全局依赖)。

  • 可以方便地针对同一个项目生成多套不同的环境。

gitlab runner 自动编译打包

Docker 内安装 GitLab Runner

确定 GitLab Runner 要安装到 Docker、Linux、macOS、Windows ...... 上(对应的安装说明)。

本文是安装在 Docker 内,所以执行以下命令 (docker文档)。

创建 Docker 卷:

docker volume create gitlab-runner-config

运行名为 gitlab-runner 的容器,开启 docker 时自动启动,绑定挂载卷,使用最新的版本的 gitlab-runner 镜像:

docker run -d --name gitlab-runner --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v gitlab-runner-config:/etc/gitlab-runner gitlab/gitlab-runner:latest

Docker 内注册 GitLab Runner

注册 Runners ,同上也是找到对应的注册说明

执行下面命令:

docker run --rm -it -v gitlab-runner-config:/etc/gitlab-runner gitlab/gitlab-runner:latest register

然后需要输入的 url 和 token 从下图去查找。

image.png

然后3次回车➡输入docker➡输入gitlab-runner:latest。

最后如下: image.png

编写 .gitlab-ci.yml 实现自动编译打包

.gitlab-ci.yml 如何配置,文档请看 ${你GitLab的IP}/help/ci/yaml/README.md

因为是在 docker 内,所以我们需要指定运行的需要镜像。(如果你想要指定 node 的版本,docker 对应的镜像去这里查看

image: node:16.15.0

如果少了指定的镜像会报下面的错误:

bash: line 71: npm: command not found\
ERROR: Job failed: exit status 1

具体的 .gitlab-ci.yml 的配置如下:

# 阶段
stages:
  - install
  - build
  - deploy

#Docker 镜像
image: node:16.15.0

# 安装依赖
install:
  stage: install

  # 执行脚本
  script:
    - if [[ ! -d node_modules ]] || [[ -n `git diff --name-only HEAD~1 HEAD | grep "\package.json\b"` ]];
      then  npm install;
      else  echo "跳过install"; fi
  #只在master分支执行
  only:
    - master
    
# 缓存node_modules包
cache:
  paths:
    - node_modules/

# 打包项目
build:
  stage: build
  script:
    - npm build
 # 文件储存传递给下一个工作阶段
  artifacts:
    paths:
      - dist/
  #只在master分支执行
  only:
    - master    

至此,提交 .gitlab-ci.yml 到 git 上,我们就实现了 master 分支提交代码时,自动编译打包。

但是,打包出来的资源文件在 docker 内,所以我们还需要复制到对应服务器的对应位置。

部署

实现使用的是 shell 的 scp 命令,实现文件传输。但是在此之前,我们先实现一下免密登录。

ssh 免密登录

执行以下命令(然后一直回车)生成私钥公钥文件:

ssh-keygen -t rsa

将公钥文件传输到另一台服务器:

ssh-copy-id -i ~/.ssh/id_rsa.pub root@服务器IP

image.png

如果按照上面的命令没有实现免登录,一些权限需要改一下,可以看下解决SSH免密登录配置成功后不生效问题

配置密钥变量

因为执行的环境是在 docker 的容器内的,所以是没有对应的 .ssh文件。

我们通过自定义变量的形式传入密钥,在部署的时候生成 .ssh。

输入以下命令,查看私钥:

cat ~/.ssh/id_rsa

复制私钥到如下图的变量。

image.png

编写 .gitlab-ci.yml 实现自动部署

加上以下代码到 .gitlab-ci.yml:

# 部署项目
deploy:
  # 写入密钥 并配置 ~/.ssh/config 文件
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - ssh-add <(echo "$SSH_PRIVATE_KEY")
    - mkdir -p ~/.ssh
    - '[[ -f /.dockerenv ]] && echo -e "Host *\\n\\tStrictHostKeyChecking no\\n\\n" > ~/.ssh/config'
  
  dependencies:
    - build

  stage: deploy
  script:
    - rm -rf /var/www/
    - scp -r $CI_PROJECT_DIR/build/* root@服务器IP:/var/www/
    - echo 'deploy 结束'
  #只在master分支执行
  only:
    - master

(CI_PROJECT_DIR 是预定义的环境变量,具体可以看这 ${你GitLab的IP}/help/ci/variables/README.md

结尾

最后梳理出来就几个点,但是为了知道是这几个点,折腾了好几天。

如果按照我这做还有不明白的,请留言。如果对你有用,请点赞鼓励~