前言

古代软件工程都强调继续集成的能力,而继续集成的一个重要组成部分继续部署。也就是本文的重点,自动化部署。本文会从零开始讲述每个环节的原理和实现办法。

jenkins+docker装置

装置docker

只须要一句运行命令即可装置:

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

输出命令后回车期待一会看到上面的信息就是装置实现了:

root@iZwz92akl2vtt9nu4w6lq7Z:~# curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun# Executing docker install script, commit: 3d8fe77c2c46c5b7571f94b42793905e5b3e42e4+ sh -c 'apt-get update -qq >/dev/null'+ sh -c 'DEBIAN_FRONTEND=noninteractive apt-get install -y -qq apt-transport-https ca-certificates curl >/dev/null'+ sh -c 'curl -fsSL "https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg" | apt-key add -qq - >/dev/null'Warning: apt-key output should not be parsed (stdout is not a terminal)+ sh -c 'echo "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu focal stable" > /etc/apt/sources.list.d/docker.list'+ sh -c 'apt-get update -qq >/dev/null'+ '[' -n '' ']'+ sh -c 'apt-get install -y -qq --no-install-recommends docker-ce >/dev/null'+ sh -c 'docker version'Client: Docker Engine - Community Version:           20.10.3 API version:       1.41 Go version:        go1.13.15 Git commit:        48d30b5 Built:             Fri Jan 29 14:33:21 2021 OS/Arch:           linux/amd64 Context:           default Experimental:      trueServer: Docker Engine - Community Engine:  Version:          20.10.3  API version:      1.41 (minimum version 1.12)  Go version:       go1.13.15  Git commit:       46229ca  Built:            Fri Jan 29 14:31:32 2021  OS/Arch:          linux/amd64  Experimental:     false containerd:  Version:          1.4.3  GitCommit:        269548fa27e0089a8b8278fc4fc781d7f65a939b runc:  Version:          1.0.0-rc92  GitCommit:        ff819c7e9184c13b7c2607fe6c30ae19403a7aff docker-init:  Version:          0.19.0  GitCommit:        de40ad0If you would like to use Docker as a non-root user, you should now consideradding your user to the "docker" group with something like:  sudo usermod -aG docker your-userRemember that you will have to log out and back in for this to take effect!WARNING: Adding a user to the "docker" group will grant the ability to run         containers which can be used to obtain root privileges on the         docker host.         Refer to https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface         for more information.

执行一下查看版本的命令再次确认装置胜利:

root@iZwz92akl2vtt9nu4w6lq7Z:~# docker versionClient: Docker Engine - Community Version:           20.10.3 API version:       1.41 Go version:        go1.13.15 Git commit:        48d30b5 Built:             Fri Jan 29 14:33:21 2021 OS/Arch:           linux/amd64 Context:           default Experimental:      trueServer: Docker Engine - Community Engine:  Version:          20.10.3  API version:      1.41 (minimum version 1.12)  Go version:       go1.13.15  Git commit:       46229ca  Built:            Fri Jan 29 14:31:32 2021  OS/Arch:          linux/amd64  Experimental:     false containerd:  Version:          1.4.3  GitCommit:        269548fa27e0089a8b8278fc4fc781d7f65a939b runc:  Version:          1.0.0-rc92  GitCommit:        ff819c7e9184c13b7c2607fe6c30ae19403a7aff docker-init:  Version:          0.19.0  GitCommit:        de40ad0

本文应用的服务器零碎是Ubuntu 20.04 64位,其它零碎装置过程相似。

在docker上装置jenkins

执行以下命令:

docker run \  -u root \  --rm \  -d \  -p 8080:8080 \  -p 50000:50000 \  -v jenkins-data:/var/jenkins_home \  -v /var/run/docker.sock:/var/run/docker.sock \  jenkinsci/blueocean

期待下载安装,看到上面的信息阐明装置实现了:

