前置声明 我的是4G服务器 部了个rocketmq集群 一个mariadb 一个jenkins 一个docker, jenkins就时不时要崩一下。即使服务器只用来部署jenkins+docker ,估计 2G服务器也够呛 所以注意自己服务器配置,如果低内存仍要尝试的话,在部署不起来的时候,排查问题时务必注意是因为操作失误还是硬件配置问题
jenkins安装
安装好后 会提示创建第一个用户
docker安装
同样的 因为内容比较多 单独一篇文章
docker安装教程
jenkins 配置gitee
注意:除了jenkins和docker , linux上面还需要安装git、maven
以 centos为例 : yum install git ,yum install maven
- jenkins安装gitee插件
顺便把 SSH Pipeline Steps插件安装一下
- 配置gitee账号密码
- 新建一个流水线项目
Jenkinsfile_dev是jenkinsfile的文件名 默认取当前路径 (就是项目的根目录)
- 接下来就是编写jenkinsfile了 这也是最核心的部分,这里贴出一份比较简单的脚步
def getHost(){
def remote = [:]
remote.name = 'aliyun'
remote.host = 'xx.xxx.xxx你的主机地址'
remote.user = '你用来登陆linux的账号'
remote.port = 22
remote.password = '密码'
remote.allowAnyHosts = true
return remote
}
pipeline {
agent any
environment {
server=""
ACTIVE_PROFILE="dev" // 当前环境
BRANCH_NAME="master" // 代码分支名称
HOST_EXPOSE_PORT=8586 // docker对外端口
CONTAINER_EXPOSE_PORT=8585 // 项目端口
JAR_NAME="springboot-core-1.0.0.jar" //jar包名
JAR_OTHER_NAME="springboot.jar" // jar包别名
GIT_USERNAME="gitee账号"
GIT_PASSWORD="gitee密码"
GIT_ADDR="https://${GIT_USERNAME}:${GIT_PASSWORD}@gitee.com:xxx/xxx.git" //项目地址
JOB_NAME="springboot"
JENKINS_WORKSPACE="/root/.jenkins/workspace" // jenkins存放文件的地址
PROJECT_NAME="springboot-core" // 项目名称
CONTAINER_NAME="${JOB_NAME}" // 容器名称
IMAGE_NAME="${JOB_NAME}" // 镜像名
IMAGE_TAG="v1.0.0" // 镜像版本号
APP_SERVER_JOB_PATH="/var/lib/jenkins/workspace/${JOB_NAME}" // 应用服务器工程项目根目录
APP_SERVER_PROJECT_PATH="${APP_SERVER_JOB_PATH}/${PROJECT_NAME}/target" // 项目目录绝对路径
}
stages {
stage('InitContainerServer'){
steps {
script {
server = getHost()
}
}
}
stage("Checkout") {
steps {
echo "从Git下载项目源码"
script {
ssh remote: server, command: """
if test -e ${APP_SERVER_JOB_PATH};then
rm -rf ${APP_SERVER_JOB_PATH}
whoami
git clone -b ${BRANCH_NAME} ${GIT_ADDR} ${APP_SERVER_JOB_PATH}
else
git clone -b ${BRANCH_NAME} ${GIT_ADDR} ${APP_SERVER_JOB_PATH}
fi
"""
}
}
}
stage("Build") {
steps {
echo "开始maven编译构建"
sh 'whoami'
sh 'pwd'
sh "mvn clean package -P ${ACTIVE_PROFILE} -U -Dmaven.test.skip=true"
sh "mv -f ${APP_SERVER_PROJECT_PATH}/${JAR_NAME} ${APP_SERVER_JOB_PATH}"
echo "maven构建成功..."
}
}
// 注意点1: jenkins需要安装SSH Pipeline Steps 插件 用于sshCommand 命令 并可以在控制台看到脚本内容做了什么
// 不安装的话 sshCommand替换成ssh 也是可以执行的 但是很多时候看不到脚本里面做了什么
// 注意点2 $()和``是一个含义 ``是shell通用 $()有的不支持 但可读性更强
// 注意点3 """ 见到$ 就会当成一个变量 但是下面有$()/`` 所以需要替换成'''
// 注意点4 awk因为里面有$1存在 所以同样的需要单引号 ''
stage("CleanContainer") {
steps {
echo "清理旧容器中..."
sh '''docker stop `docker container ls -a|grep -w ${JAR_NAME}|awk '{print $1}'` ||true'''
sh '''docker stop `docker container ls -a|grep -w ${HOST_EXPOSE_PORT}|awk '{print $1}'` ||true'''
sh 'sleep 3s'
sh '''docker rm -f `docker container ls -a|grep -w ${JAR_NAME}|awk '{print $1}'` ||true'''
sh '''docker rm -f `docker container ls -a|grep -w ${HOST_EXPOSE_PORT}|awk '{print $1}'` ||true'''
sh 'docker rmi -f ${JAR_NAME}||true'
echo "清理旧容器成功 开始构建docker"
}
}
stage("Deploy") {
steps {
sh """
pwd
whoami
docker build -t ${
JAR_NAME} .
echo "构建docker成功..."
"""
echo "开始部署"
sh 'docker run -d -p ${HOST_EXPOSE_PORT}:${CONTAINER_EXPOSE_PORT} -t ${JAR_NAME} >output 2>&1'
echo "部署完毕"
}
}
stage("Clean") {
steps {
echo "清理工作"
}
}
}
post {
always {
echo "工作流执行完毕"
}
failure {
echo "工作流执行失败! :("
}
success {
echo "工作流执行成功! ^o^"
}
}
}
语法就是上面这样了 也可以再自定义一些其它的。 全文的难点就是移除docker的语法了 ,不明白到底是linux版本问题还是jenkins问题 导致shell各种出错 试过很多其它人的写法 无一成功的 (我的linux是alibaba cloud linux 理论是等同于centos的), 最后自己想了两天 用这种写法完成了 。
- dockerFile的编写
# Docker image for springboot file run
# VERSION 0.0.1
# Author: qkj
# 基础镜像使用java
FROM java:8
# 作者
MAINTAINER qkj <1005738053@qq.com>
# 路径
WORKDIR /var/lib/jenkins/workspace/springboot
# VOLUME 指定了临时文件目录为/tmp。
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为springboot.jar
ADD springboot-core-1.0.0.jar /springboot.jar
# 运行jar包
RUN bash -c 'touch /springboot.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/springboot.jar"]
- 回到jenkins控制台构建
报错排查.: /bin/docker: cannot execute binary file
在写两个file部署过程中(上面两个file是正确的,这里以回忆的角度叙述), jenkins控制台遇到了.: /bin/docker: cannot execute binary file 排查过程是这样的:
- 首先jenkins_user已经设置为root了(在安装jenkins博客有提及),那就不应该是权限问题,可以看到jenkinsfile中也有whoami 命令(whoami是输出 当前登录账号),也确实是root
- 于是不通过jenkins控制台 直接在linux机器部署docker 先是部署成功, 后面又失败了(对 就是莫名其妙失败的),找到了stackoverflow的一个回答
https://stackoverflow.com/questions/57892651/error-invalid-or-corrupt-jarfile-app-jar/58170124
本来是不相信的 因为加不加斜杠 之前测试都是可以的, 但是别人这么说了 可能是真的遇到过这种情况 抱着试试看的态度加上去了
加上去之后 本地是可以了 没再出现失败的情况,但是jenkins控制台还是报错。
- 索性将jenkins文件夹 chmod 777 (读写执行全开放命令 在我置顶博客也有提及用法) 依然报错
- 仔细观察发现jenkins控制台命令输出 在 docker run xxxxx 前面 自动加了一个 . ,
变成了 . docker run xxxxx ,一开始我的写法是这样的 ,把docker run放在sh “”" “”"代码块里面 不知道为什么会自动加上 .
stage("Deploy") {
steps {
echo "开始部署"
sh """
pwd
whoami
docker build -t ${JAR_NAME} .
echo "build成功 开始运行"
docker run -p ${HOST_EXPOSE_PORT}:${CONTAINER_EXPOSE_PORT} -t ${JAR_NAME}
"""
echo "部署完毕"
}
}
把它单独提出来之后 就解决了这个问题
stage("Deploy") {
steps {
echo "开始部署"
sh """
pwd
whoami
docker build -t ${JAR_NAME} .
echo "build成功 开始运行"
"""
sh 'docker run -p ${HOST_EXPOSE_PORT}:${CONTAINER_EXPOSE_PORT} -t ${JAR_NAME}'
echo "部署完毕"
}
}
出现docker .: /bin/docker: cannot execute binary file问题总结:
1.权限问题(可能是账户权限 也可能是文件夹读写执行权限)
2.ADD aaa.jar /bbb.jar 或 COPY aaa.jar /bbb.jar重命名时 还是加上斜杠好 某些未知情况下 可能会有bug
3.命令前面多了一个 .