Skip to content

使用 Jenkins 自动部署 Docker 服务(二、构建部署篇) ​

如果还没有搭建好可以使用 Docker 的 Jenkins,请先移步到这篇文章进行搭建

使用 Jenkins 自动部署 Docker 服务(一、Jenkins 搭建篇) ​

目标 ​

通过 Jenkins 实现推送代码后自动部署基于 Docker 的服务

准备工作 ​

获取示例项目或者直接复制以下文件内容

# 获取示例项目
git clone https://github.com/kwkwc/jenkins_demo.git

# 项目文件
├── index.html              # 页面文件
├── Dockerfile              # 镜像文件
├── docker-compose.src.yml  # Docker 部署文件
├── deploy_jenkins.sh       # 部署脚本
├── Jenkinsfile             # Jenkins Pipeline 文件

页面文件 ​

项目很简单,就是一个静态网页

index.html ​

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Jenkins demo</title>
    </head>
    <body>
        <h1>Jenkins demo</h1>
    </body>
</html>

镜像文件 ​

镜像以 nginx 为基础镜像,然后复制 index.html 进容器

Dockerfile ​

FROM nginx:1.15.2
ENV REFRESHED_AT 2018-08-09

COPY ./index.html /usr/share/nginx/html/index.html

RUN ln -sf /dev/stdout /var/log/nginx/access.log \
	&& ln -sf /dev/stderr /var/log/nginx/error.log

EXPOSE 80

STOPSIGNAL SIGTERM

CMD ["nginx", "-g", "daemon off;"]

Docker 部署文件 ​

设置了 8081 端口和部署失败重试

docker-compose.src.yml ​

version: '3.4'
services:
  jenkins_demo:
    image: IMAGE_LATEST
    deploy:
      restart_policy:
        condition: on-failure
    expose:
      - "80"
    ports:
      - 8081:80

部署脚本 ​

deploy_jenkins.sh ​

#!/bin/bash

# 容器名称
CONTAINER="jenkins_demo"
# 镜像名称(以日期时间为镜像标签,防止重复)
IMAGE=$CONTAINER":"$(date -d "today" +"%Y%m%d_%H%M%S")

# 删除滚动更新残留的容器
docker rm `docker ps -a | grep -w $CONTAINER"_"$CONTAINER | awk '{print $1}'`
# 强制删除滚动更新残留的镜像
docker rmi --force `docker images | grep -w $CONTAINER | awk '{print $3}'`

# 创建新镜像
docker build -t $IMAGE . && \

# 删除 docker-compose.jenkins.yml 文件,防止使用相同镜像
rm -rf docker-compose.jenkins.yml && \

# 复制 docker-compose.src.yml 文件,防止污染原文件
cp docker-compose.src.yml docker-compose.jenkins.yml && \

# 替换镜像名标志位为最新镜像
sed -i s%IMAGE_LATEST%$IMAGE%g docker-compose.jenkins.yml && \

# 使用 docker stack 启动服务
docker stack deploy -c docker-compose.jenkins.yml $CONTAINER

实现无工具自动部署 ​

我们暂时忘记 Jenkins,先看看无工具自动部署是怎么实现的

初始化 Docker Swarm 集群网络 ​

由于我们使用了 Docker Stack,他可用于实现滚动更新,分布式集群,但依赖于 Docker Swarm 集群网络,直接使用会报错,所以需要先初始化 Docker Swarm 集群网络

# 初始化 Docker Swarm 集群网络
docker swarm init

运行部署脚本 ​

./deploy_jenkins.sh

查看镜像 ​

docker images

1.png

查看容器 ​

docker ps

2.png

浏览器打开 ​

http://127.0.0.1:8081

成功自动部署 ​

3.png

更改内容 ​

尝试修改 index.html 内容再运行部署脚本 ./deploy_jenkins.sh

效果 ​

4.png

实现 Jenkins 自动部署 ​

Jenkins 的自动部署本来比较复杂,但是后来有了 Pipeline,一切都简单了,Pipeline 是 Jenkins 的一个插件,初始化 Jenkins 的时候会推荐安装,如果没有请自行安装

Jenkins Pipeline 文件 ​

项目中如果有 Jenkinsfile 文件, Jenkins 检测到就会自动按 Jenkinsfile 写的流程运行命令,例如这个 Jenkinsfile 文件里面写的就是自动帮我们运行刚才的部署脚本

Jenkinsfile ​

pipeline {
  agent none
  stages {
    stage('Deploy') {
      agent any
      steps {
        echo 'Deploying'
        sh './deploy_jenkins.sh'
      }
    }
  }
}

新建任务 ​

输入任务名称,选择流水线

5.png

填写信息 ​

只需要填写流水线里面的信息 "定义" 选择 "Pipeline script from SCM" "SCM" 选择 "Git" "Repository URL" 填写 Git 仓库地址 选好 Git 分支 如果是私密仓库,在 “Credentials” 那一栏添加账号密码然后选择账号就行

6.png

查看任务 ​

保存后回到主页就可以看到我们新建的任务,可以看到状态、运行情况等信息

7.png

手动构建 ​

点击一下界面的立即构建按钮就可以开始构建了

8.png9.png

自动构建(定时查询) ​

设置构建触发器,例如每 30 分钟查询一次是否有更新,有则自动构建

10.png

自动构建(主动通知) ​

主动通知需要安装插件,这里以 Gitea 为例子,Gitea 使用的是 Gogs 的插件 "系统管理" --> "插件管理" --> "可选插件" 搜索 Gogs,勾选直接安装,安装成功后在项目配置里面会多出一个 "Gogs Webhook" 选项,不需要配置任何东西,安装了就行

11.png12.png

设置 Gitea 钩子 ​

在 Gitea 的 Webhooks 中填写下面的 URL 就可以实现推送代码后主动通知 Jenkins 自动部署,其他基于 Git 的仓库设置一样 http://127.0.0.1:8080/gogs-webhook/?job=jenkins_demo

13.png