Jenkins+Harbor+gogs+docker+portainer+springboot实现devOps(企业实战)
本篇主要讲述springboot以及vue前后端分离项目,使用Jenkins拉取gogs代码仓库源码,构建Docker镜像并推送至Harbor仓库,使用docker 可视化部署工具【portainer】部署生产服项目,编写shell脚本,至于jenkins、harbor、gogs、portainer 请自行安装部署,网上教程较多,比较简单
1、springboot 前后端分离项目,借用jenkins持续集成持续部署工具,使用shell脚本将项目编写好dockerFile 文件,生成镜像,并推送至镜像仓库
#!/bin/sh # 镜像仓库地址,我这里使用harbor镜像仓库,当然也可以使用阿里云镜像仓库
REGISTRY=hub.ywb.com
# 镜像仓库登录账号
REGISTRY_USER=admin
# 镜像仓库登录密码
REGISTRY_PASS=123456 # 镜像TAG
IMAGE_TAG=$REGISTRY/security
# 镜像名称
IMAGE_NAME=tv-api
# 镜像版本
IMAGE_VER=v2.2-$( date '+%Y%m%d' ).$BUILD_NUMBER # 构建项目名称
PROJECT_NAME=$JOB_NAME
# 构建项目的目录
PROJECT_DIR=$WORKSPACE
# 构建项目的编译目录
PROJECT_BUILD_DIR=$PROJECT_DIR/target
# 构建项目的服务访问端口
PROJECT_PORT=38101 # 当前日期
DATE=$( date '+%Y/%m/%d %H:%M:%S' )
# 返回值
RETVAL=0 echo "*******************************************************************************************" # 开始执行构建
echo "$DATE - 开始执行项目构建..." # 进入构建项目的编译目录
echo "$DATE - 进入项目构建目录 $PROJECT_BUILD_DIR"
cd $PROJECT_BUILD_DIR
# 获取编译后的 jar 包名称
JAR_NAME=$( ls | grep -i "jar" | grep -v grep | head -1 ) # 如果 JAR_NAME 为空
if [ -z "$JAR_NAME" ]; then
echo "$DATE - 未查询到项目 $PROJECT_NAME 编译的结果 $JAR_NAME"
exit $RETVAL
fi # 如果 JAR_NAME 不存在
if [ ! -f "$PROJECT_BUILD_DIR/$JAR_NAME" ]; then
echo "$DATE - 项目 $PROJECT_NAME 编译的文件 $JAR_NAME 不存在"
exit $RETVAL
fi echo "$DATE - 成功获取到项目 $PROJECT_NAME 的最终编译文件 $JAR_NAME" # 创建 Dockerfile
echo "$DATE - 创建 Dockerfile"
cat > Dockerfile <<EOF
FROM openjdk:8
MAINTAINER wanbin.yi@qq.com
# 在宿主机的 /var/lib/docker 目录下创建一个临时文件,并链接到容器的 /tmp,用于数据持久化,因为 springboot 内嵌 tomcat 默认使用 /tmp 作为工作目录
VOLUME /tmp
# 设置工作目录
WORKDIR /root
# 设置时区
RUN bash -c 'echo "Asia/Shanghai" > /etc/timezone'
# 添加 jar 包并检测
ADD $JAR_NAME /root/$JAR_NAME
RUN bash -c 'touch /root/$JAR_NAME'
# 设置 jvm 参数
ENV JAVA_OPTS="\
-server \
-Xms512m \
-Xmx2g \
-Xmn1g \
-XX:SurvivorRatio=8 \
-XX:MetaspaceSize=256m \
-XX:MaxMetaspaceSize=512m \
-XX:+UseParallelGC \
-XX:ParallelGCThreads=4 \
-XX:+UseParallelOldGC \
-XX:+UseAdaptiveSizePolicy \
-XX:+PrintGCDetails \
-XX:+PrintTenuringDistribution \
-XX:+PrintGCTimeStamps \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/ \
-Xloggc:/var/run/jvm-gc.log \
-XX:+UseGCLogFileRotation \
-XX:NumberOfGCLogFiles=5 \
-XX:GCLogFileSize=10M"
# 为了缩短 tomcat 启动时间,添加一个系统属性指向 “/dev/urandom” 作为 Entropy Source
ENTRYPOINT java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /root/$JAR_NAME
EXPOSE $PROJECT_PORT
EOF echo "$DATE - 创建 Dockerfile 完成" # 构建镜像
# 将镜像名转换为小写
IMAGE_NAME=$IMAGE_NAME | tr '[A-Z]' '[a-z]'
echo "$DATE - 开始构建镜像,镜像名称:$IMAGE_NAME:$IMAGE_VER" # 判断 docker 镜像中是否已存在,存在则删除之
IMAGE_ID=$( docker images | grep -i "$IMAGE_NAME" | grep -i "$IMAGE_VER" | grep -v grep | awk '{print $3}' | head -1 )
if [ ! -z "$IMAGE_ID" ]; then
echo "$DATE - 检测到镜像 $IMAGE_NAME:$IMAGE_VER 已存在,删除之..."
docker image rm -f $IMAGE_ID
fi docker build -t $IMAGE_NAME:$IMAGE_VER $PROJECT_BUILD_DIR
echo "$DATE - 构建镜像完成" # 推送镜像
echo "$DATE - 开始向镜像仓库推送"
docker tag $IMAGE_NAME:$IMAGE_VER $IMAGE_TAG/$IMAGE_NAME:$IMAGE_VER
docker login -u $REGISTRY_USER -p $REGISTRY_PASS $REGISTRY
docker push $IMAGE_TAG/$IMAGE_NAME:$IMAGE_VER
echo "$DATE - 向镜像仓库推送完成,请前往镜像仓库查看:http://$REGISTRY" echo "$DATE - 执行项目构建完成..." echo "*******************************************************************************************"
2、vue前端项目,同理使用jenkins生成镜像文件,并推送至镜像仓库
#!/bin/sh # 镜像仓库地址
REGISTRY=hub.ywb.com
# 镜像仓库登录账号
REGISTRY_USER=dev
# 镜像仓库登录密码
REGISTRY_PASS=123456 # 镜像TAG
IMAGE_TAG=$REGISTRY/demo
# 镜像名称
IMAGE_NAME=pms-web
# 镜像版本
IMAGE_VER=v2.2-$( date '+%Y%m%d' ).$BUILD_NUMBER # 构建项目名称
PROJECT_NAME=$JOB_NAME
# 构建项目的目录
PROJECT_DIR=$WORKSPACE
# 构建项目的最终编译目录
PROJECT_BUILD_DIR=dist
# 构建项目的正式脚本环境定义
PROJECT_PROFILE=prod # npm 指令
NPM=npm # 当前日期
DATE=$( date '+%Y/%m/%d %H:%M:%S' )
# 返回值
RETVAL=0 echo "*******************************************************************************************" # 开始执行构建
echo "$DATE - 开始执行项目构建..." # 进入构建项目的构建目录
cd $PROJECT_DIR
echo "$DATE - 进入项目构建目录 $PROJECT_DIR" # 检测是否有 npm 运行环境
echo "$DATE - 检测主机是否安装 $NPM 运行环境"
type $NPM > /dev/null
if [ $? -eq 0 ]; then
echo "$DATE - 当前主机存在 $NPM 运行环境,$NPM 版本:$( $NPM -v )"
else
echo "$DATE - 主机未安装 $NPM 编译环境,无法完成项目构建"
exit -1
fi # 执行 npm 初始化,根据项目的 package.json 安装依赖环境
echo "$DATE - 执行 $NPM 初始化,检测并安装项目依赖包,可能需要花费几分种时间,请耐心等待"
$NPM install
echo "$DATE - 完成 $NPM 初始化" # 执行 npm build,编译最终部署文件
echo "$DATE - 开始执行 $NPM 项目编译"
$NPM run build:$PROJECT_PROFILE
echo "$DATE - 完成 $NPM 项目编译,最终输出目录为:$PROJECT_DIR/$PROJECT_BUILD_DIR" # 检测项目编译后的目录是否存在
if [ ! -d $PROJECT_BUILD_DIR ]; then
echo "$DATE - 项目编译失败,未成功检测到最终编译目录:$PROJECT_DIR/$PROJECT_BUILD_DIR"
exit -1
fi echo "$DATE - 成功获取到项目 $PROJECT_NAME 的最终编译目录:$PROJECT_DIR/$PROJECT_BUILD_DIR" # 创建 nginx.conf
echo "$DATE - 创建 nginx 配置文件 nginx.conf,并计划用此文件替换 nginx 镜像中的 nginx.conf 文件"
cat > nginx.conf <<EOF
# 运行用户,可不设置
user nginx;
# 可开启进程数量,一般设置为和cpu核数一样
worker_processes 2;
# 日志路径和级别。这个设置可以放入全局块,http块,server块,级别依次为:debug|info|notice|warn|error|crit|alert|emerg
error_log /var/log/nginx/error.log;
pid /run/nginx.pid; # 最大文件打开数(连接),可设置为系统优化后的ulimit -HSn的结果
worker_rlimit_nofile 5120;
# cpu亲和力配置,让不同的进程使用不同的cpu
worker_cpu_affinity 01 10; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf; events {
# 网路连接序列化,防止惊群现象发生,默认为on
accept_mutex on;
# 一个进程是否同时接受多个网络连接,默认为off
multi_accept off;
# 事件驱动模型, select|poll|kqueue|epoll|resig|/dev/poll|eventport
# epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能
use epoll;
# 单个后台worker process进程的最大并发链接数
worker_connections 1024;
} http {
log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
'\$status \$body_bytes_sent "\$http_referer" '
'"\$http_user_agent" "\$http_x_forwarded_for"'; #access_log /var/log/nginx/access.log main;
access_log off; # 启用压缩
gzip on;
# 文件小于此大小不予压缩
gzip_min_length 1k;
gzip_buffers 4 16k;
# 压缩等级
gzip_comp_level 5;
# 压缩类型
gzip_types text/plain text/css text/javascript image/jpeg image/png image/bmp image/svg+xml font/ttf font/otf font/woff font/woff2 application/pdf application/xml application/json application/x-javascript application/x-httpd-php;
gzip_vary on;
gzip_static on; # 开启高效传输模式,默认为off,可以在http块,server块,location块
sendfile on;
# 每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限
sendfile_max_chunk 16k; # 读取客户端请求头缓冲大小
client_header_buffer_size 1k;
# 读取客户端请求体缓冲大小
client_body_buffer_size 16k;
# 客户端允许上传文件的最大值
client_max_body_size 256m; # 允许把httpresponse header和文件的开始放在一个文件里发布,作用是减少网络报文段的数量
tcp_nopush on;
# 内核会等待将更多的字节组成一个数据包,从而提高I/O性能
tcp_nodelay on; # 连接超时时间,默认为75s,可以在http,server,location块
keepalive_timeout 65; include /etc/nginx/mime.types;
default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf; server {
listen 80;
#listen [::]:80;
server_name localhost; charset utf-8; # Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf; location / {
root /usr/share/nginx/html/pc;
index index.htm index.html default.htm default.html;
autoindex on;
} error_page 404 /404.html;
location = /40x.html {
} error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
} }
EOF echo "$DATE - 创建 nginx.conf 完成" # 创建 Dockerfile
echo "$DATE - 创建 Dockerfile"
cat > Dockerfile <<EOF
FROM nginx
MAINTAINER wanbin.yw@qq.com
COPY nginx.conf /etc/nginx/nginx.conf
COPY $PROJECT_BUILD_DIR/ /usr/share/nginx/html/pc
EOF echo "$DATE - 创建 Dockerfile 完成" # 构建镜像
# 将镜像名转换为小写
IMAGE_NAME=$IMAGE_NAME | tr '[A-Z]' '[a-z]'
echo "$DATE - 开始构建镜像,镜像名称:$IMAGE_NAME:$IMAGE_VER" # 判断 docker 镜像中是否已存在,存在则删除之
IMAGE_ID=$( docker images | grep -i "$IMAGE_NAME" | grep -i "$IMAGE_VER" | grep -v grep | awk '{print $3}' | head -1 )
if [ ! -z "$IMAGE_ID" ]; then
echo "$DATE - 检测到镜像 $IMAGE_NAME:$IMAGE_VER 已存在,删除之..."
docker image rm -f $IMAGE_ID
fi docker build -t $IMAGE_NAME:$IMAGE_VER $PROJECT_DIR
echo "$DATE - 构建镜像完成" # 推送镜像
echo "$DATE - 开始向镜像仓库推送"
docker tag $IMAGE_NAME:$IMAGE_VER $IMAGE_TAG/$IMAGE_NAME:$IMAGE_VER
docker login -u $REGISTRY_USER -p $REGISTRY_PASS $REGISTRY
docker push $IMAGE_TAG/$IMAGE_NAME:$IMAGE_VER
echo "$DATE - 向镜像仓库推送完成,请前往镜像仓库查看:http://$REGISTRY" echo "$DATE - 执行项目构建完成..." echo "*******************************************************************************************"
3、jenkins构建历史记录
4、最终可以使用docker portainer可视化工具进行项目部署工作,从harbor镜像仓库拉取镜像开始部署
Jenkins+Harbor+gogs+docker+portainer+springboot实现devOps(企业实战)的更多相关文章
- 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境
写在前面 最近在 K8S 1.18.2 版本的集群上搭建DevOps环境,期间遇到了各种坑.目前,搭建环境的过程中出现的各种坑均已被填平,特此记录,并分享给大家! 文章和搭建环境所需要的yml文件已收 ...
- 构建gitlab+Jenkins+harbor+kubernetes的DevOps持续集成持续部署环境
构建gitlab+Jenkins+harbor+kubernetes的DevOps持续集成持续部署环境 整个环境的结构图. 一.准备工作 gitlab和harbor我是安装在kubernetes集群外 ...
- Jenkins+Harbor+Docker发布
使用Jenkins发布Docke 需要准备的,docker,jenkins,Harbor docker安装 安装依赖: # yum install -y yum-utils device-mapper ...
- docker 运行jenkins及vue项目与springboot项目(三.jenkins的使用及自动打包vue项目)
docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...
- docker 运行jenkins及vue项目与springboot项目(一.安装docker)
docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...
- docker 运行jenkins及vue项目与springboot项目(二.docker运行jenkins为自动打包运行做准备)
docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...
- docker 运行jenkins及vue项目与springboot项目(四.docker运行nginx)
docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...
- docker 运行jenkins及vue项目与springboot项目(五.jenkins打包springboot服务且在docker中运行)
docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...
- GitLab + Jenkins + Harbor 工具链快速落地指南
目录 一.今天想干啥? 二.今天干点啥? 三.今天怎么干? 3.1.常规打法 3.2.不走寻常路 四.开干吧! 4.1.工具链部署 4.2.网络配置 4.3.验证工具链部署结果 4.3.1.GitLa ...
- Jenkins中执行docker命令报错
Cannot connect to the Docker daemon. Is the docker daemon running on this host? 在配置Jenkins从Gitlab自 ...
随机推荐
- 记录-使用双token实现无感刷新,前后端详细代码
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 近期写的一个项目使用双token实现无感刷新.最后做了一些总结,本文详细介绍了实现流程,前后端详细代码.前端使用了Vue3+Vite ...
- TorchV的RAG实践分享(二):基于ElasticSearch的混合检索实战&原理分析
概述 在昨天员外分享的<TorchV的RAG实践分享(1)--RAG的定位.技术选型和RAG技术文章目录>一文中介绍了TorchV的由来,也分享了我们的几个基线产品和应用架构的方向,我们想 ...
- clickhouse在各大厂商的应用
案例-ClickHouse在头条的技术演进
- VScode 配置私钥免密登录
VScode 配置私钥免密登录 配置公钥私钥进行免密登录在前文已经提及.在完成上述配置后,我们希望在VScode中配置,毕竟主要的开发环境还是在VScode上且连接到远程服务器会经常遇到网络不稳定需要 ...
- Nancy支持跨域请求
public class NancyBootstrapper : DefaultNancyBootstrapper { /// <summary> /// nancy配置 /// < ...
- HttpWebRequest GetResponse操作超时
request.GetResponse()超时问题的解决 解决办法 1.将http的request的keepAlive设置为false //如果不是必须的要keepalive的,那么就要设置Keep ...
- KingbaseES V8R6 流复制冲突分类以及对应解决方案
背景 据实施人员反馈发现如下报错: FATAL: terminating connection due to conflict with recovery DETAIL: User query mig ...
- GraphQl in ASP.NET Core
GraphQl in ASP.NET Core https://graphql.cn/ https://graphql-dotnet.github.io/docs/getting-started/ar ...
- C++设计模式 - 原型模式(Prototype)
对象创建模式 通过"对象创建" 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定.它是接口抽象之后的第一步工作. 典型模式 Fac ...
- SQL中使用年月日来进行分组
SQL按年月日进行分组 select count(project_name), create_at from table_a group by date_format(create_at, '%Y%m ...