root@iZwz92akl2vtt9nu4w6lq7Z:~# docker run \>   -u root \>   --rm \>   -d \>   -p 8080:8080 \>   -p 50000:50000 \>   -v jenkins-data:/var/jenkins_home \>   -v /var/run/docker.sock:/var/run/docker.sock \>   jenkinsci/blueoceanUnable to find image 'jenkinsci/blueocean:latest' locallylatest: Pulling from jenkinsci/blueocean801bfaa63ef2: Pull complete 755713f1a3c1: Pull complete eb3cc996a4d2: Pull complete 53fff950d571: Pull complete f6936a1aec5a: Pull complete 257a3874e67f: Pull complete a1322c53804d: Pull complete 6f3525ef00e6: Pull complete d105e9324027: Pull complete 3bd288623327: Pull complete 0c464039fb0b: Pull complete 25248a2f7ff6: Pull complete 80aea1f6597d: Pull complete 9507a0ecbe89: Pull complete 90cd370947fb: Pull complete 6dc19b8b34e0: Pull complete Digest: sha256:27955db4139f933fa831638f99608b0ceb504e88ce82bcbbc80e41bfcfdcca45Status: Downloaded newer image for jenkinsci/blueocean:latest1f2b65eac96879b8ab1717edc25ccf508bd2dac2702ac3e924ce74667227a190

更多装置细节请参考:jenkins装置

同样咱们运行docker ps -a确认是否正确装置并启动了jenkins

root@iZwz92akl2vtt9nu4w6lq7Z:~#  docker ps -aCONTAINER ID   IMAGE                 COMMAND                  CREATED       STATUS       PORTS                                              NAMES1f2b65eac968   jenkinsci/blueocean   "/sbin/tini -- /usr/…"   2 hours ago   Up 2 hours   0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp   fervent_brown

看到以上信息阐明jenkins已装置并启动了,这时候咱们用浏览器关上:服务器地址:8080,能够看到以下页面:

须要输出的管理员明码在jenkins打印的日志中,咱们回到服务器终端,执行以下命令:

docker logs 1f2b65eac968

其中1f2b65eac968jenkins容器的CONTAINER ID,在后面咱们执行docker ps -a命令的时候能够查看到。
执行命令后在终端中找到这串字符串:

***************************************************************************************************************************************************************************************Jenkins initial setup is required. An admin user has been created and a password generated.Please use the following password to proceed to installation:f12938a211dc4402a7e679a71e1962e3This may also be found at: /var/jenkins_home/secrets/initialAdminPassword***************************************************************************************************************************************************************************************

复制中的随机字符串,回到浏览器,将字符串输出管理员明码的文本框中,而后点击持续按钮。通过一段时间的期待进入了如下页面,点击装置举荐的插件

接下来将进入插件装置的期待过程,装置实现后进入创立管理员的页面,填入相干信息创立管理员。

接下来进入实例配置页面,咱们不做批改,点击保留并实现

到这里咱们就胜利装置了jenkins+docker的环境。

装置jenkins插件

阿里云OSS上传插件

插件:Aliyun OSS Uploader
作用:用于上传前端动态文件到阿里云的OSS上。

创立pipeline

jenkinspipeline也就是多分支流水线pipeline将实现咱们一系列的自动化测试公布等工作。
点击页面左侧的关上 Blue Ocean

点击创立新的流水线

抉择一个代码仓库类型,而后填入你的前端代码仓库地址,填入代码仓库的用户名和明码,点击创立流水线

创立前端代码测试、构建、上传cdn工作节点

进入pipeline编辑页面,点击+创立一个节点,命名为fe
点击设置将节点运行环境设置为:dockernode:14.8.0-alpine3.12node的版本号依据我的项目调整,最正当状态下,开发环境测试环境构建环境生产环境node版本应该全副统一。

上面咱们开始增加步骤,开展步骤列表,点击增加步骤
留神:示例的前端我的项目基于vue cli,如果你间接应用webpack,相干的命令会有差别。

步骤1:装置依赖

步骤目标:装置前端的依赖,用于后续测试、构建等步骤。
步骤类型:Shell Script
内容:

npm install
步骤2:单元测试

