Docker+Jenkins+GitHub

image-20220511175224561

本文教程基于Windows 10 系统Docker+Jenkins+GitHub 实现 CI&CD。

在 Docker 中运行 Jenkins

将 Jenkins 作为 Docker 容器并从 jenkinsci/blueocean Docker 镜像中运行。

使用 Docker Engine 运行 Jenkins

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 进入cmd终端
# 查看当前wsl版本
wsl -l -v
# 进入wsl
wsl
# 使用下面的 docker run 命令运行 jenkinsci/blueocean 镜像作为Docker中的一个容器(记住,如果本地没有镜像,这个命令会自动下载)
docker run \
--name huatree-jenkins \
--rm \
--restart \
-u root \
-p 8080:8080 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /home/huatree/document:/home \
jenkinsci/blueocean
# 如果需要退出当前容器的运行状态,输入快捷键ctrl + c

说明:

wsl:windows10 子系统 Linux,这里用的是微软商店中下载的 Debian,升级到 wsl2

\:linux 环境空格输出

--name:为容器分配名称

--rm:容器退出时自动移除,可以不写,后面用docker rm移除该容器便可。

--restart:容器退出时应用的重启策略

-u:即--user,用户名或 UID(格式:<name|uid>[:<group|gid>])

-p:即--publish,将容器的端口发布到主机

-v:即--volume,绑定挂载卷

-v jenkins-data:/var/jenkins_home:将容器中的 /var/jenkins_home 目录映射到 Docker volume ,并将其命名为 jenkins-data。如果该卷不存在, 那么 docker run 命令会自动为你创建卷。

-v /var/run/docker.sock:/var/run/docker.sock:在前台运行并将其日志直接发送到您的终端,详见官网文档

docker run 命令更多参数使用信息,详见官方文档

使用 Docker Compose 运行 Jenkins

当然,每次docker run...,不方便,可以在需要的路径下配置compose.yaml文件,并在当前路径下的命令行输入docker compose up,它会读取compose.yaml文件,自动执行命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
services:
jenkins:
image: jenkinsci/blueocean
volumes:
- jenkins-data:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- /home/huatree/document:/home
user: root
restart: always
environment:
- JAVA_OPTS=-Dhudson.model.DirectoryBrowserSupport.CSP= -Dhudson.plugins.git.GitSCM.ALLOW_LOCAL_CHECKOUT=true
ports:
- 8080:8080
stdin_open: true
tty: true
volumes:
jenkins-data:

更多compse.yaml参数配置,详见官方文档

Dhudson.model.DirectoryBrowserSupport.CSP=空格:确定为 Jenkins 提供的静态文件发送的内容安全策略标头。有关更多详细信息,请参阅配置内容安全策略

Dhudson.plugins.git.GitSCM.ALLOW_LOCAL_CHECKOUT=true:允许本地目录验证。更多信息详见

访问 Jenkins/Blue Ocean Docker 容器

解锁 Jenkins

当你第一次访问一个新的 Jenkins 实例时, 要求你使用自动生成的密码对其进行解锁。

当在终端/命令提示窗口出现两组星号时, 浏览 http://localhost:8080 并等待 解锁 Jenkins 页面出现。

image-20220516093617699

再次从终端/命令提示窗口, 复制自动生成的字母数字密码(在两组星号之间)。

image-20220516093715354

解锁 Jenkins 页面, 粘贴该密码到 管理员密码 字段并点击 继续,进入新手入门页面。

image-20220516094041627

使用插件自定义 Jenkins

解锁 Jenkins 后,自定义 Jenkins 页面出现,可以选择默认的安装推荐的插件。后续可以在插件管理页面进行维护(卸载/更新/添加)。

安装向导显示了正在配置的 Jenkins 的进程,以及建议安装的插件。这个过程肯需要几分钟。

创建第一个管理员用户

最后, Jenkins 要求创建你的第一个管理员用户。

创建第一个管理员用户 页面出现, 在相应的字段中指定你的详细消息并点击 保存并完成

image-20220516095217292

实例配置 页面出现,根据需要是否配置 Jenkins URL,并点击 保存并完成

image-20220516095453149

Jenkins 已就绪 页面出现, 点击 开始使用 Jenkins

image-20220516095803705

等待一会儿,Jenkins 主页出现。

image-20220516102328899

停止和重启 Jenkins

在其他时候,如果不用了,你可以通过在终端/命令提示窗口输入 Ctrl-C停止 Jenkins/Blue Ocean Docker 容器。想用时,执行docker compose start

另一种场景:正常启动了 Jenkins,关掉命令行工具,该容器并没有停止运行。如果想停止,则终端执行命令docker compose stop

Fork 和 clone GitHub 示例仓库

通过将应用程序源代码所在的示例仓库 fork 到你自己的 Github 账号中, 并 clone 到本地, 你就可以获取一个”Welcome to React”简单 Node.js 和 React 应用程序。

将示例仓库 simple-node-js-react-npm-app fork 到你的账户的 Github 仓库中。接着,将你的 GitHub 账户中的 simple-node-js-react-npm-app 仓库 clone 到你本地的如下目录:

1
/home/huatree/document/github/simple-node-js-react-npm-app

/home/huatree/document是上面compose.yaml的内容,从你主机上的/home/huatree/document目录映射到 Jenkins 容器的 /home

在 Jenkins 中创建流水线项目

回到浏览器打开的 Jenkin 页面,再次登录并点欢迎来到 Jenkins!下的create new jobs 。 如果没有看到上述内容,请点击左侧的 新建任务

输入一个任务名称 域, 填写你的新的流水线项目的名称 (比如simple-node-js-react-npm-app)

