Gitlab+Jenkins+docker完成Maven项目的自动部署
工程自动化开发环境搭建:Gitlab+Jenkins+docker如何来构建Maven项目
本文的环境:
Ubuntu 16.04LTS
Docker version 1.12.5, build 7392c3b
思路: Jenkisn安装在宿主机上,通过Jenkins从属机来拉取gitlab上的代码,进行Maven编译,使用docker进行发布。
安装Jenkins
关于Docker的安装,国内用户建议使用以下脚本:
#!/bin/sh
mv /etc/apt/sources.list /etc/apt/sources.list.bak
cd /etc/apt/
cat > sources.list <<- EOF
deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties
deb http://archive.canonical.com/ubuntu xenial partner
deb-src http://archive.canonical.com/ubuntu xenial partner
deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties
deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse
EOF
apt-get update
curl -sSL https://get.daocloud.io/docker | sh
curl -L https://get.daocloud.io/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
可以选择官方的Docker镜像。
docker run -p 8080:8080 -p 50000:50000 jenkins
不过没有本地环境,如果需要在Jenkins的宿主机上跑docker的话可以使用如下镜像包:
建议使用我写的安装包,包含JAVA与maven环境:
docker run -it -d -p 8080:8080 -v /opt/jenkins:/jenkins -v /etc/localtime:/etc/localtime:ro --name jenkins lw96/java8-jenkins-maven-git-vim
这个包里面包含的环境:
- Ubuntu 16.04 LTS
- Oracle Java 1.8.0_112-b15 64 bit
- Maven 3.3.9
- Jenkins 2.19.4
- git 2.7.4
- Vim
不定期进行更新到最新的Jenkins,欢迎大家下载点星。
添加从属机与权限
系统管理→管理节点→新建节点
选择节点名称:选择Permament Agent
# of exectors 并发数 看你从属机的配置了
远程工作目录: /opt/jenkins_workspace
标签: SlaveServer
用法: 尽可能的使用这个节点
启用方法: Launch slave agents via SSH
Host: www.example.com
Credentials: 点击Add添加,或者选择一个SSHkey
Availability: keep this agent online as much as possible
上面的配置基本完成了一个从属机器的连接配置信息。
关于SSH登录与配置,点击我。
下面的Node Properties中Environment variables为环境变量,Tools Locations为一些环境:
比如我的是这样填的:
git-2.7.4 /usr/bin/git
Docker /usr/bin/docker
Maven3.3.9 /opt/maven
Java8 /opt/java
以上路径为slave机上的环境。
我写了一个简单的安装shell脚本:
apt-get update
apt-get install -y wget
export MAVEN_NAME=apache-maven-3.3.9
export MAVEN_HOME=/opt/maven/
wget --no-verbose -O /tmp/$MAVEN_NAME.tar.gz http://archive.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz \
&& mkdir /opt/maven \
&& tar -zxf /tmp/$MAVEN_NAME.tar.gz -C /opt/maven --strip-components=1 \
&& ln -s /opt/maven/bin/mvn /usr/local/bin \
&& rm -f /tmp/$MAVEN_NAME.tar.gz
apt-get install -y git
wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" -O /tmp/jdk-8u112-linux-x64.tar.gz http://download.oracle.com/otn-pub/java/jdk/8u112-b15/jdk-8u112-linux-x64.tar.gz \
&& mkdir /opt/java \
&& tar -zxf /tmp/jdk-8u112-linux-x64.tar.gz -C /opt/java/ --strip-components=1 \
&& update-alternatives --install /usr/bin/java java /opt/java/bin/java 20000 \
&& update-alternatives --install /usr/bin/javac javac /opt/java/bin/javac 20000
点击保存。
新建任务
我的工作目录:
mkdir /opt/jenkins_workspace
cd /opt/jenkins_workspace
# 用来拉取gitlab代码,并编译用
mkdir workspace
# 用来存项目的war包与发布用
mkdir war
(1)回到Jenkins首页,点击新建任务,选择自动风格。
General部分选择Restrict where this project can be run
:
输入前面写的从属机的标签:SlaveServer
(2)源码管理,点击Git:
填入Repository URL
仓库地址:比如ssh://www.example.com/test.git
选择之前添加的密钥,同理,把密钥添加到gitlab项目中。
点击高级,选择Name为origin
下面的分支选择origin/dev
(3)构建触发器:
选择Build when a change is pushed to Gitlab. Gitlab CI Service URL:http://jenkins.example.com:8080/project/projectName
取消 Comments
前面的勾。其他可以根据自己的需要调整。
在Gitlab中,进入项目中,选择项目设置
→webhook
→Url处填入上面的URL。
这样就完成了项目的自动触发。
(4)构建
添加Maven构建War包:
选择MavenVersion→命令:clean install→POM:pom.xml
选择Exectue Shell
cd /opt/jenkins_workspace && ./del.sh test 10000
其中del.sh
脚本中的内容如下:
大体思想是,传递两个参数,一个是项目名称,一个项目运行的端口。
先去判断有没有这个同名容器,如果有,那就删除这个容器。
再去判断有没有端口被其他应用占用,如果没有,就运行容器;如果有,就在端口池里面随机一个端口进行运行容器。
#!/bin/bash
CONTAINER=$1
PORT=$2
MAXPORT=10000
MINPORT=20000
DIR="`dirname $BASH_SOURCE`"
MYDIR=`readlink -f "$DIR"`
# MYDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo $MYDIR
# functions
# docker function
start_docker(){
filePath=$MYDIR/war/$CONTAINER
echo "docker use filePath is $filePath"
docker run -it -d --name $CONTAINER -p $PORT:8080 -v $filePath:/usr/local/tomcat/webapps tomcat:7-jre8
}
#check docker exist
check_docker(){
RUNNING=$(docker inspect --format="{{ .State.Running }}" $CONTAINER 2> /dev/null)
if [ $? -eq 1 ]; then
echo "$CONTAINER does not exist."
return 1
fi
if [ "$RUNNING" == "false" ]; then
echo "$CONTAINER is not running."
return 2
else
echo "$CONTAINER is running"
fi
}
# check port
check_port() {
echo "Checking instance port ..."
netstat -tlpn | grep "\b$1\b"
}
#random a number
rand(){
min=$1
max=$(($2-$min+1))
num=$(cat /dev/urandom | head -n 10 | cksum | awk -F ' ' '{print $1}')
echo $(($num%$max+$min))
}
# delete same name container
matchingStarted=$(docker ps --filter="name=$CONTAINER" -q | xargs)
[[ -n $matchingStarted ]] && docker stop $matchingStarted
matching=$(docker ps -a --filter="name=$CONTAINER" -q | xargs)
[[ -n $matching ]] && docker rm $matching
# create warfile dir
cd `dirname $0`/war
if [ ! -d `pwd`/$1 ];
then
mkdir $1
else
rm -rf $1/*
echo "`dirname $0`/workspace/$1/target/"
cp $MYDIR/workspace/$1/target/*.war `pwd`/$1/$1.war
fi
# check port
if check_port $PORT
then
PORT=$(rand $MINPORT $MAXPORT)
while check_port $PORT
do
PORT=$(rand $MINPORT $MAXPORT)
done
fi
echo "use $PORT to start $1 docker"
start_docker
echo "docker has started, waiting for tomcat.End!"
exit 0
(5)保存,Have Fun