本篇主要讲述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(企业实战)的更多相关文章

  1. 三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境

    写在前面 最近在 K8S 1.18.2 版本的集群上搭建DevOps环境,期间遇到了各种坑.目前,搭建环境的过程中出现的各种坑均已被填平,特此记录,并分享给大家! 文章和搭建环境所需要的yml文件已收 ...

  2. 构建gitlab+Jenkins+harbor+kubernetes的DevOps持续集成持续部署环境

    构建gitlab+Jenkins+harbor+kubernetes的DevOps持续集成持续部署环境 整个环境的结构图. 一.准备工作 gitlab和harbor我是安装在kubernetes集群外 ...

  3. Jenkins+Harbor+Docker发布

    使用Jenkins发布Docke 需要准备的,docker,jenkins,Harbor docker安装 安装依赖: # yum install -y yum-utils device-mapper ...

  4. docker 运行jenkins及vue项目与springboot项目(三.jenkins的使用及自动打包vue项目)

    docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...

  5. docker 运行jenkins及vue项目与springboot项目(一.安装docker)

    docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...

  6. docker 运行jenkins及vue项目与springboot项目(二.docker运行jenkins为自动打包运行做准备)

    docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...

  7. docker 运行jenkins及vue项目与springboot项目(四.docker运行nginx)

    docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...

  8. docker 运行jenkins及vue项目与springboot项目(五.jenkins打包springboot服务且在docker中运行)

    docker 运行jenkins及vue项目与springboot项目: 一.安装docker 二.docker运行jenkins为自动打包运行做准备 三.jenkins的使用及自动打包vue项目 四 ...

  9. GitLab + Jenkins + Harbor 工具链快速落地指南

    目录 一.今天想干啥? 二.今天干点啥? 三.今天怎么干? 3.1.常规打法 3.2.不走寻常路 四.开干吧! 4.1.工具链部署 4.2.网络配置 4.3.验证工具链部署结果 4.3.1.GitLa ...

  10. Jenkins中执行docker命令报错

    Cannot connect to the Docker daemon. Is the docker daemon running on this host?   在配置Jenkins从Gitlab自 ...

随机推荐

  1. uni-app如何实现USB插入后自动弹出对应软件

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 最近碰到了一个奇葩需求,要用uni-app来实现usb接入设备的时候,让软件自动弹出来,这里给出我制作的过程和参考的各种思路,希望对大家有 ...

  2. C++正则表达式 <regex>

    一 简介 概括而言,使用正则表达式处理字符串的流程包括: 用正则表达式定义要匹配的字符串的规则, 然后对目标字符串进行匹配, 最后对匹配到的结果进行操作. C++ 的 regex 库提供了用于表示正则 ...

  3. Loto实践干货(9) 示波器测 晶振

    我们用LOTO示波器的多个型号,带宽从20M到100M,分别测无源和有源晶振的情况.分别测试了12M,15M,24M,48M,80M晶振的波形.并分析了为什么我们经常测出晶振波形不是方波?为什么有时候 ...

  4. KingbaseES V8R6集群运维案例之---sys_monitor.sh start启动动态库错误

    案例说明: 在KingbaseES V8R6集群部署了postgis后,执行sys_monitor.sh start启动集群时,出现动态库错误,如下图所示: 适用版本: KingbaseES V8R6 ...

  5. .net 发邮件的小工具,包含json,环境变量,命令行参数三种配置方式

    一.业务需求 在工作中遇到一个场景,软件bug或功能发布之后,会通知测试进行测试,要求写一个小工具能自动发送邮件,功能包含发送和抄送支持多个,因为只是通知没有写进附件功能,这个其他博客都有搜一下就可以 ...

  6. 10 CSS边框属性

    10 CSS边框属性 border-style(边框风格) 定义边框的风格,值可以有: /* none:没有边框,当border的值为none的时候,系统将会忽略[border-color] hidd ...

  7. C# 方法详解:定义、调用、参数、默认值、返回值、命名参数、方法重载全解析

    C# Methods 方法是一段代码,只有在调用时才会运行. 您可以将数据(称为参数)传递给方法. 方法用于执行某些操作,也被称为函数. 为什么使用方法?为了重用代码:定义一次代码,然后多次使用. 创 ...

  8. Python 布尔类型

    布尔值表示两个值之一:True(真)或False(假). 布尔值 在编程中,您经常需要知道一个表达式是否为True或False. 您可以在Python中评估任何表达式,并获得两个答案之一:True或F ...

  9. Openstack之工作流程

    组件 OpenStack的核心部件即包括Nova(用于计算).Keystone(用于身份服务).Neutron(用于网络和地址管理).Cinder(块存储).Swift(对象存储).Glance(镜像 ...

  10. Pytorch-卷积神经网络CNN之ResNet的Pytorch代码实现

    先说一个小知识,助于理解代码中各个层之间维度是怎么变换的. 卷积函数:一般只用来改变输入数据的维度,例如3维到16维. Conv2d() Conv2d(in_channels:int,out_chan ...