前言

虽然Docker已经是风靡全球的容器技术了,统一环境避免环境问题上是Docker的主要吸引点之一,但使用时详细还是会遇到不少问题的,比如个人搭建时曾思考过这些问题:

  • Jenkins官网既然有Docker上安装Jenkins的流程了,那我该怎么使用Jenkins容器呢?
  • 如果使用Jenkins容器,我该怎么通过Jenkins容器部署SpringBoot项目?是通过Jenkins容器与SpringBoot容器中的文件交互进行项目部署吗?这能做到吗?又或是把SpringBoot项目放到Jenkins容器中管理,那Jenkins中又要安装git、maven等一堆东西,这一点都不方便。
  • 使用IDEA Docker插件都可以直接本地连接到服务器的Docker创建镜像并运行容器了,为什么还需要Jenkins?

个人在实际搭建部署中也找到了与上相对应的答案:

  • 如果使用Jenkins容器,这将使得部署更加麻烦,因Jenkins往往需要配置Maven、git等一系列变量,应另寻出路。Jenkins既然是一款脚本CI工具,而Docker也有自己的脚本,我应该将Docker脚本集成到Docker中这方面考虑。
  • 在实际开发中,Jenkins可能不仅需要项目的部署,还需要进行开发人员的鉴权,如开发人员A只能查看部署指定项目,管理员可以查看部署所有项目,但Docker主要用于镜像构建与容器运行,无法像Jenkins一样获取github/gitlab代码,也无法进行开发人员的鉴权,所以Docker可以在Jenkins中只扮演简化部署过程的一个角色。
  • 虽然IDEA插件可以直接把本地打包成功的项目部署服务器Dcoker并创建镜像运行容器,但为了安全还需要创建Docker CA认证下载到本地再进行服务器上的Docker连接,十分不便捷。

环境准备

当探索到自我提问的答案时,便确定了各组件的主要职责:

  • Jenkins:接收项目更新信息并进行项目打包与Docker脚本的执行
  • Docker:安装所需应用镜像与运行容器
  • git:项目信息同步

搭建环境流程:

  1. 安装JDK
  2. 安装Maven
  3. 安装git
  4. 安装Jenkins(该步骤之前的可参考Jenkins安装并部署Java项目完整流程)如有权限问题可将/etc/sysconfig/jenkins文件JENKINS_USER修改为root或手动赋权
  5. Centos安装Docker
  6. 安装DockerCompose
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose --version

使用DockerCompose可省去容器增多时需多次执行docker run的麻烦

测试Docker-composer

1. 先下载代码:https://github.com/AndyYoungCN/DockerDemo

2.运行

  • 2.1 打包jar
    mvn clean package
  • 2.2 docker-composer
    docker-compose up -d --build
  • 2.3 运行效果

具体步骤

配置文件

1. SpringBoot项目Dockerfile

FROM java:8MAINTAINER WilsonENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone#这里的 /tmp 目录就会在运行时自动挂载为匿名卷,任何向 /tmp 中写入的信息都不会记录进容器存储层
VOLUME /tmp#复制target/DOCKERDEMO.jar到容器里WORKDIR下
COPY target/DOCKERDEMO.jar app.jarENTRYPOINT ["java","-jar","app.jar"]

2. 配置docker-compose.yml

version: '3.7'
services:app:restart: alwaysbuild: ./hostname: docker-spring-bootcontainer_name: docker-spring-bootimage: docker-spring-boot#    不对外开放端口,只能通过容器访问
#    ports:
#      - 8080:8080volumes:- ./volumes/app:/appnginx:depends_on:- appcontainer_name: docker-nginxhostname: docker-nginximage: nginx:1.17.6environment:TZ: Asia/Shanghairestart: alwaysexpose:- 80ports:- 80:80links:- appvolumes:- ./volumes/nginx/nginx.conf:/etc/nginx/nginx.conf- ./volumes/nginx/conf.d:/etc/nginx/conf.d- ./volumes/nginx/logs:/var/log/nginx

3. Nginx

  • ./volumes/nginx/nginx.conf
