使用私有CI构建GitHub仓库

本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 2018年05月25日 统计字数: 5785字 阅读时间: 12分钟阅读 本文链接: https://soulteary.com/2018/05/25/building-a-github-repository-with-private-ci.html


使用私有CI构建GitHub仓库

最近使用 Drone 改造了网站的构建发布流程,感觉比较轻量,用起来还不错,记录下来留给后面感兴趣的同学参考。

起因

五月初进行网站简化的过程中,因为使用了自定义的代码高亮服务,和文档转换服务,对于构建机器的配置要求升高到了 1C2G,对PHP Fpm脚本进行高并发调用的时候,资源消耗太大了,即使设定了并发数限制,还是偶尔会出现500状态。

于是把构建机器从 1C1G升配到了 2C2G,这样倒是解决了问题,但是构建服务使用频率不是很高,加上海外机器线路进行国内机器部署的时候,偶尔使用也会遇到构建十几秒,部署十分钟

最开始构建服务是跑在家里服务器的,博客文章源码也是在服务器上的,更新、构建统一使用 GitLab+GitLabRunner ,倒也还算稳定,只是:

  1. 更新必须使用私有云的私有仓库。
  2. 构建环境需要整体打包成一个容器,不然分阶段执行,要贮存 artifacts。(家里没有上k8s)

因为生成工具我都容器固化了,所以不想贮存 artifacts ,即使能设置 expires,过期自动删除,但是也太不环保了。

另外,我希望文档是可以保存在GitHub上,而非私有仓库中的,同时也不想把文档推送多个 GitOrigin或者做mirror什么的,维护起来太麻烦了。

这一套架构使用体验贼差,于是考虑进行一番改进。

历史

说起 Drone,去年年底机器资源严重不足的时候,就考虑过找一个轻量的CI工具,暂时替换一下GitLab CI,等资源充沛之后,再替换回来。

当时看了一圈,感觉drone还不错,能够直观看到的不足只有:文档中有大量未解之谜、docker镜像缺乏明确的tags、最新版本未同步docker hub。

但是相比 GitLab+GitLabRunner 的组合拳,资源占用小,还能灵活的接入各种仓库,也是基于容器化分阶段进行执行操作,还是很有竞争力的。

当时临时使用过一阵 gogs+drone,在一台1C1G的机器上跑着就很欢腾,但是遇到几个小问题:

  • 对于个别仓库支持mirror,但是对于mirror不支持自动触发CI构建,要维护一个脚本定时检查并触发,仓库源也需要维护至少两份(源+Mirror)。
  • 出于洁癖gogs使用22作为Git Server Port,服务器经常收到爬虫探测,不胜其烦,故还是不考虑把仓库暴露在公网了,并且GitHub免费仓库+私有云仓库已经很好了,不想多维护一个仓库服务。

思来想去,在海外购置了一台1C2G的机器,临时的解决了这个问题,然后就遇到了文章开头的情况。

架构简化

GitHub 不可用时其实很少,所以可以考虑把本来就是要公开的内容直接托管GitHub,然后使用CI与其直接对接,省去部分维护仓库的成本。

这里没有使用GitLab、以及GitLab Runner直接与其对接,毕竟有的半成品还是不想公开,而且我对这个大块头的安全性很不放心,成天到晚组件有安全漏洞...

那么公网搭建一个drone便是一个不错的选择,小巧轻量,自带GitHub OAuth插件,还能直接签注SSL证书。

但是考虑到构建机器对资源配置有一定的要求,并且部署对于国内线路有一定的要求,于是考虑在内网启动一个Drone服务,对外暴露到公网机器上即可:外网机器只是充当一个反向代理,充分利用家里高配置机器资源和大带宽。

简单的架构图如下:

 
  1. [外网机器]<->[内网机器]
  2. [内网机器|
  3. [构建服务]->[发布国内云服务器]
  4. ]

数据透传,我选择了国人开源产品frp取代了ngrok。

数据透传

关于frp的配置其实很简单:

