Jenkins 发布 普通jar包、Dockerfile、docker-compose.yml方式的项目
一:使用docker 安装Jenkins
1. 命令:docker run -u root -d --name jenkins --privileged=true -v /opt/jenkins/home:/var/jenkins_home -v /opt/maven:/opt/maven -p8080:8080 -p50000:50000 jenkins/jenkins
2. 登录Jenkins : http://ip:8080 登录后的初始化密码通过查询Jenkins的启动日志可以看到,docker ps 查询容器Id ,docker logs 容器Id查询容器的日志
3. 安装maven,由于启动命令对主机和容器进行挂载卷:/opt/maven的映射,所以,只需要将maven安装包上传到主机这个文件即可
进入容器同样的路径:
在容器中配置maven的环境变量
vim /etc/profile 编辑系统配置文件将这些写入配置文件中
export MAVEN_HOME=/opt/maven/apache-maven-3.9.2
export PATH=$MAVEN_HOME/bin:$PATH
保存后,执行 source /etc/profile
最后验证 mvn --version
如果没有vim或者没有vi命令,可以使用docker cp命令,将容器中的/etc/profile文件拷贝的主机,在主机中修改后再拷贝进去容器
4. jdk的安装:由于jenkins是java写的,因此容器自带jdk环境,使用echo "${JAVA_HOMe}" 可以看到
5. git :jenkins也自带了git 使用 which git
二、插件安装:
1.登录jenkins后选择推荐插件安装,全部安装完成后,再在插件工具中安装上 Publish Over SSH 和 Maven Integration
三、配置 jdk、git、maven 在全局配置那里配置上他们的环境变量
四:系统配置
1. 配置ssh服务器信息,也就是将来项目要发布到哪一台机器
注意:这里的 Remote Directory 不填的话,默认是登录ssh这个用户的家目录,例如我这个用户是vagrant,那么目录默认就是/home/vagrant
发布到这个服务器的jar包都会放到/home/vagrant下;如果填了路径,如/app,则会将jar推送到这个目录,如果这个目录不是由vagrant用户创建,并且vagrant用户没有写权限,推送jar到这个服务器就会报错:
当这里填了指定目录如/app则必须事先在linux创建这个目录才行
五、配置一个maven项目
1.新建项目,选择maven创建
2. 进入后,源码管理那里,输入你的代码仓库地址
测试: 点击构建,然后查询控制台输出:
从结果看,第一步已经成功,之后我们要发送到远程服务器
3. 将jar包推送到远程服务器,
先在远程服务器创建好目录,并且授权给当前的登录用户,如我想将jar包推送到远程服务器的 /app/demo文件夹下,则使用 sudo chmod -R 777 app给当前用户授予权限,我这里为了方便授予了所有权限
在家目录也就是/home/vagrant下创建启动文件:
#!/bin/bash echo "开始发包" nohup java -jar /app/demo/demo_mybatis-*-SNAPSHOT.jar & echo "发包成功"
记得要加上&,表示在后台运行,不然项目一直在前台运行,jenkins会报超时异常:
最后在jenkins配置上执行shell命令即可
问题:当我再次发包时,之前的java进程还在,端口就被占用了,发包就不会成功,另外,如果后续因为jar包的版本变化了,那么在远程服务器就会存在多个不同版本的jar包,启动就会有问题,因此
我们在jar包推送到远程服务器前,需要先对远程服务器执行清除jar包和停止java 进程的shell脚本:在远程服务器家目录创建demo_clean.sh,我的是在/home/vagrant目录下创建:
#!/bin/bash #删除旧的jar包 rm -rf /app/demo/demo_mybatis*.jar #判断就的java进程是否存在,存在则kill掉 isServerExist=`ps -ef|grep java |grep -v "grep"| grep demo_mybatis | wc -l` if [ "$isServerExist" = "0" ]; then echo "my_server not found" # exit; elif [ "$isServerExist" = "1" ]; then pid=`ps -ef|grep java |grep -v "grep"| grep demo_mybatis | awk '{print $2}'` kill $pid fi
当远程执行shell脚本时,虽然shell脚本执行成功,但jenkins依然报超时,此时解决方法如下:
六、基于Dockerfile的项目配置
1.新建一个文件夹 /app/demo_sit,用来接收jenkins传过来的jar包
2..在远程服务器家目录下,创建一个sit目录,然后分别创建Dockerfile文件、sit_clean.sh、si_start.sh文件
Dockerfile:
FROM centos MAINTAINER yangxiaohui #创建java 环境 RUN mkdir /usr/java RUN mkdir /usr/logs #拷贝jdk文件 Add是就解压的 ADD jdk-8u251-linux-x64.tar.gz /usr/java/ #设置jdk的环境变量 ENV JAVA_HOME /usr/java/jdk1.8.0_251 ENV CLASSPATH $JAVA_HOME/lib/ ENV PATH $JAVA_HOME/bin:$PATH # 设置登录后的落脚点 WORKDIR /temp #拷贝 jar包 COPY demo_mybatis.jar /temp/mybatis.jar #设置docker的时区为东八区 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone #暴露端口 EXPOSE 8085 # 启动java项目 CMD nohup java -jar mybatis.jar -Xms100m -Xmx300m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/logs/heap.hprof --spring.profiles.active=sit
sit_clean.sh:
#!/bin/bash
#执行命令是在用户的家目录,所以要进入下一级sit 清除已存在的docker容器和docker镜像 cd sit echo "docker clean">docker_clean.txt rm -f demo*.jar #删除容器 isServerExist=`sudo docker ps |grep my_shop |grep -v "grep"| wc -l` if [ "$isServerExist" = "0" ]; then echo "my_server not found" # exit; elif [ "$isServerExist" = "1" ]; then containerId=`sudo docker ps |grep my_shop |grep -v "grep"| awk '{print $1}'` sudo docker rm -f $containerId fi #删除镜像 isImagesExist=`sudo docker images |grep my_shop |grep -v "grep"| wc -l` if [ "$isImagesExist" = "0" ]; then echo "my_server not found" # exit; elif [ "$isImagesExist" = "1" ]; then imagesId=`sudo docker images |grep my_shop |grep -v "grep"| awk '{print $3}'` sudo docker rmi -f $imagesId fi #清除标签名为none的虚悬镜像 sudo docker image prune -f
si_start.sh:
#!/bin/bash
#由于执行shell脚本时是在家目录,因此要进入下一级 cd sit echo "开始打包镜像">hass.tx rm -rf demo_mybatis.jar
#要将其他目录的jar包拷贝到当前目录,Dockerfile的copy命令没法拷贝其他目录的jar只能拷贝当前目录 mv /app/demo_sit/demo_mybatis-*-SNAPSHOT.jar ./demo_mybatis.jar sudo docker build -t my_shop:5.0 . sudo docker run --name my_shop_sit -p8085:8085 -d my_shop:5.0 echo "启动完毕">success.txt
3.我们在jenkins中新建一个maven项目,然后配置好:
七:基于docker-composeyml部署的项目,如我的项目使用mysql+redis
1. 在远程服务器创建一个文件夹来接收jar包 /app/demo_beta
2. 在家目录下创建一个目录 beta,在该目录下,放入:beta_clean.sh (清除历史容器和镜像)beta_start.sh (项目启动脚本) docker-compose.yml Dockerfile jdk-8u251-linux-x64.tar.gz
如:
Dockerfile:
FROM centos MAINTAINER yangxiaohui #创建java 环境 RUN mkdir /usr/java RUN mkdir /usr/logs #拷贝jdk文件 Add是就解压的 Run echo "`pwd`" ADD jdk-8u251-linux-x64.tar.gz /usr/java/ #设置jdk的环境变量 ENV JAVA_HOME /usr/java/jdk1.8.0_251 ENV CLASSPATH $JAVA_HOME/lib/ ENV PATH $JAVA_HOME/bin:$PATH # 设置登录后的落脚点 WORKDIR /temp #拷贝 jar包 COPY demo_mybatis.jar /temp/mybatis.jar #设置docker的时区为东八区 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone #暴露端口 EXPOSE 8086 # 启动java项目 后面千万别加&符号,不然启动机会立刻退出 CMD nohup java -jar mybatis.jar -Xms100m -Xmx300m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/logs/heap.hprof --spring.profiles.active=beta
docker-compose.yml:
version: "3" services: shop: image: shop:2.0 build: dockerfile: Dockerfile context: . ports: - "8086:8086" container_name: shop depends_on: - mysql_test - redis_test networks: - my_network mysql_test: image: mysql:5.7 ports: - "3306:3306" container_name: mysql_test privileged: true volumes: - "/mydata/mysql/log:/var/log/mysql" - "/mydata/mysql/data:/var/lib/mysql" - "/mydata/mysql/conf:/etc/mysql/conf.d" environment: MYSQL_ROOT_PASSWORD: root command: --default-authentication-plugin=mysql_native_password networks: - my_network redis_test: image: redis:6.2 ports: - "6379:6379" container_name: redis_test privileged: true volumes: - "/redis/redis.conf:/etc/redis/redis.conf" - "/redis/data:/data" command: redis-server /etc/redis/redis.conf --requirepass 666666 networks: - my_network networks: my_network:
beta_clean.sh :
#!/bin/bash cd beta rm -rf demo_mybatis.jar rm -rf /app/demo_beta/*.jar #删除相关容器 sudo docker-compose down #删除相关镜像 #找出docker-compose.yml 文件中的 镜像名称 sudo grep -ai 'image' docker-compose.yml| awk '{ gsub (" ", "", $0);sub(/:/,"|");sub(/\r$/,""); print}' > tmp.1.txt #找出所有镜像名称 sudo docker images|grep -v IMAGE|awk '{print $1":"$2"|"$3}' > tmp.3.txt #通过两个临时文件找出docker-compose.yml 文件中的镜像名称对应的镜像ID awk -F'|' 'NR==FNR{a[$2]=$0}NR>FNR&&a[b=$1]{print $0, a[b]}' tmp.1.txt tmp.3.txt|awk -F'|' '{print $2}'|awk '{print $1}' > result.2.txt #根据ID删除镜像 sudo docker rmi $(cat result.2.txt) #删除所有使用的临时文件 sudo rm -rf result.2.txt tmp.3.txt tmp.1.txt echo "beta清除完成">beta_clean_success
beta_start.sh
#!/bin/bash echo "开始部署">kkk.txt cd beta mv /app/demo_beta/demo*.jar demo_mybatis.jar sudo docker-compose up -d echo "部署完毕">ttt.txt
在jenkins的配置如下: