146 lines
4.4 KiB
Plaintext
146 lines
4.4 KiB
Plaintext
pipeline {
|
||
// 在任意可用节点执行(你是单机就只有 master/内置节点)
|
||
agent any
|
||
|
||
options {
|
||
// 单机一定要禁并发:避免同时构建/部署互相覆盖容器
|
||
disableConcurrentBuilds()
|
||
|
||
// 控制台输出带时间戳,排查问题更方便
|
||
timestamps()
|
||
}
|
||
|
||
environment {
|
||
// 运行容器的名字:固定一个,方便停旧启新
|
||
APP_NAME = "agri"
|
||
|
||
// 容器内程序监听端口 & 宿主机映射端口(这里同端口)
|
||
PORT = "8088"
|
||
|
||
// <span style="color:#d00;font-weight:700">部署目录</span>:你已经把宿主机 /opt/agri 挂载进 Jenkins 容器了
|
||
// 这里常用来放日志、当前版本号等
|
||
DEPLOY_DIR = "/opt/agri"
|
||
|
||
// 镜像仓库名(本机镜像名即可)
|
||
// 最终镜像:agri-backend:${BUILD_NUMBER}
|
||
IMAGE_REPO = "agri-backend"
|
||
|
||
// 记录“当前部署的构建号”,方便你手动回滚时知道上一版是啥
|
||
CURRENT_TAG_FILE = "/opt/agri/current_tag"
|
||
|
||
// 多模块项目的“真正启动模块”
|
||
// 你这个结构里一般就是 agri-admin
|
||
BOOT_MODULE = "agri-admin"
|
||
}
|
||
|
||
stages {
|
||
|
||
stage('Checkout') {
|
||
steps {
|
||
// 从 Jenkins Job 配置的 SCM 拉代码(ssh gitea)
|
||
checkout scm
|
||
}
|
||
}
|
||
|
||
stage('Build Jar (JDK8, multi-module)') {
|
||
// 用 Maven+JDK8 的构建容器来编译,避免你在服务器/jenkins里安装 JDK8/Maven
|
||
// 注意:这个 stage 运行在一个临时容器里,但 workspace 是共享的
|
||
agent {
|
||
docker {
|
||
// Maven 3.9 + Temurin JDK8
|
||
image 'maven:3.9.6-eclipse-temurin-8'
|
||
|
||
// 挂载 Maven 本地仓库缓存,加速第二次构建
|
||
// $HOME 指 Jenkins 容器内的 home,通常在 /var/jenkins_home
|
||
args '-v $HOME/.m2:/root/.m2'
|
||
}
|
||
}
|
||
|
||
steps {
|
||
sh '''
|
||
set -e
|
||
|
||
echo "==== Build multi-module boot module: ${BOOT_MODULE} ===="
|
||
|
||
# -pl ${BOOT_MODULE}:只构建启动模块
|
||
# -am:同时构建它依赖的其它模块(common/framework/system等)
|
||
# -DskipTests:跳过测试,加速
|
||
mvn -B -DskipTests -pl ${BOOT_MODULE} -am clean package
|
||
|
||
echo "==== Pick jar from ${BOOT_MODULE}/target ===="
|
||
ls -lh ${BOOT_MODULE}/target || true
|
||
|
||
# 创建根目录 target(与 Dockerfile 对齐:COPY target/agri.jar)
|
||
mkdir -p target
|
||
|
||
# 找一个可运行 jar:排除 sources/javadoc(如果有 original 也可以再排除)
|
||
jar=$(ls -1 ${BOOT_MODULE}/target/*.jar | grep -v 'sources\\|javadoc' | head -n 1)
|
||
|
||
echo "Selected jar: $jar"
|
||
|
||
# 统一命名为 target/agri.jar,后续 docker build 直接 COPY
|
||
cp -f "$jar" target/agri.jar
|
||
|
||
echo "==== Final artifact ===="
|
||
ls -lh target/agri.jar
|
||
'''
|
||
}
|
||
}
|
||
|
||
stage('Build Image') {
|
||
steps {
|
||
sh '''
|
||
set -e
|
||
|
||
# 构建镜像:agri-backend:${BUILD_NUMBER}
|
||
# Dockerfile 会 COPY target/agri.jar
|
||
docker build -t ${IMAGE_REPO}:${BUILD_NUMBER} .
|
||
|
||
echo "Built image: ${IMAGE_REPO}:${BUILD_NUMBER}"
|
||
'''
|
||
}
|
||
}
|
||
|
||
stage('Deploy') {
|
||
steps {
|
||
sh '''
|
||
set -e
|
||
|
||
echo "==== Deploy to ${DEPLOY_DIR} ===="
|
||
mkdir -p "${DEPLOY_DIR}"
|
||
|
||
# 1) 停旧容器(不存在也没关系)
|
||
docker rm -f ${APP_NAME} >/dev/null 2>&1 || true
|
||
|
||
# 2) 启新容器
|
||
# --restart unless-stopped:机器重启后自动起来
|
||
# -p 8088:8088:把宿主机 8088 映射到容器 8088
|
||
# -v /opt/agri/logs:/app/logs:把日志落到宿主机 /opt/agri/logs
|
||
docker run -d \
|
||
--name ${APP_NAME} \
|
||
--restart unless-stopped \
|
||
-p ${PORT}:${PORT} \
|
||
-v ${DEPLOY_DIR}/logs:/app/logs \
|
||
${IMAGE_REPO}:${BUILD_NUMBER}
|
||
|
||
# 记录当前版本号(手动回滚时用)
|
||
echo "${BUILD_NUMBER}" > "${CURRENT_TAG_FILE}"
|
||
|
||
echo "Deployed: ${IMAGE_REPO}:${BUILD_NUMBER}"
|
||
echo "Current tag file: ${CURRENT_TAG_FILE} -> $(cat ${CURRENT_TAG_FILE})"
|
||
'''
|
||
}
|
||
}
|
||
}
|
||
|
||
post {
|
||
always {
|
||
// 每次构建结束都打印一下当前容器状态,排查更方便
|
||
sh '''
|
||
echo "==== docker ps (agri) ===="
|
||
docker ps --filter "name=^/agri$" || true
|
||
'''
|
||
}
|
||
}
|
||
}
|