服务端配置, frps.ini

 
  1. [common]
  2. # 如果你计划多添加一层nginx,这个端口需要修改掉,避免冲突
  3. # 我这边懒得加一层nginx,直接使用frp暴露远程端口
  4. vhost_http_port = 80
  5. vhost_https_port = 443
  6.  
  7. # 客户端和服务端沟通端口
  8. bind_port = 7000
  9.  
  10. token = 需要和客户端设置一致
  11.  
  12. # 管理面板相关配置,如果不进行设置,默认使用 admin
  13.  
  14. # 对外服务使用0.0.0.0,不然可以使用127.0.0.1,配合代理进行访问
  15. dashboard_addr = 0.0.0.0
  16. dashboard_port = 你的端口
  17. dashboard_user = 你的账号
  18. dashboard_pwd = 你的密码

需要注意的是,你计划暴露的端口,记得在防火墙里打开:

 
  1. ufw allow 你的端口号

下面是客户端配置,frpc.ini

 
  1. [common]
  2. server_addr = 你的服务器IP或者私有域名
  3. # 客户端和服务端沟通端口
  4. server_port = 7000
  5.  
  6. token = 需要和客户端设置一致
  7. dns_server = 你的DNS服务,不设置默认使用8.8.8.8
  8.  
  9. [web01]
  10. type = http
  11. local_ip = 0.0.0.0
  12. local_port = 17071
  13. custom_domains = 公网要暴露的域名
  14.  
  15. [web02]
  16. type = https
  17. local_ip = 0.0.0.0
  18. local_port = 17072
  19. use_encryption = false
  20. use_compression = false
  21. custom_domains = 公网要暴露的域名

这里有两点要注意的:

  1. 你的内网服务,往往会指定一些私有DNS解析,需要配置common节中的 dns_server为你内网的DNS服务器地址,比如网关路由,或者DNS服务器地址,避免在内网解析内部服务的时候使用的是公网服务,找不到域名,无法提供服务。
  2. 你的公网暴露域名可以是任意域名,只要外网DNS能够指向到你的 server_addr即可。

CI服务

drone配置起来很简单,就像下面的配置:

 
  1. version: '2'
  2.  
  3. services:
  4. drone-server:
  5. restart: always
  6. image: drone/drone:0.8.5
  7. # 根据自己情况进行端口映射,但是要配套修改上面数据透传里的客户端端口
  8. ports:
  9. - 17071:80
  10. - 17072:443
  11. volumes:
  12. # 这里如果是OSX系统,需要mkdir或者把映射目录进行修改
  13. - /var/lib/drone:/var/lib/drone/
  14. restart: always
  15. environment:
  16. # 这个变量务必设置,否则软件将会以调试模式执行
  17. - GIN_MODE=release
  18. - DRONE_OPEN=false
  19. - DRONE_SECRET=和drone-agent设置一致即可
  20. - DRONE_ADMIN=soulteary
  21. - DRONE_HOST=https://你的域名
  22. - DRONE_GITHUB=true
  23. - DRONE_GITHUB_URL=https://github.com
  24. - DRONE_GITHUB_CLIENT=到GitHub获取
  25. - DRONE_GITHUB_SECRET=到GitHub获取
  26. - DRONE_GITHUB_SCOPE=repo,repo:status,user:email,read:org
  27. # 是否自动注册SSL证书
  28. - DRONE_LETS_ENCRYPT=true
  29.  
  30. drone-agent:
  31. restart: always
  32. image: drone/agent:0.8.5
  33. command: agent
  34. restart: always
  35. depends_on:
  36. - drone-server
  37. volumes:
  38. - /var/run/docker.sock:/var/run/docker.sock
  39. environment:
  40. - GIN_MODE=release
  41. - DRONE_SERVER=drone-server:9000
  42. - DRONE_SECRET=和drone-server设置一致即可

网上很多教程使用的通讯端口都进行了暴露,这里其实大可不必,docker-compose编排的软件直接默认可访问。 另外,根据日志反馈,需要额外定义 GIN_MODE,避免软件执行在调试状态下。

定义CI过程