user nginx;
worker_processes 2; #设置值和CPU核心数一致
error_log /etc/nginx/error.log crit; #日志位置和日志级别
pid /etc/nginx/nginx.pid;events
{use epoll;worker_connections 65535;
}
http{include mime.types;default_type application/octet-stream;log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for" "$http_cookie"';access_log  /var/log/nginx/access.log main;#charset utf8;server_names_hash_bucket_size 128;client_header_buffer_size 32k;large_client_header_buffers 4 32k;client_max_body_size 8m;sendfile on;tcp_nopush on;keepalive_timeout 60;tcp_nodelay on;fastcgi_connect_timeout 300;fastcgi_send_timeout 300;fastcgi_read_timeout 300;fastcgi_buffer_size 64k;fastcgi_buffers 4 64k;fastcgi_busy_buffers_size 128k;fastcgi_temp_file_write_size 128k;gzip on;gzip_min_length 1k;gzip_buffers 4 16k;gzip_http_version 1.0;gzip_comp_level 2;gzip_types text/plain application/x-javascript text/css application/xml;gzip_vary on;#limit_zone crawler $binary_remote_addr 10m;#server虚拟主机的配置include /etc/nginx/conf.d/*.conf;}
  • ./volumes/nginx/conf.d目录下的default.conf
upstream application {server docker-spring-boot:8080;
}server{listen 80;#监听端口server_name localhost;#域名access_log /var/log/nginx/nginx-spring-boot.log;location / {proxy_pass   http://application;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header REMOTE-HOST $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}
}

Jenkins部署执行流程

maven打包Spring Boot项目为project.jar

根据是否以第一次项目部署执行以下不同的流程:

  • 如当前挂载卷已含项目jar(即非第一次运行),则运行以下步骤:拷贝project.jar覆盖挂载卷中的project.jar重新运行SpringBoot项目容器

  • 如当前挂载卷不含项目jar(即非第一次运行),则运行以下步骤:创建挂载卷目录拷贝project.jar到挂载卷中通过docker-compose读取docker-compose.yml配置创建镜像启动容器

Jenkins脚本(如果Nginx配置更改较多也可添加Nginx容器重启指令):

cd /var/lib/jenkins/workspace/docker-spring-boot/spring-boot-nginx-docker-demo
mvn clean package
if [ -e "./volumes/app/docker-spring-boot.jar" ]then rm -f ./volumes/app/docker-spring-boot.jar \&& cp ./target/docker-spring-boot.jar ./volumes/app/docker-spring-boot.jar \&& docker restart docker-spring-boot \&& echo "update restart success"else mkdir volumes/app -p \&& cp ./target/docker-spring-boot.jar ./volumes/app/docker-spring-boot.jar \&& docker-compose -p docker-spring-boot up -d \&& echo "first start"
fi

docker-compose up指令可以进行镜像的安装,所以也省去了只用docker指令时需要提前准备好镜像相关指令的麻烦。

结果测试

  • 查看容器是否皆已启动:docker ps

  • SpringBoot容器运行结果查看:如容器开放了8080端口则可通过http://url:8080/swagger-ui.html测试,也可通过查看Jenkins工作空间下/volumes/app的SpringBoot日志校验结果(SpringBoot日志的路径配置个人设置为app/logs目录下,前文已把容器中的app目录挂载到当前项目的volumes/app目录下)

  • Nginx容器运行结果查看:访问http://url/swagger-ui.html测试是否Nginx容器已成功连通SpringBoot容器并进行了反向代理,也可通过查看Jenkins工作空间下/volumes/nginx/logs的Nginx日志校验结果

  • 添加或删除controller接口再进行推到git,查看更改的接口是否可访问

SpringBoot集群搭建

如需将SpringBoot通过容器集群搭建,只需进行以下更改:

  • docker-compose.yml添加SpringBoot项目冗余,更改冗余容器名,区分日志挂载路径,冗余项目更改容器名
version: '3.7'
services:app:restart: alwaysbuild: ./hostname: docker-spring-bootcontainer_name: docker-spring-bootimage: docker-spring-boot/latestvolumes:- ./volumes/app/docker-spring-boot.jar:/app/docker-spring-boot.jar- ./volumes/app/logs:/app/logsapp-bak:restart: alwaysbuild: ./hostname: docker-spring-bootcontainer_name: docker-spring-boot-bakimage: docker-spring-boot/latestvolumes:- ./volumes/app/docker-spring-boot.jar:/app/docker-spring-boot.jar- ./volumes/app/logs-bak:/app/logsnginx:depends_on:- appcontainer_name: docker-nginxhostname: docker-nginximage: nginx:1.17.6environment:TZ: Asia/Shanghairestart: alwaysexpose:- 80ports:- 80:80links:- app- app-bakvolumes:- ./volumes/nginx/nginx.conf:/etc/nginx/nginx.conf- ./volumes/nginx/conf.d:/etc/nginx/conf.d- ./volumes/nginx/logs:/var/log/nginx
  • nginx更改default.conf的upstream,添加冗余容器配置
upstream application {server docker-spring-boot:8080 fail_timeout=2s max_fails=2 weight=1;server docker-spring-boot-bak:8080 fail_timeout=2s max_fails=2 weight=1;
}server{listen 80;#监听端口server_name localhost;#域名access_log /var/log/nginx/nginx-spring-boot.log;location / {proxy_pass   http://application;proxy_connect_timeout 2s;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header REMOTE-HOST $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}
}
  • Jenkins添加冗余容器重启脚本
BUILD_ID=DONTKILLME
cd /var/lib/jenkins/workspace/docker-spring-boot/spring-boot-nginx-docker-demo
mvn clean package
if [ -e "./volumes/app/docker-spring-boot.jar" ]then rm -f ./volumes/app/docker-spring-boot.jar \&& cp ./target/docker-spring-boot.jar ./volumes/app/docker-spring-boot.jar \&& docker-compose -p docker-spring-boot up -d \&& docker restart docker-spring-boot \&& docker restart docker-spring-boot-bak \&& docker restart docker-nginx \&& echo "update restart success"else mkdir volumes/app -p \&& cp ./target/docker-spring-boot.jar ./volumes/app/docker-spring-boot.jar \&& docker-compose -p docker-spring-boot up -d \&& echo "first start"
fi

测试集群效果:

  • volumes/app放置了不同容器的日志,如该例子的logs、logs-bak
  • 停止任一SpringBoot容器docker stop docker-spring-boot,仍可通过url/api通过Nginx访问

可以看出容器配置集群的以下优点:

  • 安全性高,每一个应用都只属一个容器,通过特定配置才可与主机、其它容器交互
  • 统一配置文件,简单粗暴的方式解决端口、路径、版本等配置问题,如该项目即使运行了2个8080端口的SpringBoot容器而不需担心端口的冲突、暴露问题,一切都在容器内解决
  • 省略手动应用安装,易于迁移,由于版本、配置、环境等都已配置在Docker的配置文件中,所以不用担心更换机器后出现的各种配置、环境问题,且通过镜像拉取与容器运行可以省略如Nginx、Redis、Mysql等应用的安装与配置

代码参考:https://github.com/AndyYoungCN/DockerDemo

Docker(十二):Docker+Jenkins+Nginx+Spring Boot 自动化部署项目相关推荐

  1. Docker+Jenkins+Nginx+Spring Boot 自动化部署项目

    Docker通过linux的namespace实现资源隔离.cgroups实现资源控制,通过写时复制机制(copy-on-write)实现了高效的文件操作,在实际开发中可用于提供一次性的环境.微服务架 ...

  2. centos+jenkins+nginx+gitlab前端自动化部署全记录

    0. 前言 我们在开发一个新的项目时,总是需要将前端部署到测试服务器上,给测试或者产品访问.简单的来说,如果想部署前端到服务器,服务器需要提供一个服务来访问前端.如果我们在开发中没有涉及Node.js ...

  3. 《阿里云服务器搭建》------实现Jenkins和github之间自动化部署Java web项目

    本系列教程的搭建环境为阿里云服务器,其他服务器可作为参考. 本文主要讲述实现Jenkins和github之间自动化部署项目 在浏览器中打开我们的jenkins页面.(http://ip:80/jenk ...

  4. Docker教程(二) Docker环境安装

    Docker教程(二) Docker环境安装 本文链接:https://blog.csdn.net/yuan_xw/article/details/77248243 Docker教程(二) Docke ...

  5. Spring Boot电商项目57:订单模块六:【前台:生成支付二维码】接口;(支付url的拼凑;利用zxing生成二维码;二维码图片的存储;真实地址与可访问地址的转换;)

    说明: (1)本篇博客主要内容是:开发[前台:生成支付二维码]接口: (2)本篇博客需要注意的点有: ● 支付url的拼凑: ● 利用zxing生成二维码: ● 二维码图片的存储:真实地址与可访问地址 ...

  6. springboot项目实战_2019学习进阶之路:高并发+性能优化+Spring boot等大型项目实战...

    Java架构师主要需要做哪些工作呢? 负责设计和搭建软件系统架构(平台.数据库.接口和应用架构等),解决开发中各种系统架构问题. 优化现有系统的性能,解决软件系统平台关键技术问题攻关.核心功能模块设计 ...

  7. 10个Spring Boot 优秀学习项目

    10个Spring Boot 优秀学习项目 10个SpringBoot项目分享(好像多了一个项目) 一.mall (虽然培训机构已经把电商推广了烂大街了,但技术还是可以学习的) 二.Cloud-Pla ...

  8. 开源的13个Spring Boot 优秀学习项目

    开源的13个Spring Boot 优秀学习项目!超53K星,一网打尽! 原创: 徐刘根 Java后端技术 5月19日 Spring Boot 算是目前 Java 领域最火的技术栈了,也是Java开发 ...

  9. (十五)Alian 的 Spring Cloud 自动生成项目

    目录 一.创建 1.1.第一步 二.mvn命令 三.生成项目 3.1.配置 3.1.属性配置 3.2.控制层 3.3.服务层 四.验证 4.1.请求生成项目 4.2.生成项目结果 4.3.项目结构 一 ...

最新文章

  1. myeclipse 6.0 弹出 Multiple Errors have Occurred 错误
  2. 人脸识别有哪些利与弊
  3. python3.6小程序_python3.6 tkinter实现屏保小程序
  4. Spring IOC (DI-依赖注入)
  5. 没有外层实列可以访问_这糕点外层香酥,内馅香甜可口,让人吃一次就爱上了,做起来...
  6. java接口有非抽象方法_如果一个类没有实现Java接口的所有抽象方法,会发生什么?...
  7. Android之数据库操作
  8. (操作系统题目题型总结)第四章:存储管理
  9. 百度、阿里等大厂面试技巧总结,Java工程师必看!
  10. thrift (转)
  11. STM32 电机教程 13 - BLDC 电机转速计算
  12. 量化交易策略研发的三个层次
  13. ug12无法连接服务器系统,NX许可证错误:无法连接至许可证服务器系统。SPLM_LICENSE_SERVER错误[-15]...
  14. Aurix 多核链接文件 lsl --- 上篇
  15. uniapp结合萤石视频ezuikit.js的爬坑记录
  16. Linux挂载Windows共享文件夹
  17. 华三 h3c isis协议综合配置
  18. CSS Display与Visibility区别和用法
  19. 使用ajax从服务器端获取数据
  20. 【谷歌地图--DirectionsSDK集成】

热门文章

  1. 如何开启win10内置Linux子程序
  2. 小米云能同步到华为手机上吗_有没有小米还没涉足的产业?对标百度网盘,小米云盘即将上线...
  3. R语言使用party包中的ctree函数构建条件推理决策树的流程和步骤、条件推理决策树是传统决策树的一个重要变体、条件推理树的分裂是基于显著性测试而不是熵/纯度/同质性度量来选择分裂
  4. R语言ggplot2可视化强制所有的X数值都显示在X轴标签上:x-axis labels with all x-axis values
  5. R语言ggplot2可视化在X轴上可视化时间标签实战:可视化时间标签、对时间标签进行旋转
  6. R语言二项分布函数Binomial Distribution(dbinom, pbinom, qbinom rbinom)实战
  7. R假设检验之Mann-Kendall趋势检验法(Mann-Kendall Trend Test)
  8. Python代码发现链表中的环并输出环中的第一个元素
  9. 浙大Java延毕_复旦博导:我有个“拼命三郎”似的博士生,却也面临延毕,做科研得有章法!......
  10. ML基石_LinearModelsForClassfication