容器化自动打包部署思路
简介
公司当前的文章都是发布在gitbook上,gitbook是一个基于nodejs的项目,之前是直接跑在服务器上,现在已经把它迁到了docker容器内,并实现持续集成持续发布。
流程框架
大致流程是这样的

在本地写完文章,git push到gitlab代码库之后,gitlab-runner会自动从gitlab上拉下来代码,打包封装成docker镜像,然后推送到镜像仓库。ECS实例从镜像仓库拉下来这个镜像,跑起来三个容器,由nginx提供负载均衡,然后在浏览器中输入地址就可以看到了。
这里图中写的是用了三台服务器做负载均衡,实际上内部为了部署个文档站也不至于用三台机器,所以这里就在一台机器上起了三个docker容器,原理类似。
开始准备
- 注册一个gitlab的账户
这就不多说了
- 注册gitlab-runner
找一台机器注册gitlab-runner,我这里注册时执行类型选择了shell
,这里选的是shell。
- 找一个镜像仓库
这里用自建的harbor镜像仓库
嗯,模块都准备好了,剩下的就需要把他们拼接起来了
配置文件
先在本地写好.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 27 28 29 30 31 32 33 34 35
| stages: - docker_build - deploy docker_build_job: stage: docker_build script: - docker login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD harbor.socmap.org # 登录镜像仓库,这里的两个隐藏环境变量需要在“gitlab——yourproject——settings——CICD——Variables”中设置 - docker build -t harbor.socmap.org/gitbook/gitbook:$CI_PIPELINE_ID . # $CI_PIPELINE_ID是gitlab预置环境变量 - docker push harbor.socmap.org/gitbook/gitbook:$CI_PIPELINE_ID # 把刚才构建的镜像推送的镜像仓库 tags: - gitbook only: - master deploy_job: stage: deploy script: - docker login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD harbor.socmap.org - if [ $(docker ps -aq --filter name=gitbook-4050) ]; then docker rm -f gitbook-4050;fi - docker run -d -p 4050:4000 --name gitbook-4050 harbor.socmap.org/gitbook/gitbook:$CI_PIPELINE_ID && sleep 5 - if [ $(docker ps -aq --filter name=gitbook-4051) ]; then docker rm -f gitbook-4051;fi - docker run -d -p 4051:4000 --name gitbook-4051 harbor.socmap.org/gitbook/gitbook:$CI_PIPELINE_ID && sleep 5 - if [ $(docker ps -aq --filter name=gitbook-4052) ]; then docker rm -f gitbook-4052;fi - docker run -d -p 4052:4000 --name gitbook-4052 harbor.socmap.org/gitbook/gitbook:$CI_PIPELINE_ID # 为什么这么操作?其实是为了服务不中断,网上文章的做法都是删掉这个容器,然后再起一个, # 假如这两条命令执行间隔了0.1秒,那么就会有0.1秒的服务中断, # 这个中断虽然影响很小,但是本着做就要给做完美了,为了不服务中断,这里让滚动更新。 # 2019年6月28日更新:之前的写法有个小bug,还是会出现服务中断的问题,可能是因为第一个新容器还没完全启动起来提供服务,剩下两个旧的容器都已经被删除了,所以这里新加sleep 5等待一下 tags: - gitbook only: - master
|
Dockerfile
文件如下
1 2 3 4 5 6 7 8
| FROM node:11 MAINTAINER sunshiwei@socmap.net RUN npm install -g gitbook-cli && gitbook init blog WORKDIR /blog ADD ./ /blog/ RUN gitbook install ./ && gitbook build EXPOSE 4000 CMD ["gitbook","serve"]
|
为什么构建的会更快一些?因为第一次构建之后,接下来的每次构建都会用到之前的层缓存,只在有代码变动的层才会重新构建。
上面可以看出来,起了三个容器来提供服务,下面用nginx来实现负载均衡
在HTTP字段下加上:
1 2 3 4 5 6
| upstream gitbook_server { server 127.0.0.1:4050; server 127.0.0.1:4051; server 127.0.0.1:4052; } # 这里直接用默认的轮询就可以
|
在server下进行如下配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| server { listen 80; server_name book.socmap.org;
index index.html index.htm;
location / { proxy_pass http://gitbook_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 600; proxy_read_timeout 600; proxy_send_timeout 600; } }
|
部署成功后,可以看到三个正在提供服务的容器
1 2 3 4 5
| $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b7cca4b7ce58 harbor.socmap.org/gitbook/gitbook:438 "gitbook serve" 3 hours ago Up 3 hours 0.0.0.0:4052->4000/tcp gitbook-4052 e2b170866e31 harbor.socmap.org/gitbook/gitbook:438 "gitbook serve" 3 hours ago Up 3 hours 0.0.0.0:4051->4000/tcp gitbook-4051 2e9d54b6536b harbor.socmap.org/gitbook/gitbook:438 "gitbook serve" 3 hours ago Up 3 hours 0.0.0.0:4050->4000/tcp gitbook-4050
|
现在访问book.socmap.org,nginx会把流量随机分发给后端三个docker容器之一。