最近在用jenkins为公司整一套开发环境的部署系统,项目是Java的,应用打出来的包有Jar包的形式,也有War包的形式,下面就分享下Jenkins下针对不同包的部署脚本。最近在折腾Docker,也会分享下Docker的部署脚本
Jenkins环境的搭建,这里就不多讲了,网上一大堆,建议不要用Docker的方式部署,里面集成Jdk,Maven,Git啥的比较麻烦,直接war包形式部署就行。部署Jenkins的机器建议内存大点,否则项目同时部署多几个时容易挂。
假设Jenkins所在机器为A
- Jar脚本部署应用机器与Jenkins机器为同一个机器A
- War脚本部署应用所在机器为B,war包通过ssh形式传递
- Docker应用部署也为jar启动,部署机器为B,jar包通过ssh形式传递(war包Docker部署脚本同理,只演示一种,大家融会贯通)
Jenkins脚本部署的流程
- 通过Git拉取指定分支代码
- clean package -Dmaven.test.skip=true -Pdev -U 通过maven编译打包代码,其中dev是我们开发环境的环境标识,测试环境对应qa,线上online,大家需自行修改
- 通过脚本(java -jar)启动对应jar包,或者丢到tomcat里启动,或者通过docker启动
通用配置
1、参数化构建-指定git分支,通过外部输入分支名,来指定要拉取的分支,default value为默认值
2、git配置
Url处输入你的项目的git地址
Credentials处点击右侧按钮能够添加 git的用户名/密码对
${branch} 表示拉取上面填入的git分支
3、maven build配置
-P后面环境参数请自己替换
clean package -Dmaven.test.skip=true -Prd -U
maven打包完后就需要执行启动shell脚本,下面分别介绍,不同启动方式对应的脚本文件,启动脚本xxx.sh需要放在项目启动的那台机器上
Jar脚本
由于我的Jar启动在和Jenkins一台机器上,所以直接执行脚本启动jar就行
在Post Steps中执行启动jar的启动脚本
命令如下,其中finalName为项目打包的包名,自己替换
port为项目启动端口号
这么做的目的是为了多个jar包启动的项目公用一个脚本
sh /opt/jar_deploy.sh finalName port
下面看下jar_deploy.sh
$1 参数对应包名,$2 参数对应端口号,path为项目jar包存放路径
java启动jvm参数可以自行更改,流程都有注释,不再多说
#!/bin/bash
app=$1
port=$2
path=/opt
echo this is app : $app
echo port : $port
#若项目已启动,杀死旧进程
api_pid=`ps -ef | grep "$app.jar" | grep -v grep | awk '{print $2}'`
echo api_pid = $api_pid
if [ "$api_pid" != "" ]; then
echo kill api
kill -9 $api_pid
echo sleep 3s
sleep 1
echo sleep 2s
sleep 1
echo sleep 1s
sleep 1
fi
#将jar包从jenkins工作空间中移动到指定路径下
mv /root/.jenkins/workspace/$app/$app-web/target/$app.jar $path/$app
cd $path/$app
#防止进程被杀死
BUILD_ID=dontKillMe
#后台进程形式启动项目
nohup java -jar -Dserver.port=$port -Xmx256m -Xms128m $app.jar &
echo $app start success
exit 0
War脚本
往往项目所部署机器与jenkins不在一台机器上
这里war包项目启动所在机器在B,所以相对A,多了一步ssh传输文件
war包的tomcat也用的不是一个,所在参数里多了个tomcat路径
先贴上除了分支之外的参数配置
贴上ssh传输文件配置
name就是目标机器ip地址
source files:标识war包所在相对路径,即相对jenkins工作空间/root/.jenkins/workspace/的路径
remove prefix:标识移除目录路径,只传输 xxx.war
remote directory:远程机器存放war的目录,我这存在/opt/war下
exec command:传输完成后执行的脚本,
具体执行命令如下
sh /opt/war_deploy.sh ${projectName} ${tomcat}
再贴上war_deploy.sh内容,基本思路就是先kill老的tomcat进程,然后把war包移动到tomcat的webapps下,然后调用bin/startup.sh启动tomcat,大家自己看看就明白了
project_name=$1
tomcat_home=$2
echo this is app : $project_name
echo tomcat : $tomcat_home
echo "删除war包"
rm $tomcat_home/webapps/ROOT.war
echo "复制war包"
mv /opt/war/$project_name-web.war $tomcat_home/webapps/ROOT.war
echo "kill tomcat $tomcat_home"
ID=`ps -ef | grep java | grep $tomcat_home|awk '{print $2}'`
for id in $ID
do
kill -9 $id
echo "killed pid=$id"
done
echo "执行tomcat启动shell"
#防止jenkins构建完成后杀死tomcat进程
export BUILD_ID=dontKillMe
sh $tomcat_home/bin/startup.sh
#tail -f $tomcat_home/logs/catalina.out
Docker脚本
docker部署所在机器也是B,与jenkins不在一个机器上,贴上ssh传输配置
finalName也是当做参数,从外部传入
docker部署基本流程有点不一样,简单介绍下
1、先通过一个通用的dockerFile文件,从外部传入finalName,从而制定出项目特定的dockerFile
2、通过dockerFile创建镜像
3、运行docker容器
直接进入核心,看docker.sh
#参数个数<1或者参数空值时,中断执行
if [ $# -lt 2 ] || [ -z $1 ] || [ -z $2 ]; then
echo -e "启动参数不合法"
exit 1
fi
#jar名字
SERVER_NAME=$1
PORT=$2
echo this is app : $SERVER_NAME
echo port : $PORT
#操作/项目路径(Dockerfile存放的路劲)
BASE_PATH=/docker/project/$SERVER_NAME
#动态生成Dockerfile
sed "s/finalName/${SERVER_NAME}/g" /docker/Dockerfile > $BASE_PATH/Dockerfile
#容器id
CID=$(docker ps | grep "$SERVER_NAME" | awk '{print $1}')
#镜像id
IID=$(docker images | grep "$SERVER_NAME" | awk '{print $3}')
# 构建docker镜像
function build(){
if [ -n "$IID" ]; then
echo "存在$SERVER_NAME镜像,IID=$IID"
else
echo "不存在$SERVER_NAME镜像,开始构建镜像"
cd $BASE_PATH
docker build -t $SERVER_NAME .
fi
}
# 运行docker容器
function run(){
build
if [ -n "$CID" ]; then
echo "存在$SERVER_NAME容器,CID=$CID,重启docker容器 ..."
docker restart $SERVER_NAME
echo "$SERVER_NAME容器重启完成"
else
echo "不存在$SERVER_NAME容器,docker run创建容器..."
docker run --name $SERVER_NAME -v $BASE_PATH:$BASE_PATH -d -p $PORT:$PORT $SERVER_NAME
echo "$SERVER_NAME容器创建完成"
fi
}
#入口
run
再附上通用的dockerFile文件
#基于openjdk:8-jdk-alpine
FROM openjdk:8-jdk-alpine
# 指定当前操作目录
WORKDIR /docker/project/finalName
#容器启动后执行的操作
CMD java -jar finalName.jar
如果想用docker部署war包应用,docker里基础镜像得换成tomcat的,启动命令也得参考war包部署里的,用tomcat的startup.sh启动
不足之处
这里都是开发环境的部署脚本,如果要应用到线上,最好能解决集群部署,上下线的问题,也要对旧的包做好备份操作,docker也是最简单的单机部署操作,仅供学习参考