Gitlab 的 CI 还是比较有好的,只要配置好一些 Shared Runner,所有的项目都可以共享这些 Runner 来跑 CI 了,这样比较节省资源,这些 Runner 勤勤恳恳地跑完了一个就去跑下一个。
但是 CD 自动部署稍稍有些麻烦,Gitlab 这边能做到的就是跑完所有的测试之后发送一个 Curl 通知,告诉 Build 所有的测试通过了,可以开始部署了。.gitlab-ci.yml
文件类似下面:
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 |
image: reg.docker.com/laixintao/test:latest stages: - test - deploy unit_test: stage: test script: - pytest tags: - swarm style_check: stage: test script: - flake8 --show-source --statistics tags: - swarm deploy_staging: stage: deploy only: - master script: - curl -v your-domain.com:9999 |
这样 Runner 在所有的 test
stage 执行完了之后,就会执行 deploy
这个 stage。
最后 deploy 这个地方只写了一个 curl
,那么接收 Gitlab 的通知,然后执行部署这个步骤就有些麻烦了。可能需要一个 HTTP 服务监听端口,在网上找了一些方案,有用 PHP 写的脚本,也有用 Python 写的,但是这样就有了更多的依赖要维护了。
找了一圈,发现 netcat
这个小巧的工具就能实现监听端口->响应请求->执行脚本部署的需求。
下面的命令可以一直监听 9999 端口,有请求的话就响应 echo
的内容。然后结束命令。
1 |
echo -e "hello" | nc -l 0.0.0.0 9999 |
配合 &&
连接起来,就可以做到通过 Curl 触发部署操作了。
1 |
echo -e "HTTP/1.1 200 ok,glass\r\nConnection: close\r\n\r" | nc -l 0.0.0.0 9999 ; sh /home/admin/update.sh >> /home/admin/logs/webhook.log 2>&1 |
通过 systemd,可以将这个脚本管理起来,让它永远重启,这样一次部署之后,马上就可以重新监听,等待下一次部署命令。注意要添加 StartLimitInterval
,限制一下执行的频率。最终的 systemd service 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[Unit] Description=Autopull through webhook After=network.target [Service] User=admin Type=simple ExecStart=/bin/bash -xc 'echo -e "HTTP/1.1 200 ok,glass\r\nConnection: close\r\n\r" | nc -l 0.0.0.0 9999 ; sh /home/admin/deploy/update.sh >> /home/admin/logs/webhook.log 2>&1' Restart=always StartLimitInterval=1min StartLimitBurst=60 [Install] WantedBy=multi-user.target |
这样就可以实现每次向 master push 代码,自动测试成功并且马上推送到测试环境中。 update.sh
脚本的最后可以加一个 Curl 命令向钉钉或者 slack 发送提醒。