乐趣区

关于node.js:jenkinsdocker-实现前端和nodejs服务端自动化发布

前言

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

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:      true

Server: 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
If you would like to use Docker as a non-root user, you should now consider
adding your user to the "docker" group with something like:

  sudo usermod -aG docker your-user

Remember 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 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:      true

Server: 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/blueocean
Unable to find image 'jenkinsci/blueocean:latest' locally
latest: Pulling from jenkinsci/blueocean
801bfaa63ef2: 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:27955db4139f933fa831638f99608b0ceb504e88ce82bcbbc80e41bfcfdcca45
Status: Downloaded newer image for jenkinsci/blueocean:latest
1f2b65eac96879b8ab1717edc25ccf508bd2dac2702ac3e924ce74667227a190

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

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

root@iZwz92akl2vtt9nu4w6lq7Z:~#  docker ps -a
CONTAINER ID   IMAGE                 COMMAND                  CREATED       STATUS       PORTS                                              NAMES
1f2b65eac968   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:

f12938a211dc4402a7e679a71e1962e3

This 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 [容器自定义名称] || true
docker run -d --name=[容器自定义名称] --network host [镜像仓库地址]:$BUILD_NUMBER

留神:

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

其它细节

革除旧的镜像

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

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