jenkins:
image: jenkins/jenkins:lts-jdk21
container_name: jenkins
restart: always
user: root
ports:
- "8088:8088" # 访问端口(避免和 nginx 冲突)
- "50000:50000"
environment:
TZ: Asia/Shanghai
LANG: C.UTF-8
LC_ALL: C.UTF-8
JENKINS_OPTS: "--httpPort=8088"
volumes:
- /docker/jenkins/home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock # 让 Jenkins 可以用宿主机 docker(很关键)
- /usr/bin/docker:/usr/bin/docker
- /data/fonts:/usr/share/fonts
privileged: true
network_mode: "host"
1、先安装Jenkins
2、安装nodejs、ssh、maven
3、连接ssh建议使用 key密钥的形式
使用流水线作业
pipeline {
agent any
parameters {
choice(
name: 'GIT_BRANCH',
choices: ['chancheng_company_show'],
description: '代码分支'
)
string(
name: 'SERVICE_NAME',
defaultValue: 'all',
description: '服务名称,all 表示全部'
)
choice(
name: 'ACTION',
choices: ['compile', 'build', 'all'],
description: '执行动作'
)
booleanParam(
name: 'DO_DEPLOY',
defaultValue: true,
description: '是否部署'
)
}
environment {
TARGET_SERVER = 'xxx'
SCRIPT_PATH = '/docker'
}
options {
timestamps()
disableConcurrentBuilds()
}
stages {
stage('Remote Build') {
steps {
withCredentials([sshUserPrivateKey(
credentialsId: 'e4e8dee2-1ceca86c1467',
keyFileVariable: 'SSH_KEY',
usernameVariable: 'SSH_USER'
)]) {
sh '''
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no "$SSH_USER@$TARGET_SERVER" "
cd $SCRIPT_PATH &&
chmod +x build-backend-v2.sh &&
./build-backend-v2.sh ${ACTION} ${GIT_BRANCH} ${SERVICE_NAME}
"
'''
}
}
}
stage('Remote Deploy') {
when {
expression { return params.DO_DEPLOY }
}
steps {
withCredentials([sshUserPrivateKey(
credentialsId: 'e4e8de2b-7c20-4810-aae2-1ceca86c1467',
keyFileVariable: 'SSH_KEY',
usernameVariable: 'SSH_USER'
)]) {
sh '''
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no "$SSH_USER@$TARGET_SERVER" "
cd $SCRIPT_PATH &&
chmod +x deploy-v2.sh &&
./deploy-v2.sh ${SERVICE_NAME}
"
'''
}
}
}
}
post {
success {
echo '✅ 发布成功'
}
failure {
echo '❌ 发布失败'
}
}}
build-backend-v2.sh:
!/bin/bash
set -e
======= 参数控制 =======
BRANCH="chancheng_company_show"
DO_MAVEN=false
DO_DOCKER=false
TARGET_SERVICE="all"
解析参数
for arg in "$@"; do
# 兼容 Jenkins 传 origin/branch
if [[ "$arg" == origin/* ]]; then
arg="${arg#origin/}"fi
case $arg in
build)
DO_DOCKER=true
;;
compile)
DO_MAVEN=true
;;
all)
DO_MAVEN=true
DO_DOCKER=true
;;
dev|zhongyalian|master|test|chancheng_company_show)
BRANCH="$arg"
;;
hh-auth|hh-gateway|hh-finance|hh-job|hh-mall|hh-resource|hh-sign|hh-site|hh-system|hh-trade|hh-im|hh-xxl-job-admin|hh-oauth2-server)
TARGET_SERVICE="$arg"
;;
*)
echo "❌ 未知参数: $arg"
echo "用法示例:"
echo " ./build-backend.sh all dev"
echo " ./build-backend.sh build dev hh-auth"
exit 1
;;esac
done
======= Git 信息 =======
REPO_URL="git@kend.git"
PROJECT_DIR="/data/git-backend"
======= 模块映射 =======
get_module_path() {
case "$1" in
hh-auth) echo "hh-auth" ;;
hh-gateway) echo "hh-gateway" ;;
hh-finance) echo "hh-modules/hh-finance" ;;
hh-job) echo "hh-modules/hh-job" ;;
hh-mall) echo "hh-modules/hh-mall" ;;
hh-resource) echo "hh-modules/hh-resource" ;;
hh-sign) echo "hh-modules/hh-sign" ;;
hh-site) echo "hh-modules/hh-site" ;;
hh-system) echo "hh-modules/hh-system" ;;
hh-trade) echo "hh-modules/hh-trade" ;;
hh-im) echo "hh-modules/hh-im" ;;
hh-xxl-job-admin) echo "hh-visual/hh-xxl-job-admin" ;;
hh-oauth2-server) echo "hh-modules/hh-oauth2-server" ;;
*)
echo ""
;;esac
}
======= 全量模块 =======
directories=(
"hh-auth"
"hh-gateway"
"hh-modules/hh-"
"hh-modules/hob"
"hh-modules/hhall"
"hh-modules/hh-rource"
"hh-modules/hh-n"
"hh-modules/hh-te"
"hh-modules/hhstem"
"hh-modules/hh-tde"
"hh-modules/hhm"
"hh-visual/hh-xb-admin"
"hh-modules/hh-oauth2-server"
)
echo "========================================="
echo "分支: $BRANCH"
echo "Maven编译: $DO_MAVEN"
echo "Docker构建: $DO_DOCKER"
echo "目标服务: $TARGET_SERVICE"
echo "项目目录: $PROJECT_DIR"
echo "========================================="
======= 克隆或更新代码 =======
if [ ! -d "$PROJECT_DIR/.git" ]; then
echo "📥 克隆后端仓库(分支:$BRANCH)..."
rm -rf "$PROJECT_DIR"
git clone -b "$BRANCH" "$REPO_URL" "$PROJECT_DIR" || {
echo "❌ clone 失败,请检查网络或权限"
exit 1}
else
cd "$PROJECT_DIR"
echo "🔄 更新后端仓库(切换到分支:$BRANCH)..."
git fetch origin
git checkout "$BRANCH"
git pull origin "$BRANCH"
fi
======= Maven 编译 =======
if [ "$DO_MAVEN" = true ]; then
echo "🔧 执行 Maven 编译..."
cd "$PROJECT_DIR"
mvn clean package -Dmaven.test.skip=true || {
echo "❌ Maven 编译失败"
exit 1}
echo "✅ Maven 编译成功"
fi
======= 构建 Docker 镜像 =======
if [ "$DO_DOCKER" = true ]; then
echo "🐳 构建 Docker 镜像..."
if [ "$TARGET_SERVICE" = "all" ]; then
for dir in "${directories[@]}"; do
MODULE_PATH="$PROJECT_DIR/$dir"
IMAGE_NAME="${dir##*/}"
if [ ! -f "$MODULE_PATH/Dockerfile" ]; then
echo "⚠️ 跳过:$IMAGE_NAME,没有 Dockerfile"
continue
fi
echo "🔨 构建镜像: $IMAGE_NAME"
cd "$MODULE_PATH"
docker build -t "$IMAGE_NAME" . || {
echo "❌ 构建失败: $IMAGE_NAME"
exit 1
}
doneelse
MODULE_RELATIVE_PATH=$(get_module_path "$TARGET_SERVICE")
if [ -z "$MODULE_RELATIVE_PATH" ]; then
echo "❌ 未找到服务对应模块: $TARGET_SERVICE"
exit 1
fi
MODULE_PATH="$PROJECT_DIR/$MODULE_RELATIVE_PATH"
if [ ! -f "$MODULE_PATH/Dockerfile" ]; then
echo "❌ $TARGET_SERVICE 没有 Dockerfile"
exit 1
fi
echo "🔨 构建单个镜像: $TARGET_SERVICE"
cd "$MODULE_PATH"
docker build -t "$TARGET_SERVICE" . || {
echo "❌ 构建失败: $TARGET_SERVICE"
exit 1
}fi
echo "✅ Docker 镜像构建完成"
fi
deploy-v2.sh:
!/bin/bash
set -e
SERVICE_NAME="${1:-all}"
COMPOSE_FILE="/docker/docker-compose.yml"
BUSINESS_SERVICES=(
hh-xxl-job-admin
hh-gateway
hh-auth
hh-system
hh-job
hh-resource
hh-finance
hh-mall
hh-sign
hh-site
hh-trade
hh-im
hh-oauth2-server
)
echo "========================================="
echo "部署目标: $SERVICE_NAME"
echo "Compose文件: $COMPOSE_FILE"
echo "========================================="
if [ ! -f "$COMPOSE_FILE" ]; then
echo "❌ docker-compose 文件不存在: $COMPOSE_FILE"
exit 1
fi
cd /docker
if [ "$SERVICE_NAME" = "all" ]; then
echo "🚀 发布全部业务服务..."
docker-compose -f "$COMPOSE_FILE" up -d "${BUSINESS_SERVICES[@]}"
else
echo "🚀 发布单个服务: $SERVICE_NAME"
docker-compose -f "$COMPOSE_FILE" up -d "$SERVICE_NAME"
fi
echo "📋 当前服务状态:"
docker-compose -f "$COMPOSE_FILE" ps
echo "✅ 部署完成"