从 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 的最后一句即可。