多图超详细 jenkins 容器安装并部署前端项目

1,027 阅读8分钟

1.提前准备

  1. 1 台 linux 云服务器或者本地虚拟机代替
  2. 在服务器宿主机上装好 docker
  3. 准备好 2 个 github 仓库(或者 gitee 仓库),1 个用于 jenkins,1 个用于前端项目(文章以 github 仓库为例)
  4. 1 个 dockerhub 仓库,用于存储 jenkins 镜像

2.jenkins 容器安装

1. 安装前的疑问

  1. 为什么不直接在宿主机上安装 jenkins?

答:可以直接在宿主机上安装 jenkins,并不一定非得使用容器这种形式安装,只不过本文使用了容器安装这种方式。

  1. 为什么不直接拉取 dockerhub 上的 jenkins 镜像?

答:可以直接拉取,但一定要拉取jenkins/jenkins这个镜像,jenkins这个镜像已经很久没维护了。 还有官方的 jenkins 镜像默认是没有 sudo 用户权限的,即执行sudo wget http://xxxx,是不识别 sudo 命令的,还有常见的wgetvimping等常用命令都是没有的,需要自己安装,所以这里选择自己构建 jenkins 镜像。

  1. 如何在 jenkins 容器里执行 docker 命令?

答:一番搜索,有两种方案,本文使用了 Docker-outside-of-Docker 方案,另一种未实验成功。

  • Docker-outside-of-Docker

    使用外部的 docker,即容器宿主机上的 docker。将宿主机的 docker 程序映射到 jenkins 容器里。这样没安装 docker 的 jenkins 容器可以执行 docker 命令。但需要注意的是,容器里本身是没有 docker 的,是把指令发送给宿主机来执行的。

  • Docker-in-Docker

    顾名思义,在 docker 容器里安装 docker,然后使用 docker。容器里有 docker,和宿主机上的 docker 是隔离的。

2. Dockerfile 编写

FROM jenkins/jenkins:latest

