前言
从三月面试开始拉开巨幕,到五月份结束,终于拿到欢聚时代的offer。于是,在离职期间,我开始研究了服务端渲染,从技术选型,搭建框架到实现自动化部署,踩了不少的坑,终于完成了初步框架搭建和自动化部署这两步。
由于自动化部署是最后完成的,所以印象深刻。现在趁热打铁,先把自动化部署的研发的整个过程记录在案,以方便之后自己或者各位看客能够看到我踩过的坑!
本次自动化部署是基于gitlab+docker进行自动化部署的。下面请看我娓娓道来~
一、gitlab和.gitlab-ci.yml
众所周知,gitlab自动化部署非常方便,只要在对应服务器注册runner(或者在docker上注册runner也行),然后编写好对应的.gitlab-ci.yml文件,那么就可以实现脚本自动化部署了。下面我们来看看怎么进行gitlab的runner注册,以及如何编写.gitlab-ci.yml文件。
备注:本次使用的环境是阿里云服务器(Ubuntu18.0.4)
1.在宿主机上注册gitlab runner
- curl是linux请求服务器的命令,-L这个命令表示重定向,因为curl默认是不跟随请求的服务器重定向的。这样我们就可以下载gitlab-runner了:
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
- 接着执行安装命令:
apt-get install gitlab-runner
注意:如果这里安装不成功的话,可以执行:
sudo apt-get update
升级一下apt-get这个安装命令包。
- 此时,gitlab-runner已经安装完毕,接下来我们就要在宿主机上注册runner,我们可以执行如下命令:
gitlab-runner register
然后正如官方文档所说,会进入如下图1-1流程:(关于下面的url和token,可以参照图1-2,1-3找到对应的url和token位置,并把它复制填写到注册选项上)
- 输入url(见图1-2,1-3)
- 输入token(见图1-2,1-3)
- 输入描述
- 输入tag(可以随便输入)
- 输入runner executor,我这里输入了shell(其他选择项详见图1-4),shell就是直接在宿主机执行脚本了,当然也可以选择docker等
图1-1
图1-2
图1-3
图1-4
所有选项选择好后,稍等片刻,就会注册完毕!
我们看到这里的runner选项上,出现绿点,代表runner注册成功了!
这里有两个坑:
- 在注册完runner后,我们要关闭掉share runner,如下图所示(默认shared runner是开启的,我们必须要关闭掉)
- 同时,我们要编辑一下我们注册好的runner,expand一下runner选项(如下两个图),找到编辑按钮,并且把红框框住的选项给勾选上即可:
这样,我们gitlab-runner注册已经大功告成了!下面开始配置.gitlab-ci.yml文件
2.配置.gitlab-ci.yml文件
- .gitlab-ci.yml文件是用来编写gitlab部署自动化的脚本,通过它可以进行脚本自动化部署,一般是创建在项目的根目录下(如下图2-1所示):
图2-1
- 创建完.gitlab-ci.yml文件后,我们可以开始编辑该文件了,如下图2-2所示:
图2-2
那么图2-2的script下面的脚本究竟代表什么含义呢?不急,它其实是docker的一些命令,我们下面会继续细说,现在,我们已经准备好了.gitlab-ci.yml和runner文件了,接下来我们就要在宿主机上安装好docker,以便能够让项目在docker容器中运行。
二、Docker安装、Dockerfile和docker命令
再次提醒下,本次使用的宿主机环境是Ubuntu18.0.4版本的,所以我们直接去到docker官网,找到Ubuntu的docker下载安装教程即可(附:Ubuntu的docker下载安装官网教程:https://docs.docker.com/engine/install/ubuntu/#prerequisites)
1、Docker安装
- 官网解释的比较清楚(如下图3-1),首先,我们要先卸载掉旧版本的docker,命令如下所示:
图3-1
sudo apt-get remove docker docker-engine docker.io containerd runc
- 接着,我们update一下apt-get
sudo apt-get update
- 然后,我们设置一下,允许apt通过h:ttps获取docker安装包,复制下面的语句执行:
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
- 在系统上加上docker官方的GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
- 接着看下自己的系统cpu是属于什么类型的,docker给我们列出了三种类型,如下图3-2所示:
图3-2
如果不清楚什么类型,我们可以输入如下命令获取我们系统的内核类型:(我自己做个另外的记录,与本文无关:lsb_release -a,此命令可以查看当前Ubuntu的版本)
arch
即可看到当前内核版本是x86_64的,所以我们可以直接使用上图3-2的第一个tab的命令,去配置我们的稳定的仓库:(当然你可以配置官方给的测试的仓库,但是可能会不稳定,如下图3-3所示)
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
图3-3
- 接着我这边开始安装docker了,在这里我直接安装docker最新版本,执行如下命令:
sudo apt-get install docker-ce docker-ce-cli containerd.io
当然,也可以使用下面的命令去安装指定版本的docker:
# 查看当前的docker有什么版本
apt-cache madison docker-ce
# 其中<VERSION_STRING>填入版本号即可
sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
- 接着,等待片刻,就已经把docker安装完毕,我们可以执行如下命令,测试是否安装成功:
sudo docker run hello-world
如果执行上面这条命令后,打印出hello world,就代表docker安装成功了!
2、Dockerfile文件
- 和.gitlab-ci.yml文件一样,Dockerfile文件也是创建在项目的根目录下,如下图4-1所示:
图4-1
- 编写Dockerfile文件:
# 表示该docker环境基于node的11版本
FROM node:11
# 表示NODE_ENV的值为production
ENV NODE_ENV production
# 创建目录/usr/app并且进入到/usr/app
WORKDIR /usr/app
# 把项目的package.json和package-lock.json复制到docker容器的/usr/app中
COPY package*.json ./
# 切换npm为cnpm镜像
RUN npm install cnpm -g --registry=https://registry.npm.taobao.org
# 安装项目依赖包
RUN cnpm install
把整个项目copy到/usr/app
COPY . .
# 暴露容器的8080端口
EXPOSE 8080
# 执行命令 node xxx,开启node服务
CMD ["node", "/usr/app/src/server/server.js"]
注意:这里RUN 和CMD命令,前者表示docker build(构建镜像)时执行,后者是docker run(运行镜像生成容器)时执行。
- 回到刚才的.gitlab-ci.yml文件中,我们可以看到如下图4-2所示,这一段脚本就是通过docker构建镜像并且运行容器实例的过程:
docker build命令是根据Dockerfile构建镜像ssr:${TAG},而docker run命令是根据镜像ssr:${TAG}生成容器实例并运行
注意:如果运行的时候提交代码,运行ci/cd的时候,出现如下问题:(是个坑)
我们可以直接在宿主机中执行如下命令,去释放该文件权限:
sudo chmod a+rw /var/run/docker.sock
然后重新执行提交代码,让他自动化部署即可。
三、总结 and Todo
那么,这次自动化部署是否已经完成呢?但是我先记录一部分的实战以及踩过的坑,以方便之后和大家不要继续踩坑了。接下来我还要继续完成并且更新这篇博客的事情是:
- 如果突然宕机,怎么使得docker权限可以通过呢?(重启宿主机的时候,怎样才能不执行sudo chmod a+rw /var/run/docker.sock这个语句,也能让docker + gitlab-ci跑起来)
- 多次部署docker会出现端口被占用的情况从而部署失败,怎么解决?(这个就要通过命名docker容器的name来解决了,不过到时会把详细方案说出)
- 通过docker log来查看docker容器部署的日志的讲解
- react + ssr的思路和代码实现
好了,暂时先记录在这里,如果各位看官大神经过看到此篇文章有什么改善之处,或者有什么疑虑,不妨可以在评论区留下你们的精贵之言,技术无国界,希望我们能够通过这种方式的交流,积累技术沉淀,提升自己的能力!!!