从 GitHub 到 GitLab,打造私有项目 CI/CD 工作流
一直用 GitHub 托管所有代码,包括一些非开源的商业项目,同时也一直在寻找最佳的 CI/CD 工作流配置。作为个人开发者,主要的需求有两个:
- 不自建服务;
- 成本越低越好,最好免费。
GitHub 的不足
GitHub 首先对私有仓库收费,新政策 7 美元/月还算便宜,比以前按仓库数量收费好得多。最主要的问题还是没有很合适的 CI/CD 服务。Travis CI 只对公开项目免费,对私有项目收费且价格不菲;CircleCI 对私有项目免费,但配置比较难用,也不是很满意。
GitLab 的优势
在试用了 GitLab 后发现以上问题都可以解决:
- 无限制私有仓库
- 内置 CI/CD 服务,且配置简单易用,支持 Docker
- 内置私有的 Docker 仓库
- 免费
我已经重新梳理了项目的开发-测试-部署流程,并把所有个人非开源项目都转移到 GitLab,把 GitHub 账户重新降级为 Free。
工作流
我目前采用的工作流依托两个工具:
- Git:版本控制和管理
- Docker:部署和运行应用
我自己目前主要是个人开发,多人开发流程需要做一些调整。
- 在本地
dev
分支上开发和单元测试 - 测试通过后,
merge
到本地master
分支 - 对
master
分支打tag
,push
到 GitLab - GitLab 自动进行构建和测试
- 测试通过后自动
build image
,并将其push
到 GitLab 提供的免费 Docker 仓库 - 手动登录服务器,
pull image
,替换container
其中 4、5 两步在 GitLab 上自动完成,并且只对 tag 的推送进行操作。
实例
这是一个 TypeScript 的 Node.js 项目的实例。
.gitlab-ci.yml
1 | build: |
GitLab 的 CI 过程分为多个 job
,每个 job
彼此独立,可以实现复杂的 CI 过程,比如多环境并行测试。像这样一个简单的项目其实不需要分 job
,因为每个 job
都要新建环境,浪费时间。
GitLab 的文档非常简单易懂,这里只说几个值得注意的点:
- 在
build
中产生的文件(安装的依赖和编译文件),需要通过artifacts
传递给后续的jobs
,否则后续jobs
的环境中是没有这些文件的。 - 所有环境和数据库都在不同的 Docker
container
中,所以连接数据库不能用Host: localhost
,而要用Host: redis
、Host: mysql
这种。 $CI_REGISTRY
这种是 GitLab 的预设变量,可以直接使用。$CI_JOB_TOKEN
需要在设置页面先新建一个 Access Token。
GitLab 提供了 CI Lint 工具检查 .gitlab-ci.yml
文件的语法正确性。
Dockerfile
CI 的最后一步是 build
Docker Image,所以要提供 Dockerfile 文件。
1 | FROM node:8.0 |
值得注意下的是 ADD
命令,如果:
ADD
文件夹到目标位置,目标路径结尾没有/
:ADD node_modules /app/node_modules
ADD
多个文件到目标位置,目标路径结尾有/
:ADD app/*.js /app/app/
缺点
目前发现这个过程唯一的缺点是,阿里云从 GitLab pull image
的网络连接很差,经常容易失败,比较考验 RP。这是阿里云的老问题了,对 GitHub 和 npm 的连接都很差。
如果对这一点不能忍受,可以选择其他 Docker 仓库,只需修改 .gitlab-ci.yml
的最后一句即可。