本篇主要讲述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. C++关于栈对象返回的问题

    本次实验环境 环境1:Win10, QT 5.12 环境2:Centos7,g++ 4.8.5 一. 主要结论 可以返回栈上的对象(各平台会有不同的优化),不可以返回栈对象的引用. 二.先看看函数传参 ...

  2. SSH框架使用AOP代理+自定义注解遇到的相关问题总结

    1.AOP注解失效问题 编写完成注解和AOP切面类时,在controller中加上注解,注解不生效.在配置文件xml中开启AOP注解: <aop:aspectj-autoproxy proxy- ...

  3. KingbaseES 使用百分比函数获取中位数

    客户从Oracle数据库迁移至KingbaseES数据库,应用中使用MEDIAN函数来求中位数.KingbaseES数据库中没有MEDIAN函数,但可以通过百分比函数来实现相应的功能. MEDIAN ...

  4. 双向循环链表(DoubleLoopLinkList)

    双向循环链表 关于双向循环链表可以先阅读这篇文章这里就不再赘述:双向链表(DoubleLinkList) Node template<typename T> class Node { pu ...

  5. 3D Object Detection Essay Reading 2024.04.01

    Swin Transformer paper: https://arxiv.org/abs/2103.14030 (ICCV 2021) code:https://github.com/microso ...

  6. 19 JavaScript的hook

    19 JavaScript的hook 什么叫hook? Hook技术又叫钩子函数,在系统没有调用该函数之前,钩子程序就捕获该消息,钩子函数先得到该函数的控制权,这时钩子函数既可以改变该函数的执行行为, ...

  7. MCM箱模型建模方法及大气O3来源解析

    OBM箱模型可用于模拟光化学污染的发生.演变过程,研究臭氧的生成机制和进行敏感性分析,探讨前体物的排放对光化学污染的影响.箱模型通常由化学机理.物理过程.初始条件.输入和输出模块构成,化学机理是其核心 ...

  8. GPT-3的训练一次成本约为140万美元

    训练GPT模型的成本非常高昂,因为它需要大量的计算资源和时间.具体来说,GPT-3的训练成本约为140万美元,对于一些更大的LLM模型,训练成本介于200万美元至1200万美元之间.此外,OpenAI ...

  9. wireshark 抓包整理———— 从一个小案例开始 [一]

    前言 前面已经有抓包系列了,简单写一下wireshark的抓包系列,共36节,18个理论小栗子,36个实战栗子. 正文 这个例子是<<wireshark 分析就这么简单>>的一 ...

  10. 痞子衡嵌入式:在i.MXRT1xxx系列上用NAND型启动设备时可用两级设计缩短启动时间

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在i.MXRT1xxx系列上用NAND型启动设备时可用两级设计缩短启动时间. 去年痞子衡写过一篇骚操作文章 <借助i.MXRT10 ...