22、Jenkins容器化部署Java应用

22、Jenkins容器化部署Java应用

1、准备Dockerfile

将Dockerfile文件放入项目目录下

dockerfile 复制代码
FROM registry.cn-hangzhou.aliyuncs.com/xx_blog/openjdk:21-jdk
LABEL maintainer="xx@qq.com"
#复制打好的jar包
COPY target/*.jar /app.jar
RUN  apk add -U tzdata; \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime; \
echo 'Asia/Shanghai' >/etc/timezone; \
touch /app.jar;

ENV JAVA_OPTS=""
ENV PARAMS=""

EXPOSE 8001

ENTRYPOINT [ "sh", "-c", "java -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar /app.jar $PARAMS" ]

这里加了个target,因为maven打完包之后jar包在target目录下

2、新建流水线工程

xx-springboot-docker

3、执行脚本修改一下

sh 复制代码
docker -v
pwd
ls
# 查看当前用户是谁
whoami

docker build -t xx-springboot:v1 .

会报没有权限的错误,默认情况下jenkins用户是没有权限操作docker的

sh 复制代码
# 以管理员权限,将系统中的 jenkins 用户追加加入到 docker 用户组,从而让 jenkins 用户具备执行 Docker 命令(访问 Docker daemon)的权限。
sudo usermod -aG docker jenkins

4、构建一次

5、修改版本号

sh 复制代码
docker -v
pwd
ls
# 查看当前用户是谁
whoami

docker build -t xx-springboot:v${BUILD_NUMBER} .

6、启动项目

sh 复制代码
docker build -t xx-springboot:v${BUILD_NUMBER} .

docker run -d --name=xx-springboot -p 8001:8001 xx-springboot:v${BUILD_NUMBER}

7、再构建一次

因为不能启动相同容器名的容器,所以要先删除原来的容器

sh 复制代码
docker build -t xx-springboot:v${BUILD_NUMBER} .

docker stop xx-springboot

docker rm xx-springboot

docker run -d --name=xx-springboot -p 8001:8001 xx-springboot:v${BUILD_NUMBER}

8、停止容器问题

我们手动把容器删掉

sh 复制代码
# 在没有容器的情况下会报错,所以要是没有正在运行的xx-springboot容器会报错
docker stop xx-springboot

所以我们要判断是否有启动的同名容器

9、删除镜像容器通用脚本

由于判断脚本很多 为了方便维护 我们抽取成一个通用文件 放入项目根目录

sh 复制代码
#! /bin/sh
#镜像名称
imageName=$1
build_number=$2

containerStr=`docker ps -a | grep -w ${imageName} | awk '{print $1}'`
imageStr=`docker images | grep -w $imageName  | awk '{print $3}'`
echo "container id:$containerStr"
echo "image id:$imageStr"

if [ "$imageStr" !=  "" ] ; then
  if [ "$containerStr" !=  "" ] ; then
    #停掉容器
    docker stop `docker ps -a | grep -w ${imageName}  | awk '{print $1}'`

    #删除容器
    docker rm `docker ps -a | grep -w ${imageName}  | awk '{print $1}'`

    #删除镜像
    docker rmi -f $(docker images | grep $imageName | grep -v v$build_number | awk '{print $3}')
  else
     #删除镜像
    docker rmi -f $(docker images | grep $imageName | grep -v v$build_number | awk '{print $3}')
  fi
fi
sh 复制代码
#! /bin/sh
# 镜像名称,从脚本参数第1个传入
imageName=$1
# 构建版本号,从脚本参数第2个传入
build_number=$2

# 查找所有容器(包括停止的),名字中完全匹配镜像名的容器ID(第一列)
containerStr=`docker ps -a | grep -w ${imageName} | awk '{print $1}'`
# 查找镜像列表中名字完全匹配的镜像ID(第三列)
imageStr=`docker images | grep -w $imageName  | awk '{print $3}'`

echo "container id:$containerStr"
echo "image id:$imageStr"

# 判断是否存在镜像ID(即镜像是否存在)
if [ "$imageStr" !=  "" ] ; then
  # 判断是否存在对应容器
  if [ "$containerStr" !=  "" ] ; then
    # 如果存在容器,先停止这些容器
    docker stop `docker ps -a | grep -w ${imageName}  | awk '{print $1}'`

    # 停止后删除这些容器
    docker rm `docker ps -a | grep -w ${imageName}  | awk '{print $1}'`

    # 删除镜像,排除当前build_number版本的镜像(v开头的标签)
    docker rmi -f $(docker images | grep $imageName | grep -v v$build_number | awk '{print $3}')
  else
    # 如果没有容器,则直接删除所有除了当前build_number版本以外的镜像
    docker rmi -f $(docker images | grep $imageName | grep -v v$build_number | awk '{print $3}')
  fi
fi

10、改进部署脚本

sh 复制代码
chmod 777 stop_container.sh && bash stop_container.sh xx-springboot $BUILD_NUMBER

docker build -t xx-springboot:v${BUILD_NUMBER} .

docker run -d --name=xx-springboot -p 8001:8001 xx-springboot:v${BUILD_NUMBER}

11、上传镜像到镜像仓库

sh 复制代码
chmod 777 stop_container.sh && bash stop_container.sh xx-springboot $BUILD_NUMBER

docker build -t xx-springboot:v${BUILD_NUMBER} .

docker tag xx-springboot:v${BUILD_NUMBER} 112.74.160.27:8081/xx-blog/xx-springboot:v${BUILD_NUMBER}
echo "Harbor12345" | docker login 112.74.160.27:8081 -u "admin" --password-stdin
docker push 112.74.160.27:8081/xx-blog/xx-springboot:v${BUILD_NUMBER}

docker run -d --name=xx-springboot -p 8001:8001 xx-springboot:v${BUILD_NUMBER}

12、最终脚本抽取变量

sh 复制代码
SERVER_NAME=xx-springboot

chmod 777 stop_container.sh && bash stop_container.sh ${SERVER_NAME} $BUILD_NUMBER

docker build -t ${SERVER_NAME}:v${BUILD_NUMBER} .

docker tag ${SERVER_NAME}:v${BUILD_NUMBER} 112.74.160.27:8081/xx-blog/${SERVER_NAME}:v${BUILD_NUMBER}
echo "Harbor12345" | docker login 112.74.160.27:8081 -u "admin" --password-stdin
docker push 112.74.160.27:8081/xx-blog/${SERVER_NAME}:v${BUILD_NUMBER}

docker run -d --name=${SERVER_NAME} -p 8001:8001 ${SERVER_NAME}:v${BUILD_NUMBER}
相关推荐
杨云龙UP5 分钟前
Oracle 19c RAC到RAC Active Data Guard标准搭建与巡检指南
运维·服务器·数据库·oracle·adg·data guard·rac到rac
Mikko77 分钟前
JVM 线上排查实战(七):jps 看不到进程、jstack 报不允许的操作怎么办?attach 失败的六种情况实测
java·运维·jvm·后端
jianjinwssy8 分钟前
MyBatis-Plus 从入门到实战:常用功能与核心原理
java·mybatis
会编程的吕洞宾16 分钟前
Spring AI 2.0 会话记忆实战,让 AI 助手记住每一次对话
java·人工智能·spring
小宋102120 分钟前
Agent 工具升级如何不破坏线上:Tool Schema 版本兼容与契约测试
java·人工智能·后端·spring
都适、隶仁ミ22 分钟前
【等保加固】MySQL5.7.38
运维·服务器·mysql·安全·等保
汤米粥23 分钟前
后端开发主流技术方案
java·python·golang·php·nodejs·后端开发
Helix25028 分钟前
2026编程入门指南:零基础如何科学选择第一门编程语言?
java·c语言·javascript·零基础·编程语言·python入门·编程就业
EatFan29 分钟前
2026 后端 AI 集成三条落地路径:Spring AI 2.0、MCP 协议与旁路服务怎么选
java·人工智能·spring boot·spring·大模型·spring ai·mcp
SimonKing29 分钟前
QClaw关停之后:一个工具的退场,一段关系的告别
java·后端·程序员