向下滚动并单击 流水线, 然后点击页面末尾的 确定

image-20220516105037672

General>描述 字域为你的流水线项目做一个简短的描述(比如. An entry-level Pipeline demonstrating how to use Jenkins to build a simple Node.js and React application with npm.)

image-20220516105429577

流水线栏,在定义域,选择 Pipeline script from SCM 选项。此选项指示 Jenkins 从源代码管理(SCM)仓库获取你的流水线, 这里的仓库就是你 clone 到本地的 Git 仓库。

SCM 域中,选择 Git。有关GitSCM更多信息,详见

Repository URL 域中,可以有如下填写操作:

如果填写 clone 到本地的仓库映射路径/home/github/simple-node-js-react-npm-appCredentials项就默认即可,无需添加凭据,因为compose.yaml文件已经配置了如下内容:

1
2
environment:
- JAVA_OPTS=-Dhudson.model.DirectoryBrowserSupport.CSP= -Dhudson.plugins.git.GitSCM.ALLOW_LOCAL_CHECKOUT=true

如果填写的是远程仓库路径:如git@github.com:huatree/simple-node-js-react-npm-app.git,则在Credentials域中,添加凭据,选择类型为SSH Username with private key,然后复制粘贴本地的.ssh 目录下的私钥,点击确定,再选中配置好的凭据。

image-20220516105841594

其他项默认即可(后续可根据需要自行修改配置),点击 保存 保存你的流水线项目。你现在可以开始创建你的 Jenkinsfile,这些文件会被添加到你的本地仓库。

将你的初始流水线创建为 Jenkinsfile

simple-node-js-react-npm-app项目根目录下创建Jenkinsfile文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
pipeline {
agent {
docker {
image 'node:10'
args '-p 3000:3000'
}
}
stages {
stage('Build') {
steps {
sh 'npm install'
}
}
}
}

更多Jenkinsfile配置,详见官方文档

保存并提交你编辑的 Jenkinsfile 到你本地的 simple-node-js-react-npm-app Git 仓库,推送到远程simple-node-js-react-npm-app仓库。

回到浏览器 Jenkins 主页面,左侧选择打开 Blue Ocean,弹出框提示”该任务还未运行“,点击运行。等待一会儿,出现报错

image-20220516113556323

此时,需要安装DockerDocker Pipeline2 个插件。转到 Jenkins 根页面 > 插件管理 > 可用并搜索插件。安装好后,重启 Jenkins 服务生效,再次运行即可。

如果 Jenkins 成功构建了你的应用,Blue Ocean 的界面就会变绿。

image-20220516122621742

向流水线添加 Test 阶段

回到文本编辑器/IDE,打开Jenkinsfile,如下编辑

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
pipeline {
agent {
docker {
image 'node:lts-buster-slim'
args '-p 3000:3000'
}
}
environment {
CI = 'true'
}
stages {
stage('Build') {
steps {
sh 'npm install'
}
}
stage('Test') {
steps {
sh './jenkins/scripts/test.sh'
}
}
stage('Deliver') {
steps {
sh './jenkins/scripts/deliver.sh'
input message: 'Finished using the web site? (Click "Proceed" to continue)'
sh './jenkins/scripts/kill.sh'
}
}
}
}

修改package.json

1
"test": "cross-env CI=true react-scripts test --env=jsdom"

修改jenkins/scripts/test.th

1
2
# 去掉npm install --save-dev cross-env的注释
npm install --save-dev cross-env

再次提交并推送到远程仓库,运行构建,结果如下

image-20220516124427698

给流水线添加最终交付阶段

回到文本编辑器/IDE,打开Jenkinsfile,如下编辑

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
pipeline {
agent {
docker {
image 'node:10'
args '-p 3000:3000'
}
}
environment {
CI = 'true'
}
stages {
stage('Build') {
steps {
sh 'npm install'
}
}
stage('Test') {
steps {
sh './jenkins/scripts/test.sh'
}
}
stage('Deliver') {
steps {
sh './jenkins/scripts/deliver.sh'
input message: 'Finished using the web site? (Click "proceed" to continue)'
sh './jenkins/scripts/kill.sh'
}
}
}
}

提交并推送到远程仓库,点击立即构建或运行

image-20220516130020852

观察 “Deliver” 阶段 (必要的时候点击它), 然后点击 绿色的 ./jenkins/scripts/deliver.sh 步骤扩展它的内容并向下滚动直到看见 http://localhost:3000 链接,访问它。

image-20220516130125776

点击 http://localhost:3000 链接在一个新的浏览器选项卡查看你的 Node.js 和 React 应用的运行(在开发模式下) 。 你会 看到一个标题为 Welcome to React 的网页/站点。

image-20220516130201358

当你查看完页面/站点, 点击 继续 按钮以完成流水线的执行。

image-20220516130920146

总结

做得好!您刚刚使用 Jenkins 通过 npm 构建了一个简单的 Node.js 和 React 应用程序!

您在上面创建的 “Build”, “Test” 和 “Deliver” 阶段是使用 Jenkins 中的 Maven 构建更复杂的 Node.js 和 React 应用程序以及与其他技术栈集成的 Node.js 和 React 应用程序的基础。

由于 Jenkins 具有极高的可扩展性,因此可以对其进行修改和配置,以处理构建协调和自动化的几乎任何方面。

要详细了解 Jenkins 可以做什么,请查看:

相关链接

[1] 使用 npm 构建 Node.js 和 React 应用

[2] Jenkins. Invalid agent type “docker” specified. Must be one of [any, label, none]

[3] ALLOW_LOCAL_CHECKOUT set but local checkout not available

[4] Pipeline: SCM Step