在你的GitHub仓库中添加一个drone.yml,内容可以参考如下:

 
  1. pipeline:
  2.  
  3. 同步数据:
  4. image: appleboy/drone-scp
  5. secrets:
  6. - source: deploy_key
  7. target: ssh_key
  8. - source: deploy_host
  9. target: ssh_host
  10. - source: deploy_port
  11. target: ssh_port
  12. - source: deploy_user
  13. target: ssh_username
  14. target: ~/Code/www.soulteary.com/My-Blog-Posts/
  15. source: ./*
  16.  
  17.  
  18. 转换文档:
  19. image: appleboy/drone-ssh
  20. secrets:
  21. - source: deploy_key
  22. target: ssh_key
  23. - source: deploy_host
  24. target: ssh_host
  25. - source: deploy_port
  26. target: ssh_port
  27. - source: deploy_user
  28. target: ssh_username
  29. - source: excute_timeout
  30. target: ssh_command_timeout
  31. script:
  32. - cd ~/Code/www.soulteary.com/blog/
  33. - ./1.convert.sh
  34.  
  35.  
  36. 开始构建:
  37. image: appleboy/drone-ssh
  38. secrets:
  39. - source: deploy_key
  40. target: ssh_key
  41. - source: deploy_host
  42. target: ssh_host
  43. - source: deploy_port
  44. target: ssh_port
  45. - source: deploy_user
  46. target: ssh_username
  47. - source: excute_timeout
  48. target: ssh_command_timeout
  49. script:
  50. - cd ~/Code/www.soulteary.com/blog/
  51. - ./3.update.sh
  52.  
  53.  
  54. 压缩页面:
  55. image: appleboy/drone-ssh
  56. secrets:
  57. - source: deploy_key
  58. target: ssh_key
  59. - source: deploy_host
  60. target: ssh_host
  61. - source: deploy_port
  62. target: ssh_port
  63. - source: deploy_user
  64. target: ssh_username
  65. - source: excute_timeout
  66. target: ssh_command_timeout
  67. script:
  68. - cd ~/Code/www.soulteary.com/blog/
  69. - ./4.minify.sh
  70.  
  71.  
  72. 产物打包:
  73. image: appleboy/drone-ssh
  74. secrets:
  75. - source: deploy_key
  76. target: ssh_key
  77. - source: deploy_host
  78. target: ssh_host
  79. - source: deploy_port
  80. target: ssh_port
  81. - source: deploy_user
  82. target: ssh_username
  83. - source: excute_timeout
  84. target: ssh_command_timeout
  85. script:
  86. - cd ~/Code/www.soulteary.com/blog/
  87. - ./5.package.sh
  88.  
  89.  
  90. 尝试发布:
  91. image: appleboy/drone-ssh
  92. secrets:
  93. - source: deploy_key
  94. target: ssh_key
  95. - source: deploy_host
  96. target: ssh_host
  97. - source: deploy_port
  98. target: ssh_port
  99. - source: deploy_user
  100. target: ssh_username
  101. - source: excute_timeout
  102. target: ssh_command_timeout
  103. script:
  104. - cd ~/Code/www.soulteary.com/blog/
  105. - ./6.deploy.sh
  106. - ./7.notice.sh

这里是有drone-scp和drone-ssh两个插件,通过drone依次在远程服务器上进行了一些脚本的执行。 如果你的构建服务简单,还可以直接写在scripts中,直接在docker容器中执行CI过程。

这里有几点需要注意:

  1. 插件没有使用docker tag进行固化,尽量自行保存容器镜像。
  2. 定义 deploy_*变量的时候, ssh_host如果是内网服务,记得进行内网解析。
  3. excute_timeout单位是秒。
  4. 在OSX环境执行的话,会丢失PATH变量,需要在执行脚本中重新声明变量:
 
  1. sysOS=`uname -s`
  2. if [ $sysOS == "Darwin" ];then
  3. PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
  4. fi

启动服务

先在服务器启动frp的服务端:

 
  1. frps -c frps.ini

你可以使用进程守护软件保障进行健康,这里不做展开,网上文章参考讲了太多。

接着在内网服务器启动frp的客户端:

 
  1. frpc -c frpc.ini

和服务端一样,可以使用进程守护来进行可用性保障。

然后启动你的drone服务:

 
  1. docker-compose -f docker-compose.yml up -d

然后访问你的域名,即可看到drone暴露在公网上,并且通过OAuth和GitHub产生了“联动”效果。

接下来向你的GitHub进行一次提交、合并操作,你会发现CI已经在进行自动的构建处理了。

---EOF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值