Compare commits

...

71 Commits
main ... test

Author SHA1 Message Date
yidl f199612f54 调整 2025-08-31 00:01:08 +08:00
yidl 93bec8a709 更换网关 2025-08-25 23:25:02 +08:00
yidl 6f987832ad healthy config 2025-08-25 21:22:53 +08:00
yidl 55212594fc Merge branch 'stage' of http://111.230.114.47:3000/yidongliang/gateway into stage 2025-08-25 21:17:42 +08:00
yidl 0146b2462a Healthy系统服务 (8003) 2025-08-25 21:16:53 +08:00
yidongliang 470effc4f7 Merge pull request '106.52.199.114:8001;' (#2) from stage-changehost into stage
Reviewed-on: http://111.230.114.47:3000/yidongliang/gateway/pulls/2
2025-08-20 01:24:56 +08:00
易栋梁 0c008f42a4 106.52.199.114:8001; 2025-08-20 01:24:12 +08:00
yidongliang 8a1de1b2a6 Merge pull request 'host' (#1) from stage-changehost into stage
Reviewed-on: http://111.230.114.47:3000/yidongliang/gateway/pulls/1
2025-08-19 23:26:36 +08:00
yidl 5748690443 host 2025-08-19 23:23:44 +08:00
yidl d7c8c69986 Revert "host"
This reverts commit 4bc72fbe57.
2025-08-18 12:01:15 +08:00
yidl 4bc72fbe57 host 2025-08-17 22:58:11 +08:00
yidl 678d6c8a8e .vs忽略 2025-08-17 14:35:03 +08:00
yidl 67d7822159 Merge branch 'stage' of http://111.230.114.47:3000/yidongliang/gateway into stage 2025-08-17 14:32:36 +08:00
yidl 318240db25 nginx 大小限制 2025-08-17 14:32:33 +08:00
yidongliang 886faeaead 更新 nginx.conf.gateway 2025-08-15 14:01:14 +08:00
yidl 9a7e257f2c sv 2025-07-31 23:54:07 +08:00
yidl 6912ddd3dd 代理 2025-07-31 23:32:37 +08:00
yidl bb8bfff16c 附件代理 2025-07-31 23:25:08 +08:00
yidl c11eda86d8 调整附件目录映射 2025-07-31 23:07:10 +08:00
yidl a3b99e35e8 调整文件路由 2025-07-31 22:52:55 +08:00
易栋梁 e0844bd024 更改映射地址 2025-07-06 11:43:29 +08:00
yidl 1411750505 增加附件的路径 2025-07-04 21:43:45 +08:00
yidl b4bf1fd0e8 更换端口 2025-07-04 00:47:40 +08:00
yidl ee00c21d39 lmg路由 2025-07-02 23:51:16 +08:00
yidongliang 1743431b2c 更新 nginx.conf.gateway 2025-07-02 12:48:21 +08:00
yidongliang 03b9653f3c 更新 nginx.conf.gateway 2025-07-02 12:44:41 +08:00
yidongliang cf2fe0038c 更新 Dockerfile 2025-07-02 12:29:39 +08:00
yidongliang bbee69c1b1 更新 nginx.conf.gateway 2025-07-02 12:28:56 +08:00
yidl 29df7e83b1 save 2025-07-02 01:32:17 +08:00
yidl afdd5744a7 sve 2025-07-02 01:26:27 +08:00
yidl d895f96bff save 2025-07-02 01:18:48 +08:00
yidl 331b5519c4 save 2025-07-02 01:08:27 +08:00
yidl 80a1063d7d save 2025-07-02 00:55:40 +08:00
yidl fd646c9785 save 2025-07-02 00:33:54 +08:00
yidl 0d00202a80 connect 2025-07-01 01:39:35 +08:00
易栋梁 b71d14f3d8 增加8002 2025-06-29 18:18:48 +08:00
易栋梁 768fc15d6b 证书问题 2025-06-29 17:43:34 +08:00
易栋梁 4b95c77dca issuser 不改 2025-06-29 17:19:46 +08:00
易栋梁 823b200bc7 changes 2025-06-29 17:11:03 +08:00
易栋梁 412cf2d70d sys_api filter 2025-06-29 17:04:05 +08:00
易栋梁 39a52fab83 改成3服务分开部署的模式 2025-06-29 16:35:53 +08:00
易栋梁 87b6e0b1ae 把 授权也业务分开 2025-06-29 16:12:53 +08:00
易栋梁 4b15df695e add ids router 2025-06-29 15:06:38 +08:00
易栋梁 b2c24799f2 https 2025-06-29 14:36:24 +08:00
易栋梁 f68e5df0bc 调整路由代码 2025-06-29 14:30:44 +08:00
yidl 65afb933c9 更新 2025-06-29 01:36:27 +08:00
yidl 2aef82d7ca 修正 2025-06-29 00:29:41 +08:00
yidl 0ec8bea1c1 save 2025-06-29 00:04:06 +08:00
yidl d4b42ab3be save 2025-06-28 23:20:38 +08:00
yidl 7787668092 https 协议 2025-06-28 23:03:36 +08:00
yidl d8dd567f25 证书问题修复 2025-06-28 22:44:07 +08:00
yidl a3a131074f 证书外挂 2025-06-28 22:16:58 +08:00
yidl 2c03f18f10 bzpt_sys-internal 2025-06-28 18:29:51 +08:00
yidl 06241e868d proxy_ssl_verify off; 2025-06-28 18:19:36 +08:00
yidl 460374f404 路由规则调整 2025-06-28 17:52:44 +08:00
yidl 14c4505670 路由规则调整 2025-06-28 14:16:22 +08:00
yidl 3fac72ea38 修改路由 2025-06-28 12:37:21 +08:00
yidl f5a6a676a4 更新协议 2025-06-27 23:50:33 +08:00
yidl 162a6d734a 调整路由
调整路由
2025-06-27 23:21:50 +08:00
yidl 028acdc5d7 save 2025-06-26 23:50:07 +08:00
yidl 905c4e491a Merge branch 'stage' of http://111.230.114.47:3000/yidongliang/gateway into stage
# Conflicts:
#	nginx.conf.gateway
2025-06-26 23:47:14 +08:00
yidl 98c6875bb2 sav 2025-06-26 23:39:24 +08:00
yidongliang 4f495add3d 更新 nginx.conf.gateway
auth定位到授权
2025-06-26 15:56:10 +08:00
yidongliang 0642c1f484 更新 nginx.conf.gateway
调整路由
2025-06-26 12:58:00 +08:00
yidl 6c9df7ea75 配置文件问题 2025-06-25 23:08:41 +08:00
yidl 624f99aa96 sav 2025-06-24 00:56:09 +08:00
yidl 102cd439bb save 2025-06-24 00:28:34 +08:00
yidl 9d186312e5 save 2025-06-24 00:18:46 +08:00
yidl c410885ff9 更新配置 2025-06-23 00:24:53 +08:00
易栋梁 ead0985923 stage 2025-06-22 17:26:17 +08:00
易栋梁 4bc643fcd1 init 2025-06-22 14:46:32 +08:00
6 changed files with 438 additions and 1 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
################################################################################
# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
################################################################################
/.vs

27
Dockerfile Normal file
View File

@ -0,0 +1,27 @@
# 基于官方 Traefik v3 镜像
FROM traefik:v3.0
# 维护者
LABEL maintainer="you@example.com"
# 拷贝静态配置 (traefik.yml)
COPY traefik.yml /etc/traefik/traefik.yml
# 拷贝动态配置 (dynamic.yml)
COPY dynamic.yml /etc/traefik/dynamic.yml
# 创建证书目录(可挂载)
RUN mkdir -p /etc/certs
# 暴露你需要的端口
# - 8000: Sys 系统
# - 8002: LMG 系统
# - 8003: Healthy 系统
# - 8080: Traefik Dashboard (可选)
EXPOSE 8000 8002 8003 8080
# 启动 Traefik
ENTRYPOINT ["traefik"]
# 默认命令:启动并加载静态配置
CMD ["--configFile=/etc/traefik/traefik.yml"]

211
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,211 @@
// Groovy 辅助函数,用于发送钉钉通知。(保持不变)
@NonCPS
def sendDingTalkNotification(Map config) {
def message = config.get('message', '来自 Jenkins 的通知')
def webhookEnvVarName = config.get('webhookEnvVarName') // 存储 Webhook URL 的环境变量名称
def author = config.get('author', '未知用户')
def jobName = config.get('jobName', env.JOB_NAME ?: 'N/A')
def buildNumber = config.get('buildNumber', env.BUILD_NUMBER ?: 'N/A')
def enabled = config.get('enabled', false)
if (enabled && webhookEnvVarName) {
def webhookUrl = env[webhookEnvVarName]
if (!webhookUrl) {
echo "钉钉 Webhook URL 未通过环境变量 ${webhookEnvVarName} 找到。跳过通知。"
return
}
def finalMessage = "BZPT.发布 (${jobName}#${buildNumber}):\n${message}"
if (author && author != "未知用户" && author.trim() != "") {
finalMessage += "\n@${author.trim()}"
}
def payload = groovy.json.JsonOutput.toJson([msgtype: "text", text: [content: finalMessage]])
def curlResult = sh script: """
echo "正在发送钉钉通知..."
curl -X POST -H 'Content-Type: application/json' -d '${payload}' '${webhookUrl}' --silent --show-error --connect-timeout 10 --max-time 15
""", returnStatus: true
if (curlResult != 0) {
echo "警告:钉钉通知可能发送失败 (curl 退出码: ${curlResult})。"
} else {
echo "钉钉通知发送成功。"
}
} else {
echo "钉钉通知已跳过 (可能已禁用、未设置 Webhook 凭证或未找到 Webhook URL 的环境变量)。"
}
}
pipeline {
agent any
// triggers 块现在会使用在 Jenkins UI 中配置的 SCM 信息进行轮询
triggers {
pollSCM('H/5 * * * *')
}
parameters {
// Git 参数现在主要用于 UI 显示和分支选择,实际 SCM 配置在 Job UI 中
string(name: 'GIT_REPO_URL', defaultValue: 'http://111.230.114.47:3000/yidongliang/gateway.git', description: 'Git 仓库 URL (仅供参考实际配置在Job的SCM部分)')
string(name: 'GIT_BRANCH', defaultValue: 'stage', description: '要拉取的 Git 分支 (例如develop, stage, master)')
credentials(name: 'GIT_CREDENTIALS_ID', defaultValue: 'jenkins', description: 'Git 凭证 ID', required: true)
// Docker 构建参数 (保持不变)
string(name: 'DOCKERFILE_PATH_IN_REPO', defaultValue: 'Dockerfile', description: '仓库中 Dockerfile 的路径')
string(name: 'DOCKER_REGISTRY_URL', defaultValue: 'https://106.52.199.114:5000', description: 'Docker 镜像仓库 URL。留空则不推送。')
string(name: 'DOCKER_IMAGE_NAME', defaultValue: 'bzpt.gateway', description: 'Docker 镜像名称')
string(name: 'IMAGE_BASE_TAG', defaultValue: '1.0', description: '镜像标签的基础部分')
credentials(name: 'DOCKER_CREDENTIALS_ID', defaultValue: 'dockerregister', description: 'Docker 镜像仓库凭证 ID', required: false)
booleanParam(name: 'PUSH_LATEST_TAG', defaultValue: true, description: '是否同时创建并推送 "latest" 标签?')
// 钉钉通知参数 (保持不变)
booleanParam(name: 'SEND_DINGTALK_NOTIFICATIONS', defaultValue: true, description: '是否发送钉钉通知?')
credentials(name: 'DINGTALK_WEBHOOK_CREDENTIAL_ID', defaultValue: 'stage-publish-dingding', description: '存储钉钉 Webhook URL 的凭证 ID', required: false)
}
environment {
LAST_COMMIT_AUTHOR = "gateway-stage"
DINGTALK_WEBHOOK_ENV_VAR_NAME = 'DINGTALK_WEBHOOK_URL_FROM_CREDS'
}
stages {
// =========================================================================
// **核心改动:不再需要“拉取代码”阶段。**
// 代码已由 Jenkins 根据 UI 配置自动检出。
// 第一个阶段直接开始进行初始化。
// =========================================================================
stage('0. 初始化和准备') {
steps {
// 清理工作空间是好习惯,但注意它会删除所有文件,包括 Jenkins 自动检出的代码。
// 如果需要重新检出,可以使用 checkout scm。但通常在此场景下不需要 cleanWs。
// 我们暂时保留它,因为它在您的原始脚本中。
cleanWs()
// **重要**:由于 cleanWs 删除了所有内容,我们需要再次检出代码。
// `checkout scm` 是一个特殊的步骤,它会使用在 Jenkins UI 中配置的 SCM 信息。
echo "重新检出代码以确保工作空间内容最新..."
checkout scm
script {
echo "代码已检出。开始初始化构建环境..."
// 构造带 registry 的完整镜像名
def preparedImageNameWithRegistry = params.DOCKER_IMAGE_NAME
env.PREPARED_IMAGE_NAME = preparedImageNameWithRegistry
echo "构建的镜像全名 (不含标签): ${env.PREPARED_IMAGE_NAME}"
// 现在可以安全地执行 git 命令
def shortCommit = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
env.IMAGE_TAG = "${params.IMAGE_BASE_TAG}.${BUILD_NUMBER}-${shortCommit}"
echo "生成的 IMAGE_TAG: ${env.IMAGE_TAG}"
try {
env.LAST_COMMIT_AUTHOR = sh(script: 'git log -1 --pretty=format:"%an"', returnStdout: true).trim()
} catch (e) {
echo "警告:无法获取最后提交的作者。 ${e.getMessage()}"
env.LAST_COMMIT_AUTHOR = "未知用户"
}
echo "最后提交的作者: ${env.LAST_COMMIT_AUTHOR}"
}
}
}
// 后续阶段保持不变,仅序号变更
stage('1. 构建 Docker 镜像') {
steps {
script {
def dockerfilePath = params.DOCKERFILE_PATH_IN_REPO
if (!fileExists(dockerfilePath)) {
error "在工作空间相对路径下未找到 Dockerfile: ${dockerfilePath}"
}
if (!env.PREPARED_IMAGE_NAME || !env.IMAGE_TAG) {
error "构建 Docker 镜像所需的 PREPARED_IMAGE_NAME 或 IMAGE_TAG 未设置。"
}
def fullImageNameWithTag = "${env.PREPARED_IMAGE_NAME}:${env.IMAGE_TAG}"
docker.build(fullImageNameWithTag, "-f \"${dockerfilePath}\" .")
echo "Docker 镜像 ${fullImageNameWithTag} 构建成功。"
if (params.PUSH_LATEST_TAG) {
def fullImageNameLatest = "${env.PREPARED_IMAGE_NAME}:latest"
sh "docker tag ${fullImageNameWithTag} ${fullImageNameLatest}"
echo "成功将镜像标记为: ${fullImageNameLatest}"
}
}
}
}
stage('2. 推送 Docker 镜像 (可选)') {
when { expression { params.DOCKER_REGISTRY_URL != "" } }
steps {
script {
def fullImageNameWithTag = "${env.PREPARED_IMAGE_NAME}:${env.IMAGE_TAG}"
def fullImageNameLatest = "${env.PREPARED_IMAGE_NAME}:latest"
docker.withRegistry(params.DOCKER_REGISTRY_URL, params.DOCKER_CREDENTIALS_ID) {
echo "正在推送镜像: ${fullImageNameWithTag}"
docker.image(fullImageNameWithTag).push()
echo "镜像 ${fullImageNameWithTag} 推送成功。"
if (params.PUSH_LATEST_TAG) {
echo "正在推送 latest 镜像: ${fullImageNameLatest}"
docker.image(fullImageNameLatest).push()
echo "镜像 ${fullImageNameLatest} 推送成功。"
}
}
}
}
}
}
// post 块定义无需任何修改,保持原样
post {
always {
echo "流水线结束。最终状态: ${currentBuild.result ?: 'IN PROGRESS'}"
}
success {
script {
if (params.SEND_DINGTALK_NOTIFICATIONS && params.DINGTALK_WEBHOOK_CREDENTIAL_ID) {
withCredentials([string(credentialsId: params.DINGTALK_WEBHOOK_CREDENTIAL_ID, variable: env.DINGTALK_WEBHOOK_ENV_VAR_NAME)]) {
sendDingTalkNotification(
message: "${params.DOCKER_IMAGE_NAME} 构建和推送成功。镜像: ${env.PREPARED_IMAGE_NAME}:${env.IMAGE_TAG}",
webhookEnvVarName: env.DINGTALK_WEBHOOK_ENV_VAR_NAME,
author: env.LAST_COMMIT_AUTHOR ?: '未知用户',
jobName: env.JOB_NAME,
buildNumber: env.BUILD_NUMBER,
enabled: params.SEND_DINGTALK_NOTIFICATIONS
)
}
}
}
}
failure {
script {
if (params.SEND_DINGTALK_NOTIFICATIONS && params.DINGTALK_WEBHOOK_CREDENTIAL_ID) {
withCredentials([string(credentialsId: params.DINGTALK_WEBHOOK_CREDENTIAL_ID, variable: env.DINGTALK_WEBHOOK_ENV_VAR_NAME)]) {
sendDingTalkNotification(
message: "${params.DOCKER_IMAGE_NAME} 构建失败。请检查控制台: ${env.BUILD_URL}console",
webhookEnvVarName: env.DINGTALK_WEBHOOK_ENV_VAR_NAME,
author: env.LAST_COMMIT_AUTHOR ?: '未知用户',
jobName: env.JOB_NAME,
buildNumber: env.BUILD_NUMBER,
enabled: params.SEND_DINGTALK_NOTIFICATIONS
)
}
}
}
}
aborted {
script {
if (params.SEND_DINGTALK_NOTIFICATIONS && params.DINGTALK_WEBHOOK_CREDENTIAL_ID) {
withCredentials([string(credentialsId: params.DINGTALK_WEBHOOK_CREDENTIAL_ID, variable: env.DINGTALK_WEBHOOK_ENV_VAR_NAME)]) {
sendDingTalkNotification(
message: "${params.DOCKER_IMAGE_NAME} 构建已中止。请检查控制台: ${env.BUILD_URL}console",
webhookEnvVarName: env.DINGTALK_WEBHOOK_ENV_VAR_NAME,
author: env.LAST_COMMIT_AUTHOR ?: '未知用户',
jobName: env.JOB_NAME,
buildNumber: env.BUILD_NUMBER,
enabled: params.SEND_DINGTALK_NOTIFICATIONS
)
}
}
}
}
}
}

View File

@ -1,3 +1,25 @@
# gateway
nginx 网关
nginx 网关
version: '3.9'
services:
traefik:
image: my-traefik:latest
container_name: traefik
ports:
- "8000:8000"
- "8002:8002"
- "8003:8003"
- "8080:8080"
volumes:
- ./traefik.yml:/etc/traefik/traefik.yml
- ./dynamic.yml:/etc/traefik/dynamic.yml
- ./certs:/etc/certs
restart: unless-stopped
参考地址
https://askmany.cn/chat/c970ddff-b553-4491-b4d3-a1572ed55db5

145
dynamic.yml Normal file
View File

@ -0,0 +1,145 @@
http:
routers:
# Sys Auth
sys-auth:
entryPoints: ["sys"]
rule: "PathPrefix(`/auth`)"
service: ids4
middlewares: [strip-auth, cors, ids4-hostfix]
sys-connect:
entryPoints: ["sys"]
rule: "PathPrefix(`/connect`)"
service: ids4
middlewares: [cors, ids4-hostfix]
sys-api:
entryPoints: ["sys"]
rule: "PathPrefix(`/api/sys`)"
service: sys-api
middlewares: [cors, auth-header, strip-api-sys]
sys-ui:
entryPoints: ["sys"]
rule: "PathPrefix(`/`)"
service: sys-ui
middlewares: [cors]
# LMG Auth
lmg-auth:
entryPoints: ["lmg"]
rule: "PathPrefix(`/auth`)"
service: ids4
middlewares: [strip-auth, cors, ids4-hostfix]
lmg-api:
entryPoints: ["lmg"]
rule: "PathPrefix(`/api/lmg`)"
service: lmg-api
middlewares: [cors, auth-header, strip-api-lmg]
lmg-ui:
entryPoints: ["lmg"]
rule: "PathPrefix(`/`)"
service: lmg-ui
middlewares: [cors]
# Healthy Auth
healthy-auth:
entryPoints: ["healthy"]
rule: "PathPrefix(`/auth`)"
service: ids4
middlewares: [strip-auth, cors, ids4-hostfix]
healthy-api:
entryPoints: ["healthy"]
rule: "PathPrefix(`/api/healthy`)"
service: healthy-api
middlewares: [cors, auth-header, strip-api-healthy]
healthy-ui:
entryPoints: ["healthy"]
rule: "PathPrefix(`/`)"
service: healthy-ui
middlewares: [cors]
services:
ids4:
loadBalancer:
servers:
- url: "https://sys-api:8001"
serversTransport: ids4-transport
sys-api:
loadBalancer:
servers:
- url: "https://sys-api:8001"
serversTransport: ids4-transport
sys-ui:
loadBalancer:
servers:
- url: "http://sys-ui:80"
lmg-api:
loadBalancer:
servers:
- url: "https://lmg-api:19904"
serversTransport: ids4-transport
lmg-ui:
loadBalancer:
servers:
- url: "http://lmg-ui:80"
healthy-api:
loadBalancer:
servers:
- url: "https://healthy-api:19906"
serversTransport: ids4-transport
healthy-ui:
loadBalancer:
servers:
- url: "http://healthy-ui:80"
serversTransports:
ids4-transport:
insecureSkipVerify: true
middlewares:
cors:
headers:
accessControlAllowOriginList: ["*"]
accessControlAllowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
accessControlAllowHeaders: ["Authorization", "Content-Type"]
accessControlAllowCredentials: true
addVaryHeader: true
strip-auth:
stripPrefix:
prefixes: ["/auth"]
strip-api-sys:
stripPrefix:
prefixes: ["/api/sys"]
strip-api-lmg:
stripPrefix:
prefixes: ["/api/lmg"]
strip-api-healthy:
stripPrefix:
prefixes: ["/api/healthy"]
ids4-hostfix:
headers:
customRequestHeaders:
Host: "192.168.1.100:8001"
X-Forwarded-Host: "192.168.1.100:8001"
X-Forwarded-Proto: "https"
auth-header:
headers:
customRequestHeaders:
Authorization: "{header:Authorization}"

27
traefik.yml Normal file
View File

@ -0,0 +1,27 @@
entryPoints:
sys:
address: ":8000"
http:
maxRequestBodyBytes: 104857600 # 100MB
lmg:
address: ":8002"
http:
maxRequestBodyBytes: 104857600
healthy:
address: ":8003"
http:
maxRequestBodyBytes: 104857600
api:
dashboard: true
insecure: true
providers:
file:
filename: /etc/traefik/dynamic.yml
watch: true
tls:
certificates:
- certFile: /etc/certs/gateway.crt
keyFile: /etc/certs/gateway.key