步骤目标:运行单元测试,如果过程报错则整个工作会中断。
步骤类型:Shell Script
内容:

npm run test

留神:这里只是进行单元测试,理论状况可能还须要进行端到端等测试,只须要减少一个步骤即可。

步骤3:构建前端代码

步骤目标:如果测试通过,则进行前端代码的打包构建。
步骤类型:Shell Script
内容:

npm run build
步骤4:将index.html暂存起来

步骤目标:将构建实现后的前端入口html文件暂存起来,后续步骤须要应用。
步骤类型:Stash some files to be used later in the build
内容:

以上内容依据你我的项目的状况做目录和名称上的批改,如果是多page我的项目则需反复这个步骤屡次,将多个入口html文件暂存起来。

步骤5:前端代码上传至阿里云的OSS

步骤目标:将构建实现的前端代码上传至阿里云的OSS(相当于cdn)。
步骤类型:阿里云OSS上传
内容:

创立服务端代码测试、构建、生成docker镜像节点

本文的服务端是nodejs语言,应用eggjs框架。如果应用php或者java作为后端语言,相干设置会有差别。
fe节点前面点击+创立一个节点,命名为service
上面咱们开始增加步骤,开展步骤列表,点击增加步骤

步骤1:在GIT上拉取服务端代码

步骤目标:拉取git上服务端代码。
步骤类型:Git
内容:

其中凭证id须要到jenkins凭证治理中增加,如下图,填如git的用户名和明码,而后自定义一个凭证id

步骤2:将前端的入口html放在服务端代码指定目录

fe节点的步骤4中,咱们将前端的index.html暂存起来,当初咱们先进入服务端代码的特定目录(你想搁置这个文件的目录),而后取出这个index.html搁置在这个目录下。这样你的服务端代码在用户拜访的时候返回这个index.html文件的内容即可。
步骤目标:进入服务端代码的指定目录
步骤类型:Change current directory
内容:

进入了服务端代码的app目录,并且通过子步骤将咱们暂存的index.html搁置在这个目录中。不同的服务端目录构造会有差别,请依据服务端我的项目构造来抉择搁置地位。

子步骤

在步骤2中增加一个子步骤
步骤目标:将暂存的index.html搁置在当前目录
步骤类型:Restore files previously stashed
内容:

步骤3:登录阿里云的容器镜像服务

阿里云的容器镜像服务用于存储docker的镜像,你也能够用docker本人创立一个镜像仓库。这里就不对此展开讨论。
步骤目标:后续步骤须要传输镜像到阿里云的容器镜像服务上,所以先登录。
步骤类型:Shell Script
内容:docker login -u [阿里云账号] -p [阿里云明码] [镜像仓库地址]
具体参数能够请查阅阿里云的相干文档。

步骤4:将服务端代码构建成镜像

步骤类型:Shell Script
内容:docker build -t [镜像仓库地址]:$BUILD_NUMBER
此步骤须要先配置Dockerfile文件,该步骤不在这里开展,你能够自行搜寻相干材料。

步骤5:将镜像提交到阿里云的容器镜像服务上

步骤类型:Shell Script
内容:docker push [镜像仓库地址]:$BUILD_NUMBER

步骤6:将镜像运行到指标服务器上

步骤类型:Shell Script
内容:

ssh -o StrictHostKeyChecking=no root@[指标服务器ip]docker rm -f [容器自定义名称] || truedocker run -d --name=[容器自定义名称] --network host [镜像仓库地址]:$BUILD_NUMBER

留神:

  1. 通常状况下会有多个服务器须要部署,这里作为示例只部署一台;
  2. docker rm是先移除服务器上旧的运行的容器;
  3. ssh免密登录须要在两台服务器上配置密匙,这方面的材料能够自行搜寻;

其它细节

革除旧的镜像

在服务器上运行近程镜像的时候每次都会存储旧的镜像在服务器中,所以有必要每次运行新镜像前清理一下旧的镜像,能够应用上面的命令来清理掉相干的镜像:

docker rmi -f  `docker images | grep '[镜像的关键字]' | awk '{print $3}'` || true