USER root
RUN apt-get update \
  # 安装sudo
  && apt-get install -y sudo \
  && rm -rf /var/lib/apt/lists/*
RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers

USER jenkins

EXPOSE 8080

3. github 的 workflow 配置文件

  • 前提需要在 github 的 jenkins 仓库里设置好 secrets

  • 在仓库的Settings -> Secrets -> Actions,点击New repository secret按钮创建你的 dockerhub 账号和密码,即添加DOCKERHUB_USERNAMEDOCKERHUB_TOKEN。如下图所示操作:

add-secrets.jpg

  • /.github/workflows/deploy.yml
name: jenkins image build and push

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      #制作docker镜像推送到dockerhub
      - name: build and push to dockerhub
        run: |
          docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }}
          docker image build -t my-jenkins:latest .
          docker tag my-jenkins:latest ${{ secrets.DOCKERHUB_USERNAME }}/my-jenkins:latest
          docker push ${{ secrets.DOCKERHUB_USERNAME }}/my-jenkins:latest
          docker logout
  • git 提交代码,自动打包推送镜像到 dockerhub
git add .
git commit -m "feat: init"
git push -u origin main

不出意外,Actions里可以看到,自动部署成功

workflows.jpg

镜像也成功推送到 dockerhub 了

dockerhub.jpg

4. 在服务器宿主机上拉取刚才的镜像并安装

  1. 拉取镜像
docker pull [你的dockerhub名字]/my-jenkins:latest
  1. 启动容器
sudo docker container run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(which docker):/usr/bin/docker \
-p 8000:8080 \
--name my-jenkins [你的dockerhub名字]/my-jenkins:latest

解释下参数的含义:

  • -d: 后台运行容器

  • -v: 指定挂载目录卷。

    • 第 1 行表示将宿主机上的/var/run/docker.sock目录映射到容器中,这样我们在容器中运行的 docker 命令,就会被发送到宿主机上去执行
    • 第 2 行表示将宿主机上的 docker 程序映射到容器中,这样容器就可以运行 docker 命令,容器本身没有安装 docker 服务。
  • -p: 前面是宿主机上的端口(服务器安全组中要配置好,不然浏览器里无法访问),后面是容器端口,jenkins 默认是 8080 端口

  • -name: 给容器命名,是基于[你的dockerhub名字]/my-jenkins:latest这个镜像创建的容器,并命名为my-jenkins

不出意外,容器启动成功,我们可以用浏览器进行访问了。

3.jenkins 容器配置

注意:如果在 jenkins 里不部署 docker 项目,这一章节可以略过,这里都是为了能在 jenkins 里部署 docker 项目准备的。

在浏览器访问前,我们还需要进入容器内部,安装常用命令工具,检验是否可以执行 docker 命令。

  1. 先进入容器内部

如果你的宿主机上安装了如portainerrancher等 docker 容器管理面板,可以直接通过可视化的方式来进入容器,就不用敲命令了。

docker container exec -it my-jenkins /bin/bash
  1. 查看系统信息
cat /etc/issue

不出意外,打印出

Debian GNU/Linux 11 \n \l

说明容器内部是Debian发行版,不是Ubuntu,也不是CentOS

  1. 安装常用工具

因为容器内是Debian,那就使用 apt-get。安装这些工具的目的在于后面有可能需要进入容器操作,所以这里提前安装好。

# 先更新升级apt-get源
sudo apt-get update
sudo apt-get upgrade
# 安装systemctl
sudo apt-get install -y systemctl
# 安装vim
sudo apt-get install -y vim
# 安装wget
sudo apt-get install -y wget
  1. 检验容器内部是否可以执行 docker 命令
  • 测试 docker -v 命令

    docker -v
    

    不出意外,正常打印信息,比如:

    Docker version 17.12.1-ce, build 7390fc6
    

    如果出现报错:

    docker: error while loading shared libraries: libltdl.so.7: cannot open shared object file: No such file or directory
    

    那就再安装libltdl7

    sudo apt-get install -y libltdl7
    
  • 测试运行 hello-world

    sudo docker run --rm hello-world
    

    如果正常打印下面信息,说明在容器里执行 docker 命令是没问题的。

    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    

4.jenkins 初始化

  1. 浏览器里访问http://[你的服务器ip]:[上面启动容器暴露的端口,我这里是8000],开始初始化,如下图:

jenkens-init.jpg

  1. 初始化结束后,需要解锁 Jenkins

jenkins-unlock.jpg

进入容器内部,执行下面命令,复制出那一串密码,粘贴到这里,然后点击确定

cat /var/jenkins_home/secrets/initialAdminPassword
  1. 安装推荐的插件

jenkins-plugin.jpg

点击左侧安装推荐的插件,过一会,等插件安装好

jenkins-plugins-install.jpg

  1. 注册管理员账号

按着提示一步步来操作

jenkins-admin.jpg

  1. 最终进入 jenkins 首页,表示安装成功了

jenkins-welcome.jpg

5. jenkins 部署前端项目

这里以 react(create-react-app 创建) 项目为例,vue 的一样的,和框架无关

5.1 jenkins 安装 Nodejs 插件

因为是前端项目,离不开 nodejs,所以要安装

  1. 左侧Manage Jenkins(系统管理) -> System Configuration(系统配置)下点击Manage Plugins(插件管理),找到并安装 Nodejs 插件,点击Download now and install after restart,安装完成后,勾选重启,jenkins 会自动重启

jenkins-plugin-nodejs.png

  1. 重启完成后,左侧Manage Jenkins(系统管理) -> System Configuration(系统配置)下点击全局工具配置,找到 Nodejs 选项,点击新增Nodejs按钮,输入别名,最后点击保存,就配置好 Nodejs 了

jenkins-global-plugin.jpg

5.2 部署前的配置

  1. 提前准备好前端项目,提交到 github 仓库

  2. github 生成 Personal access tokens

    github 头像下拉框-> Settings -> 左侧菜单Developer settings -> Personal access tokens -> 点击Generate new token注意:请把生成的 token 复制下来,页面刷新后就没了

github-token.jpg

  1. jenkins 中添加 Github 服务器
  • 系统管理 -> 系统配置 -> 添加 Github 服务器 -> 添加 Secret text 凭证 -> 连接测试

jenkins-addpj.jpg

  • 第 2 步点击后,弹出下面弹框,类型里下拉选择Secret text,Secret里填入上面生成的 token,点击确定

jenkins-pj.jpg

  • 第 5 步点击后,勾选为Github指定另一个Hook URL,会自动生成一个 url,保存下这个 url

jenkins-auto-webhooks.jpg

最后,别忘记保存

  1. 配置 github 仓库的Webhooks
  • 点击Settings->Webhooks->Add Webhook->输入Payload URL

  • 这里的 Payload URL,就是上面生成的 Hook URL

github-webhook.jpg

5.3 正式部署前端项目

  1. jenkins 左侧菜单点击新建任务,输入任务名称,选择构建一个自由风格的软件项目,点击确定

jenkins-firsttask.jpg

  1. 创建

jenkins-task-1.jpg

  1. 源码管理

jenkins-task-2.jpg

  1. 构建触发器

这样每次在提交代码后,jenkins 就可以自动为我们构建项目

勾选GitHub hook trigger for GITScm polling

jenkins-task-3.jpg

  1. 构建环境

这里是选择项目需要的 nodejs 版本,nodejs 的版本就按着前面所说的添加

jenkins-task-4.jpg

  1. 构建-执行 shell

jenkins-task-5.jpg

完整 shell 如下:

node -v
npm -v
docker -v
sudo su

echo "1.开始打包构建==>"
npm install -g yarn
yarn install
npm run build

{ # try
	echo "2.暂停旧的容器==>"
  sudo docker container stop react-app
} || { # catch
  echo "2.旧的容器不存在==>"
    # save log for exception
}

{ # try
	echo "3.删除旧的容器==>"
  sudo docker container rm react-app
} || { # catch
  echo "3.旧的容器不存在==>"
}

{ # try
	echo "4.删除旧的镜像==>"
  sudo docker image rm react-app:latest
} || { # catch
  echo "4.旧的镜像不存在==>"
}

echo "5.开始构建==>"
sudo docker image build -t react-app:latest .
sudo docker tag react-app:latest srect/react-app:latest

echo "6.开始启动docer容器==>"

sudo docker container run -d -p 8002:80 --name react-app react-app:latest
  1. 点击保存,然后立即构建,可以进入任务,点击控制台输出,查看具体的构建日志

jenkins-console.jpg

  1. 我们可以随便修改下前端代码,然后提交代码,测试是否会自动构建

jenkins-github-hook-log.jpg

6. 参考资料

  1. 用安装在 Docker 中的 jenkins 运行 Docker 任务
  2. Jenkins+Github 实现自动触发构建