DevOps 之使用 Gitlab CI 构建和部署 Vue 项目

DevOps 之使用 Gitlab CI 构建和部署 Vue 项目

本片文章介绍如何使用 Gitlab Runner 来构建和部署 Vue 项目,通过这篇文章可以大致了解 Node 相关项目的 CI/CD 大致流程。

所需环境

  • Gitlab (可以参考之前的 《DevOps 之快速搭建 Gitlab 服务》
  • 运行 Gitlab Runner 的 Server (可以参考之前的《DevOps 之注册 Gitlab Runner》)
  • 用于部署 Vue 项目的 Server (可以是运行 Gitlab Runner 的服务器, 如果不是,则需要将运行 Gitlab Runner 的服务器的 Public key 添加到用于部署 Vue 的服务器上)
  • Gitlab Runner 以 Docker 的方式运行

编写 CI 配置文件

Cache 和 Artifacts

很多人对与 Cache 和 Artifacts 这两个的作用不是很清楚,其实官方文档中也又一定的说明。 Cache 适用于在多个阶段中共享的依赖文件,例如 Vue 项目依赖的 NPM 包,也就是 node_modules 目录,而 Artifacts 则是在构建或测试中产生的数据,这类数据往往不想被覆盖,甚至需要上传至 Gitlab 服务器。

流水线中的阶段

因为 Vue SPA 的特性,所以并不依赖其他服务,我们只需要安装一些依赖,然后进行打包,最终部署到预览和线上环境即可。根据上述需求,我们将整个 Pipeline 设置为两个 Stage,效果如下:

1
2
3
stages:
- build # 安装依赖和构建项目
- deploy # 部署到预览和线上环境

每个阶段的任务

构建阶段的任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
build:
image: node:latest # 指定镜像
stage: build # 指定所属的阶段
tags:
- sonitus #指定需要在那个 Runner 上运行该任务
only: # 定义监听分支,当分支发生变化则触发 CI
refs:
- master
- develop
- tags
script: # 执行的脚本
- yarn install
- yarn build
artifacts: # 定义需要上传的文件或目录
name: "$CI_COMMIT_REF_SLUG"
when: on_success # 定义只有当任务成功时才上传
expire_in: 1 week # 定义文件过期时间,过期后将自动删除
paths: # 定义需要打包上传的文件或目录
- dist/

部署阶段的任务

因为我们有预览环境和线上环境,所以在部署阶段我们有两个任务,预览环境与 build stage 的触发条件一致,也就是 master、develop 和 tags 发生变化时都部署到预览服务器。而线上环境的部署则只监听 tags 的变化,并且需要开发人员或运维人员在 Gitlab 的项目页面手动触发部署任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
deploy:preview:
image: alpine:latest # 指定镜像
stage: deploy
tags:
- sonitus
when: on_success
script:
- apk add --no-cache rsync openssh # 安装 rsync 和 openssh
- mkdir -p ~/.ssh
- echo "$PREVIEW_SSH_PRIVATE_KEY" >> ~/.ssh/id_rsa # 将 Gitlab 里设置的的私钥环境变量输出到 ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- rsync -rav -e "ssh -p $PREVIEW_SERVER_PORT -o StrictHostKeyChecking=no" --delete dist/ "$PREVIEW_SERVER_USER"@"$PREVIEW_SERVER":"$PREVIEW_PROJECT_PATH" # 将构建的 dist 部署到服务器上
only:
refs:
- master
- develop
- tags
dependencies: # 定义依赖,当 build 任务完成后才能执行
- build
environment: # 定义环境
name: preview
url: https://vue.betterde.com # 定义访问的 URL

deploy:production:
image: alpine:latest
stage: deploy
tags:
- sonitus
script:
- apk add --no-cache rsync openssh
- mkdir -p ~/.ssh
- echo "$PRODUCTION_SSH_PRIVATE_KEY" >> ~/.ssh/id_dsa
- chmod 600 ~/.ssh/id_dsa
- rsync -rav -e "ssh -p $PRODUCTION_SERVER_PORT -o StrictHostKeyChecking=no" --delete dist/ "$PRODUCTION_SERVER_USER"@"$PRODUCTION_SERVER":"$PRODUCTION_PROJECT_PATH"
when: manual # 定义为手动触发
only:
refs:
- tags # 只有打了 tag 才会展示该 Job
dependencies:
- build
environment:
name: production
url: https://vue.betterde.com

这里需要注意的是,部署阶段中涉及很多环境变量(这些环境变量的名称可以自己定义),这些环境变量需要在 Gitlab 中进行设置。访问路径是:Project > Settings > CI/CD > Variables。

Project > Settings > CI/CD > Variables

还有就是需要注意项目是否有可用的 Runner, 同样的也是访问: Project > Settings > CI/CD > Runners,查看指定 tag 的 Runner 是否可用。

Project > Settings > CI/CD > Runners

完整的 CI 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
stages:
- build
- deploy

variables:
GIT_STRATEGY: fetch

cache:
paths:
- node_modules/

build:
image: node:latest
stage: build
tags:
- sonitus
only:
refs:
- master
- develop
- tags
script:
- yarn install
- yarn build
artifacts:
name: "$CI_COMMIT_REF_SLUG"
when: on_success
expire_in: 1 week
paths:
- dist/

deploy:preview:
image: alpine:latest
stage: deploy
tags:
- sonitus
when: on_success
script:
- apk add --no-cache rsync openssh
- mkdir -p ~/.ssh
- echo "$PREVIEW_SSH_PRIVATE_KEY" >> ~/.ssh/id_dsa
- chmod 600 ~/.ssh/id_dsa
- rsync -rav -e "ssh -p $PREVIEW_SERVER_PORT -o StrictHostKeyChecking=no" --delete dist/ "$PREVIEW_SERVER_USER"@"$PREVIEW_SERVER":"$PREVIEW_PROJECT_PATH"
only:
refs:
- master
- develop
- tags
dependencies:
- build
environment:
name: preview
url: https://vue.betterde.com

deploy:production:
image: alpine:latest
stage: deploy
tags:
- sonitus
script:
- apk add --no-cache rsync openssh
- mkdir -p ~/.ssh
- echo "$PRODUCTION_SSH_PRIVATE_KEY" >> ~/.ssh/id_dsa
- chmod 600 ~/.ssh/id_dsa
- rsync -rav -e "ssh -p $PRODUCTION_SERVER_PORT -o StrictHostKeyChecking=no" --delete dist/ "$PRODUCTION_SERVER_USER"@"$PRODUCTION_SERVER":"$PRODUCTION_PROJECT_PATH"
when: manual
only:
refs:
- tags
dependencies:
- build
environment:
name: production
url: https://vue.betterde.com

总结

接下来,我们就可以测试整个 CI 流程了,当我们 push、merge 或打 tag 发布 release 时将触发 CI,如上面的配置那样,如果你只是对 master 和 develop 分支做操作。那么在后台的 Pipelines 中看到两个 stages 和两个 jobs:

当 PUSH 到 master 分支时的 Pipelines 中的 Jobs

当我们为项目打了 v1.0.1 的 tag 后并发布了 release,则此时的 Pipeline 的 Jobs 如下:

打了 tag 后的 Jobs

可以看到 deploy:procuction 这个 Job 出现了,但是并没有触发,此时需要我们人工的点击后面的 Run 按钮来触发这个 Job,从而实现部署到生成环境中。在手动触发前可以点击这个 Job (不是后面的按钮)进入 Job 的详情页,设置临时环境变量,然后点击下方的 Trigger this manual action 来触发。

到这里整个关于 Gitlab CI 构建部署 Vue 的项目就算完成了。希望大家也能通过 Gitlab CI 来替代人工,从而腾出更多时间,去做更多有价值的事情。

评论