在写完基于 Webhooks 的"第一篇《都9012年了,你还在手动部署代码吗》"以后,有同窗评论到"至少你得用个 docker 啊""一对一嘛...感受面试吹这个会被吊起来锤"....因而我决定出一篇基于 Docker 的自动部署文章 (:html
这是一篇利用 Docker 和 Gitlab-CI 的学习自动部署和实践的笔记,若是您是 Docker 资深玩家,跪求大佬不要吊锤;若是您是萌新,刚开始 Docker 学习之旅,那么但愿笔记中的理解和操做可以对您有所帮助.node
然鹅,饱和的需求和人的惰性让第二篇拖到了今天ORZ!!! 王者峡谷一时爽,一直王者一直爽git
偷懒是第一辈子产力,当你享受过自动化带给你的便捷时,不再会想回到手动打包部署上传的"石器时代".web
在本地开发完成 push 后,集成环境可以自动完成测试部署打包上传 FTP面试
工欲善其事必先利其器,开始行动前有必要理解一波 Docker 和 Gitlab-CI 自动部署原理;docker
这波要理解的东西有点多,不过不慌,咱们一个一个来 !shell
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口. 它将应用程序与该程序的依赖,打包在一个文件里面. 运行这个文件,就会生成一个虚拟容器. 程序在这个虚拟容器里运行,就好像在真实的物理机上运行同样. 有了 Docker,就不用担忧环境问题.
数据库
Docker 容器经常拿来和虚拟机 VM 相比较,提到 VM ,就不得不说....别提了,我还记得当年在大学的虚拟机课程,等虚拟机启动的时间里,老师能够寂寞地抽完几根烟...npm
有几个概念咱们须要理解一下:后端
咱们首先根据文档在集成服务器上安装 Docker => CentOS7上安装Docker
不建议各位同窗在window系统上尝试 Docker ,过程及其残忍
我在此次部署中经常使用的docker命令:
docker search NAME 搜索image镜像
docker pull NAME 拉取image镜像
docker run -d -p 2222:22 --name NAME <IMAGE> 后台运行IMAGE命名为NAME并映射容器端口22到宿主机端口2222(-d:后台运行 -p:端口映射)
docker ps 查看正在运行的docker容器
docker images 查看本地全部镜像
docker stop NAME 中止容器
docker rm 删除容器
docker exec -it <IMAGE> bash 以伪终端交互方式进入容器,运行bash
复制代码
本地仓库 -> (push提交代码) -> 远程仓库(Gitlab-CI) -> (通知注册完成的runner) -> 集成服务器(runner Executor执行命令)-> 打包上传FTP
经过简单的比较咱们能够发现,整个流程和使用 webhooks 并没有太大差异,可是区别于webhooks 使用 Token 请求具体服务, Gitlab-CI 会找出与这个工程相关联的Runner,并通知这些Runner, 而后这些Runner在宿主机上更新代码, 进行测试, 自动部署, 打包上传.
咱们能够把 Gitlab-CI 和 Runner 看作工厂和工人的关系, 工人在工厂里先注册, 工厂开工的时候通知工人干活 ~
理解完原理后咱们来配置(搞定)Gitlab-CI(Gitlab-8.0版本之后默认集成Gitlab-CI):
找到项目 Project 的 Settings 中的 CI/CD, 点击 Runners settings.这时你会发现两种 Runners:
这里咱们使用 Specific Runner, 记住 Specific Runner 配置里的 URL 和 token, 等下咱们就是利用这两个参数在集成服务器配置 Runner 和 Gitlab-CI 创建联系 !
这里 Gitlab-runner 的安装方式分两种:
咱们这里使用 Docker 安装 Gitlab-runner , 注意: 操做前修改 Docker 镜像源为国内源
ps: 注意一下 Gitlab 和 Gitlab-runner 的版本是否匹配, 不然 runner 可能连不上 Gitlab-CI
下载Gitlab-runner
docker search gitlab-runner
docker pull gitlab/gitlab-runner
运行Gitlab-runner,将容器gitlab-runner config.toml映射到主机,方便修改
docker run -d --name gitlab-runner --restart always
-v /data/docker/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner
进入Gitlab-runner bash
docker exec -it gitlab-runner bash
复制代码
gitlab-runner register
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
gitlab-ci URL
Please enter the gitlab-ci token for this runner:
gitlab-ci Token
Please enter the gitlab-ci description for this runner:
输入runner名字/描述便可
Please enter the gitlab-ci tags for this runner (comma separated):
输入runner的tag *后面编辑.gitlab-ci.yml须要用到这个tag
Whether to run untagged builds [true/false]:
[false]: 是否运行没有tag的构建
Whether to loack the Runner to current project [true/false]:
[true]: 是否锁定此Runner到正确的project
Registering runner... succeeded runner=******
Please enter the executor: docker, docker-ssh, shell, ssh, docker-ssh+machine, kubernetes, parallels, virtualbox, docker+machine:
选择执行器类型 这里咱们选docker
Please enter the default Docker iamge (e.g. ruby: 2.1):
选择执行Docker运行的image镜像 这里我打包了一个服务node环境镜像到本地使用 若是项目服务须要什么依赖,好比数据库之类的也能够打包到镜像中
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded !
此时Runner建立成功!
docker restart gitlab-runner
重启一下gitlab-runner
复制代码
此时咱们刷新 Gitlab-CI -> Settings -> CI/CD -> Runners settings 页面能够看到咱们刚刚注册的 Runner 已经出现了 !
ps: 具体 Runner 配置参数能够在 gitlab-runner 容器里 /etc/gitlab-runner 的 config.toml 文件查看和修改
Gitlab-CI 会在仓库发生 push 时通知 Runner 执行脚本动做,具体的脚本动做就须要咱们在项目目中新建 .gitlab-ci.yml 编写:
小贴士:
stages 能够拥有多个不重名的 job
咱们能够根据本身项目的实际状况编写属于本身的 job
script 定义由Runner执行的shell脚本或命令
before_script 覆盖在做业以前执行的脚本或命令
tags 定义job所适用的runner,tags为runner标签
cache 定义须要被缓存的文件、文件夹列表
具体更多配置推荐阅读官方文档
# 这是个人 .gitlab-ci.yml
stages:
- test
- deploy
- package
# 测试job
test:
stage: test
script:
- npm config set registry https://registry.npm.taobao.org
- npm i
- npm run test
cache:
# key: "$CI_BUILD_REF_NAME"
paths:
- node_modules
tags:
- ego
# 部署job
deploy-dev:
stage: deploy
before_script:
- echo "Start to deploy to dev host"
script:
- echo "deploy front ...."
- sh deploy-front.sh
- echo "deploy backend ...."
- sh ./app/deploy-backend.sh
only:
- /^release\/.*/
tags:
- dennis
- node
# 打包job
package:
stage: package
before_script:
- echo "Start to deploy to dev host"
only:
- /^release\/.*/
script:
- echo "start package..."
- sh package.sh $VERSION
when: manual
tags:
- dennis
- node
复制代码
Gitlab CI/CD 的 Pipelines 中每一次提交的 stages 就是根据 .gitlab-ci.yml 中的配置造成的, 你能够在Pipelines 中看到你每一次提交的 job 执行状况(成功/失败/等待/取消等状态), 由于网络状况的失败除了能够自动重试外, 咱们还能够手动点击重试.
这里的 deploy-front.sh deploy-backend.sh package.sh 先后端部署打包命令就不详细展现了,你们能够根据本身的项目实际状况编写.
ps: 这里要注意一下脚本命令在环境中的执行权限
最后,今天的文章到这里就差很少要结束了,其实当中每一个部分均可以深刻学习好久,我在文章中也是最粗浅的运用,总目标都是为搭建一整套流程,运行畅通服务,若是您对其中某个部分好比 Dokcer , .gitliab-ci.yml 感兴趣,能够自主深刻学习,我也在文章中给出了官网文档~
虽然Runner能够分布在不一样的主机上,同一个主机上也能够有多个Runner。难道咱们要在每一个部署服务器上都安装运行 Gitlab-runner 吗 ? 这里引用我第一篇文章中 @Axetroy老哥的评论:
恕我直言,服务端须要安装配套工具(服务)的,都是垃圾。
有 10 机器,就得给这 10 台机器安装工具(服务),例如这里是用 nodejs 写的 hook 接受服务 (固然能够解决,本身基于 centerOS 打包一个 Docker 镜像,内置 nodejs 和 hook 服务,而后这 10 台机器就以这个镜像开启。固然这并非全部的服务器商都支持自定义镜像)
能纯客户端部署的,才是好的。在 CI 构建成功的阶段,只要 CI 的环境变量服务器 IP,端口,用户名和密码,就能经过 SSH 部署。
好了, 又构建失败发邮件了,待我去看看什么问题 (:
最后的最后感谢强哥,在我学习使用 Docker 和 Gitlab-CI 的过程当中给予的巨大帮助 ! ! !