22、Jenkins容器化部署Java應用
1、準備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 8001ENTRYPOINT [ "sh", "-c", "java -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar /app.jar $PARAMS" ]
這里加了個target
,因為maven打完包之后jar包在target目錄下
2、新建流水線工程
xx-springboot-docker
3、執行腳本修改一下
docker -v
pwd
ls
# 查看當前用戶是誰
whoamidocker build -t xx-springboot:v1 .
會報沒有權限的錯誤,默認情況下jenkins用戶是沒有權限操作docker的
# 以管理員權限,將系統中的 jenkins 用戶追加加入到 docker 用戶組,從而讓 jenkins 用戶具備執行 Docker 命令(訪問 Docker daemon)的權限。
sudo usermod -aG docker jenkins
4、構建一次
5、修改版本號
docker -v
pwd
ls
# 查看當前用戶是誰
whoamidocker build -t xx-springboot:v${BUILD_NUMBER} .
6、啟動項目
docker build -t xx-springboot:v${BUILD_NUMBER} .docker run -d --name=xx-springboot -p 8001:8001 xx-springboot:v${BUILD_NUMBER}
7、再構建一次
因為不能啟動相同容器名的容器,所以要先刪除原來的容器
docker build -t xx-springboot:v${BUILD_NUMBER} .docker stop xx-springbootdocker rm xx-springbootdocker run -d --name=xx-springboot -p 8001:8001 xx-springboot:v${BUILD_NUMBER}
8、停止容器問題
我們手動把容器刪掉
# 在沒有容器的情況下會報錯,所以要是沒有正在運行的xx-springboot容器會報錯
docker stop xx-springboot
所以我們要判斷是否有啟動的同名容器
9、刪除鏡像容器通用腳本
由于判斷腳本很多 為了方便維護 我們抽取成一個通用文件 放入項目根目錄
#! /bin/sh
#鏡像名稱
imageName=$1
build_number=$2containerStr=`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" != "" ] ; thenif [ "$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
#! /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、改進部署腳本
chmod 777 stop_container.sh && bash stop_container.sh xx-springboot $BUILD_NUMBERdocker build -t xx-springboot:v${BUILD_NUMBER} .docker run -d --name=xx-springboot -p 8001:8001 xx-springboot:v${BUILD_NUMBER}
11、上傳鏡像到鏡像倉庫
chmod 777 stop_container.sh && bash stop_container.sh xx-springboot $BUILD_NUMBERdocker 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、最終腳本抽取變量
SERVER_NAME=xx-springbootchmod 777 stop_container.sh && bash stop_container.sh ${SERVER_NAME} $BUILD_NUMBERdocker 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}