暂存提交
This commit is contained in:
+2
-1
@@ -5,6 +5,8 @@
|
|||||||
*.yaml text eol=lf
|
*.yaml text eol=lf
|
||||||
*.md text eol=lf
|
*.md text eol=lf
|
||||||
*.sql text eol=lf
|
*.sql text eol=lf
|
||||||
|
*.sh text eol=lf
|
||||||
|
Jenkinsfile text eol=lf
|
||||||
*.ps1 text eol=crlf
|
*.ps1 text eol=crlf
|
||||||
*.cmd text eol=crlf
|
*.cmd text eol=crlf
|
||||||
*.bat text eol=crlf
|
*.bat text eol=crlf
|
||||||
@@ -13,4 +15,3 @@
|
|||||||
*.jpg binary
|
*.jpg binary
|
||||||
*.jpeg binary
|
*.jpeg binary
|
||||||
*.pdf binary
|
*.pdf binary
|
||||||
|
|
||||||
|
|||||||
Vendored
+19
-6
@@ -67,7 +67,7 @@ pipeline {
|
|||||||
choice(name: 'ENVIRONMENT', choices: ['test', 'staging', 'production'], description: '部署环境')
|
choice(name: 'ENVIRONMENT', choices: ['test', 'staging', 'production'], description: '部署环境')
|
||||||
booleanParam(name: 'DEPLOY', defaultValue: false, description: '构建成功后是否部署')
|
booleanParam(name: 'DEPLOY', defaultValue: false, description: '构建成功后是否部署')
|
||||||
booleanParam(name: 'SKIP_TESTS', defaultValue: false, description: '是否跳过测试;生产构建不建议勾选')
|
booleanParam(name: 'SKIP_TESTS', defaultValue: false, description: '是否跳过测试;生产构建不建议勾选')
|
||||||
string(name: 'IMAGE_REPOSITORY', defaultValue: '8.163.30.128:10082/java-project/baiyue-firstleg', description: 'Gitea 容器镜像仓库地址')
|
string(name: 'IMAGE_REPOSITORY', defaultValue: '8.163.30.128:10082/java-project/baiyue-firstleg', description: '预发布/生产镜像仓库地址;test 环境自动使用本机镜像,无需修改')
|
||||||
string(name: 'DOCKER_BASE_IMAGE', defaultValue: 'docker.m.daocloud.io/library/eclipse-temurin:17-jre-alpine', description: 'Java 17 基础镜像;默认使用国内镜像代理')
|
string(name: 'DOCKER_BASE_IMAGE', defaultValue: 'docker.m.daocloud.io/library/eclipse-temurin:17-jre-alpine', description: 'Java 17 基础镜像;默认使用国内镜像代理')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,14 +81,19 @@ pipeline {
|
|||||||
stage('确定构建范围') {
|
stage('确定构建范围') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
String requestedRepository = params.IMAGE_REPOSITORY?.trim()
|
String requestedRepository
|
||||||
|
if (params.ENVIRONMENT == 'test') {
|
||||||
|
requestedRepository = 'baiyue-firstleg-test'
|
||||||
|
echo '测试环境使用 Jenkins 节点本机镜像,不登录、不推送远程 Registry'
|
||||||
|
} else {
|
||||||
|
requestedRepository = params.IMAGE_REPOSITORY?.trim()
|
||||||
if (!requestedRepository || requestedRepository == 'registry.example.com/your-group/baiyue-firstleg') {
|
if (!requestedRepository || requestedRepository == 'registry.example.com/your-group/baiyue-firstleg') {
|
||||||
requestedRepository = '8.163.30.128:10082/java-project/baiyue-firstleg'
|
error('预发布/生产环境必须填写真实的 HTTPS 镜像仓库地址')
|
||||||
echo "检测到旧的镜像仓库占位地址,已自动切换为测试环境 Gitea:${requestedRepository}"
|
|
||||||
}
|
}
|
||||||
if (requestedRepository.contains('://') || !requestedRepository.contains('/')) {
|
if (requestedRepository.contains('://') || !requestedRepository.contains('/')) {
|
||||||
error('IMAGE_REPOSITORY 格式错误:请填写 host[:port]/owner/image,不要包含 http:// 或 https://')
|
error('IMAGE_REPOSITORY 格式错误:请填写 host[:port]/owner/image,不要包含 http:// 或 https://')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
env.RESOLVED_IMAGE_REPOSITORY = requestedRepository
|
env.RESOLVED_IMAGE_REPOSITORY = requestedRepository
|
||||||
|
|
||||||
List selected = []
|
List selected = []
|
||||||
@@ -150,16 +155,23 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('构建并推送镜像') {
|
stage('构建镜像并按环境发布') {
|
||||||
when { expression { env.NO_SERVICE_CHANGE != 'true' } }
|
when { expression { env.NO_SERVICE_CHANGE != 'true' } }
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
|
env.SELECTED_SERVICES.split(',').each { service ->
|
||||||
|
String image = "${env.RESOLVED_IMAGE_REPOSITORY}/${service}:${env.IMAGE_TAG}"
|
||||||
|
sh "docker build -f deploy/docker/Dockerfile --build-arg BASE_IMAGE=${params.DOCKER_BASE_IMAGE} --build-arg JAR_FILE=${serviceJars[service]} -t ${image} ."
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.ENVIRONMENT == 'test') {
|
||||||
|
echo "测试镜像已保存在当前 Docker 节点:${env.RESOLVED_IMAGE_REPOSITORY}/*:${env.IMAGE_TAG}"
|
||||||
|
} else {
|
||||||
String registryHost = env.RESOLVED_IMAGE_REPOSITORY.tokenize('/')[0]
|
String registryHost = env.RESOLVED_IMAGE_REPOSITORY.tokenize('/')[0]
|
||||||
withCredentials([usernamePassword(credentialsId: env.REGISTRY_CREDENTIALS, usernameVariable: 'REGISTRY_USER', passwordVariable: 'REGISTRY_PASSWORD')]) {
|
withCredentials([usernamePassword(credentialsId: env.REGISTRY_CREDENTIALS, usernameVariable: 'REGISTRY_USER', passwordVariable: 'REGISTRY_PASSWORD')]) {
|
||||||
sh 'printf %s "$REGISTRY_PASSWORD" | docker login -u "$REGISTRY_USER" --password-stdin "' + registryHost + '"'
|
sh 'printf %s "$REGISTRY_PASSWORD" | docker login -u "$REGISTRY_USER" --password-stdin "' + registryHost + '"'
|
||||||
env.SELECTED_SERVICES.split(',').each { service ->
|
env.SELECTED_SERVICES.split(',').each { service ->
|
||||||
String image = "${env.RESOLVED_IMAGE_REPOSITORY}/${service}:${env.IMAGE_TAG}"
|
String image = "${env.RESOLVED_IMAGE_REPOSITORY}/${service}:${env.IMAGE_TAG}"
|
||||||
sh "docker build -f deploy/docker/Dockerfile --build-arg BASE_IMAGE=${params.DOCKER_BASE_IMAGE} --build-arg JAR_FILE=${serviceJars[service]} -t ${image} ."
|
|
||||||
sh "docker push ${image}"
|
sh "docker push ${image}"
|
||||||
}
|
}
|
||||||
sh "docker logout ${registryHost} || true"
|
sh "docker logout ${registryHost} || true"
|
||||||
@@ -167,6 +179,7 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage('生产环境部署确认(仅 production 执行)') {
|
stage('生产环境部署确认(仅 production 执行)') {
|
||||||
when {
|
when {
|
||||||
|
|||||||
Vendored
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
# 复制本文件仅用于本地验证。Jenkins 中应创建“Secret file”凭据,禁止提交真实 .env。
|
# 复制本文件仅用于本地验证。Jenkins 中应创建“Secret file”凭据,禁止提交真实 .env。
|
||||||
DEPLOY_ENV=test
|
DEPLOY_ENV=test
|
||||||
IMAGE_REPOSITORY=8.163.30.128:10082/java-project/baiyue-firstleg
|
# Jenkins 部署时会覆盖为 baiyue-firstleg-test;本地手工部署可使用此默认值。
|
||||||
|
IMAGE_REPOSITORY=baiyue-firstleg-test
|
||||||
IMAGE_TAG=latest
|
IMAGE_TAG=latest
|
||||||
INFRA_NETWORK=firstleg-test-infra-network
|
INFRA_NETWORK=firstleg-test-infra-network
|
||||||
|
|
||||||
|
|||||||
@@ -20,17 +20,23 @@ fi
|
|||||||
SERVICES=$(printf '%s' "$SERVICE_CSV" | tr ',' ' ')
|
SERVICES=$(printf '%s' "$SERVICE_CSV" | tr ',' ' ')
|
||||||
|
|
||||||
export DEPLOY_ENV IMAGE_REPOSITORY IMAGE_TAG
|
export DEPLOY_ENV IMAGE_REPOSITORY IMAGE_TAG
|
||||||
docker compose \
|
|
||||||
|
PULL_POLICY_ARGS=""
|
||||||
|
if [ "$DEPLOY_ENV" = "test" ]; then
|
||||||
|
PULL_POLICY_ARGS="--pull never"
|
||||||
|
else
|
||||||
|
docker compose \
|
||||||
--project-name "firstleg-${DEPLOY_ENV}" \
|
--project-name "firstleg-${DEPLOY_ENV}" \
|
||||||
--env-file "$ENV_FILE" \
|
--env-file "$ENV_FILE" \
|
||||||
-f deploy/docker-compose.yml \
|
-f deploy/docker-compose.yml \
|
||||||
pull $SERVICES
|
pull $SERVICES
|
||||||
|
fi
|
||||||
|
|
||||||
docker compose \
|
docker compose \
|
||||||
--project-name "firstleg-${DEPLOY_ENV}" \
|
--project-name "firstleg-${DEPLOY_ENV}" \
|
||||||
--env-file "$ENV_FILE" \
|
--env-file "$ENV_FILE" \
|
||||||
-f deploy/docker-compose.yml \
|
-f deploy/docker-compose.yml \
|
||||||
up -d --remove-orphans $SERVICES
|
up -d --remove-orphans $PULL_POLICY_ARGS $SERVICES
|
||||||
|
|
||||||
docker compose \
|
docker compose \
|
||||||
--project-name "firstleg-${DEPLOY_ENV}" \
|
--project-name "firstleg-${DEPLOY_ENV}" \
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ MySQL、Redis、Nacos 是外部基础设施,不包含在业务 Compose 文件
|
|||||||
| `deploy/env/.env.test.example` | 测试环境变量模板,不含真实密码 |
|
| `deploy/env/.env.test.example` | 测试环境变量模板,不含真实密码 |
|
||||||
| `deploy/scripts/deploy-services.sh` | Jenkins 节点上的增量部署脚本 |
|
| `deploy/scripts/deploy-services.sh` | Jenkins 节点上的增量部署脚本 |
|
||||||
|
|
||||||
|
测试环境服务器准备步骤详见 `docs/test-environment-deployment.md`。
|
||||||
|
|
||||||
## 三、Jenkins 前置条件
|
## 三、Jenkins 前置条件
|
||||||
|
|
||||||
Jenkins 新建“多分支流水线”或“流水线”,脚本路径填写 `Jenkinsfile`。执行节点标签为 `docker-java17`,节点需要安装:
|
Jenkins 新建“多分支流水线”或“流水线”,脚本路径填写 `Jenkinsfile`。执行节点标签为 `docker-java17`,节点需要安装:
|
||||||
|
|||||||
Reference in New Issue
Block a user