diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 517fe3a..f933330 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -1,9 +1,11 @@ name: ci-bschclass-service # 后端标准化 CI:maven 构建 jar -> docker build -> 推 Nexus docker-hosted -# 触发:push 到 master(本仓库默认分支,代码在根目录)/ 手动 Run workflow +# 触发:push 到 master(本仓库默认分支)/ 手动 Run workflow +# ⚠️ 本 workflow 不再负责部署:镜像推完后由 projman 平台接管(DeployTab 选 tag 手动触发部署, +# 平台负责 compose 渲染 / 配置挂载 / 健康检查 / Caddy 路由)。 # 依赖仓库 Actions Secrets:NEXUS_USER / NEXUS_PASSWORD(ci-docker 账号,仅 docker-hosted 推送权) -# 中间件密码(redis/mysql/rabbitmq)由 Nacos application-infra.yaml 注入,无需 Secret,也不注入容器 env +# 中间件连接由 projman 平台按「infra 勾选」注入容器 env,无需 Secret on: push: branches: [master] @@ -13,10 +15,6 @@ on: description: 'image tag (default = short sha)' required: false default: 'auto' - deploy: - description: 'deploy to 160 after build (auto / skip)' - required: false - default: 'auto' jobs: build-and-push: @@ -83,65 +81,4 @@ jobs: run: docker push nexus:8083/docker-hosted/bschclass-service:${{ steps.meta.outputs.tag }} - name: Report build - run: echo "pushed nexus:8083/docker-hosted/bschclass-service:${{ steps.meta.outputs.tag }}" - - # —— 部署阶段(仅在 push 或手动 dispatch deploy=auto 时执行)—— - # 运行在 160 的 act_runner 上,复用宿主 docker daemon(docker.sock 由 act_runner 自动挂载), - # 因此 docker pull / run 直接作用于 160 宿主。 - - name: Deploy (pull + rollout with rollback) - if: github.event_name == 'push' || inputs.deploy == 'auto' - run: | - set +e - IMG=nexus:8083/docker-hosted/bschclass-service:${{ steps.meta.outputs.tag }} - echo "deploying $IMG" - echo "${{ secrets.NEXUS_PASSWORD }}" | docker login nexus:8083 -u ${{ secrets.NEXUS_USER }} --password-stdin - docker pull "$IMG" - # 回滚锚:保留当前 bschclass-service:latest(已知良好镜像),再额外打一个时间点标签 - RB=bschclass-service:rb-$(date +%s) - docker tag bschclass-service:latest "$RB" 2>/dev/null || true - docker stop bschclass-service 2>/dev/null; docker rm -f bschclass-service 2>/dev/null - # bootstrap.yml 默认 nacos.config.enabled=false(本地不连);CI 必须注入 NACOS_CONFIG_ENABLED=true 才会拉配置 - # SPRING_PROFILES_ACTIVE=prod 激活生产 profile - # namespace/凭据用顶层 SPRING_CLOUD_NACOS_* env(bootstrap 的 ${...} 占位符才能解析到) - # ⚠️ 后端有 context-path=/bschclass(application-prod.yml),caddy 用 handle(不剥离 /bschclass 前缀), - # 故 CAS 客户端拼出的 service URL 正确包含 /bschclass,登录回跳地址不会丢前缀。 - docker run -d --name bschclass-service --restart unless-stopped --network infra-infra-net -p 8087:8087 \ - --add-host sso.yunhaixingtong.com:192.168.10.160 \ - --memory=1.5g --memory-swap=1.5g \ - -v /data/logs/bschclass:/app/logs \ - -e JAVA_OPTS="-Xms512m -Xmx1024m -XX:MaxMetaspaceSize=256m" \ - -e SPRING_PROFILES_ACTIVE=prod \ - -e NACOS_CONFIG_ENABLED=true \ - -e NACOS_ADDR=nacos:8848 \ - -e SPRING_CLOUD_NACOS_CONFIG_NAMESPACE=6196f0de-a28d-4894-8f10-e2982b57c6bc \ - -e SPRING_CLOUD_NACOS_USERNAME=yh-reader \ - -e SPRING_CLOUD_NACOS_PASSWORD=123456 \ - "$IMG" - # 健康检查:context-path=/bschclass 后,context root 为 /bschclass/(无欢迎页返回 404); - # 000 表示应用未起来(端口不通),非 000 即视为已启动。探 /bschclass/ 而非 / 更准确。 - OK=0 - for i in $(seq 1 30); do - sleep 5 - CODE=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8087/bschclass/ 2>/dev/null || true) - if [ "$CODE" != "000" ]; then OK=1; break; fi - done - if [ "$OK" = "0" ]; then - echo "!! UNHEALTHY -> rollback to bschclass-service:latest" - docker stop bschclass-service 2>/dev/null; docker rm -f bschclass-service 2>/dev/null - docker run -d --name bschclass-service --restart unless-stopped --network infra-infra-net -p 8087:8087 \ - --add-host sso.yunhaixingtong.com:192.168.10.160 \ - --memory=1.5g --memory-swap=1.5g \ - -v /data/logs/bschclass:/app/logs \ - -e JAVA_OPTS="-Xms512m -Xmx1024m -XX:MaxMetaspaceSize=256m" \ - -e SPRING_PROFILES_ACTIVE=prod \ - -e NACOS_CONFIG_ENABLED=true \ - -e NACOS_ADDR=nacos:8848 \ - -e SPRING_CLOUD_NACOS_CONFIG_NAMESPACE=6196f0de-a28d-4894-8f10-e2982b57c6bc \ - -e SPRING_CLOUD_NACOS_USERNAME=yh-reader \ - -e SPRING_CLOUD_NACOS_PASSWORD=123456 \ - bschclass-service:latest - echo "rolled back"; exit 7 - fi - echo "DEPLOY OK: $IMG" - docker tag "$IMG" bschclass-service:latest - docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}' | grep bschclass || true + run: echo "pushed nexus:8083/docker-hosted/bschclass-service:${{ steps.meta.outputs.tag }} —— 部署请到 projman 平台 DeployTab 手动触发" diff --git a/docker/Dockerfile b/docker/Dockerfile index 855d0f2..8aa6674 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -10,8 +10,8 @@ RUN apt-get update \ WORKDIR /app COPY target/BschClass-0.1.jar /app/BschClass-0.1.jar -# 镜像内 application-prod.yml 仅作「nacos 不可达时的兜底默认」; -# 正常启动由 run-app.sh 从 nacos 拉取线上配置(主 dataId=bschclassmanage.yaml,group=SCHCLASSMANAGE,prod 命名空间)后覆盖。 +# 镜像内 application-prod.yml 仅作独立运行时的兜底默认; +# projman 部署时平台配置档案会以 bind mount 覆盖同路径文件,环境变量再压过文件。 COPY docker/application-prod.yml /app/config/application-prod.yml COPY docker/run-app.sh /app/run-app.sh RUN chmod +x /app/run-app.sh && mkdir -p /data/upload diff --git a/docker/application-prod.yml b/docker/application-prod.yml index f54423a..eccf1e8 100644 --- a/docker/application-prod.yml +++ b/docker/application-prod.yml @@ -1,7 +1,14 @@ -# BschClass 生产配置(线上以 nacos 的 bschclassmanage.yaml 为准,本文件是 nacos 不可达时的兜底) -server: - port: 8087 - # 无 context-path:经 caddy 暴露为 http://base.yunhaixingtong.com/bschclass,caddy 已剥离 /bschclass 前缀 +# ============================================================== +# BschClass 生产配置(projman 应用配置档案;同一份内容烤进镜像作独立运行兜底) +# -------------------------------------------------------------- +# 加载顺序(低 -> 高): +# jar 内 application.yml(本地开发自己的,写本地 redis/DB) +# < 本文件(projman 挂载 /app/config/application-prod.yml,SPRING_PROFILES_ACTIVE=prod) +# < 平台注入环境变量(SERVER_PORT / SPRING_DATASOURCE_* / SPRING_REDIS_* / SPRING_RABBITMQ_* / SSO / FILE_WEB_PATH) +# ⚠️ 覆盖是 key 级合并非整文件替换;env 压过本文件。 +# 本文件只放:appKey/appSecret、业务开关、JPA/Hikari 口径、日志级别。 +# 不要放:端口/contextPath(SERVER_* env 注入)、平台供给的 DB/中间件连接(勾选 infra 后 env 注入)。 +# ============================================================== spring: mvc: @@ -14,36 +21,17 @@ spring: time-zone: GMT+8 date-format: yyyy-MM-dd HH:mm:ss - redis: - host: redis - port: 6379 - database: 0 - # 密码由 nacos application-infra.yaml 注入(spring.redis.password),不在此写死、不依赖容器 env - timeout: 2000ms - data: - redis: - repositories: - enabled: false - - # datasource: - # url: jdbc:mysql://mysql8:3306/dbschoolclass?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true - # username: root - # # 生产由 nacos application-infra.yaml 注入(含密码);此处仅作 nacos 不可达时的兜底参考 - # password: ${DB_PASSWORD} - # driver-class-name: com.mysql.cj.jdbc.Driver - # min-idle: 30 - # max-active: 30 - # hikari: - # minimum-idle: 20 - # maximum-pool-size: 500 - # connection-timeout: 600000 - # idle-timeout: 120000 - # leakDetectionThreshold: 300000 - # auto-commit: true - # max-lifetime: 1800000 - # validation-timeout: 3000 - # connection-test-query: SELECT 1 FROM DUAL - # connection-init-sql: SET NAMES utf8mb4 + datasource: + hikari: + # 连接治理(平台口径):泄漏 60s 打堆栈现形;拿不到连接快速失败而非干等 600s + minimum-idle: 10 + maximum-pool-size: 30 + connection-timeout: 10000 + leak-detection-threshold: 60000 + max-lifetime: 1800000 + validation-timeout: 3000 + connection-test-query: SELECT 1 + connection-init-sql: SET NAMES utf8mb4 jpa: database: MySQL @@ -58,11 +46,8 @@ spring: open-in-view: true rabbitmq: - host: rabbitmq - port: 5672 - username: admin - # 密码由 nacos application-infra.yaml 注入(spring.rabbitmq.password),不在此写死、不依赖容器 env listener: + # 业务开关:消费端不随应用自动启动(保留原 Nacos 生产行为,与连接注入无关) direct: auto-startup: false simple: @@ -71,22 +56,25 @@ spring: # 单点登录 / 应用间签名鉴权(基础平台 yh-auth / yh-app-auth) yh: sso: - server-url-prefix: http://sso.yunhaixingtong.com/cas/ - client-host-url: http://base.yunhaixingtong.com/bschclass + # server-url-prefix / client-host-url 由平台按平台设置注入(改地址 Apply 即生效),此处不写 allow-headers: all allow-origins: all url-pattern: /api/* mobi-api-pattern: /mobiapi/* app-auth: enabled: true + app-key: 100002 + app-secret: 2314a3b158b24a838b2b9b69fd3db118 + open: + enabled: true + # base-host 由平台注入;此处仅保留相对路径约定 + user-center-url: http://base.yunhaixingtong.com/userbase + group-center-url: http://base.yunhaixingtong.com/userbase -# 上传文件落容器卷(docker 内 /data/upload) +# 上传文件落容器卷 /data/upload(平台挂载宿主持久目录,勿改) FILE_PATH: /data/upload -FILE_WEB_PATH: http://base.yunhaixingtong.com/bschclass/upload/ -UPLOAD_WEB_PATH_HTTP: http://base.yunhaixingtong.com/bschclass/upload/file/ +# FILE_WEB_PATH / UPLOAD_WEB_PATH_HTTP 由平台注入 {portal}/bschclass/upload/...,此处不写 logging: level: root: INFO - file: - path: /app/logs diff --git a/docker/run-app.sh b/docker/run-app.sh index 81e8956..7fa16a7 100644 --- a/docker/run-app.sh +++ b/docker/run-app.sh @@ -1,10 +1,11 @@ #!/bin/sh -# BschClass 启动入口:配置统一由 Nacos 配置中心在 bootstrap 阶段下发(见 bootstrap.yml) -# 不再需要手动 curl 拉取;若 nacos 不可达,bootstrap 中 fail-fast=false 会自动回退到 -# 镜像内烤好的 application-prod.yml 兜底默认。 +# BschClass 启动入口。 +# 配置来源(低 -> 高):镜像内兜底 /app/config/application-prod.yml +# < projman 平台挂载的同名文件(覆盖镜像内兜底) +# < 平台注入的环境变量(SERVER_PORT / 数据库连接 / 中间件 / SSO 等) set -e -echo "[run-app] starting BschClass (profile=prod, nacos=${NACOS_ADDR:-nacos.yunhaixingtong.com:8848}) ..." +echo "[run-app] starting BschClass (profile=${SPRING_PROFILES_ACTIVE:-prod}) ..." exec java ${JAVA_OPTS:--Xms512m -Xmx1024m} -Dfile.encoding=UTF-8 -jar /app/BschClass-0.1.jar \ - --spring.profiles.active=prod + --spring.profiles.active=${SPRING_PROFILES_ACTIVE:-prod} diff --git a/pom.xml b/pom.xml index 6e70a24..f9a77ce 100644 --- a/pom.xml +++ b/pom.xml @@ -30,14 +30,6 @@ pom import - - - com.alibaba.cloud - spring-cloud-alibaba-dependencies - 2021.0.5.0 - pom - import - @@ -53,16 +45,10 @@ spring-boot-starter-jdbc - + - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-config - - - - org.springframework.cloud - spring-cloud-starter-bootstrap - 3.1.8 + org.springframework.boot + spring-boot-starter-actuator diff --git a/service.zip b/service.zip new file mode 100644 index 0000000..c57989d Binary files /dev/null and b/service.zip differ diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml deleted file mode 100644 index 2e6149d..0000000 --- a/src/main/resources/application-dev.yml +++ /dev/null @@ -1,14 +0,0 @@ -server: - address: 0.0.0.0 - port: 8086 - -spring: - web: - cors: - enabled: false - -yh: - sso: - client-host-url: http://192.168.10.166:8086 - -FILE_WEB_PATH: http://localhost:8086/upload/ \ No newline at end of file diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml deleted file mode 100644 index 8bb96c4..0000000 --- a/src/main/resources/application-prod.yml +++ /dev/null @@ -1,13 +0,0 @@ -server: - address: 0.0.0.0 - port: 8087 - servlet: - # 对齐 UserBase:后端加 context-path,配合 Caddy 用 handle(不剥离 /bschclass 前缀), - # 使 CAS 客户端拼出的 service URL 正确包含 /bschclass(否则登录回跳会丢前缀)。 - context-path: /bschclass - -yh: - sso: - client-host-url: http://192.168.10.166:8087 - -FILE_WEB_PATH: http://localhost:8087/upload/ \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 8fbdb55..65de5c7 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,4 +1,9 @@ spring: + application: + name: bschclassmanage + # 本地默认 local(纯走本文件);线上由平台注入 SPRING_PROFILES_ACTIVE=prod(容器 env) + profiles: + active: ${SPRING_PROFILES_ACTIVE:local} mvc: date-format: yyyy-MM-dd HH:mm:ss servlet: diff --git a/src/main/resources/bootstrap.yml b/src/main/resources/bootstrap.yml deleted file mode 100644 index 7a9059a..0000000 --- a/src/main/resources/bootstrap.yml +++ /dev/null @@ -1,47 +0,0 @@ -spring: - application: - name: bschclassmanage - # 本地默认 local(不连 nacos);CI 注入 SPRING_PROFILES_ACTIVE=prod - profiles: - active: ${SPRING_PROFILES_ACTIVE:local} - cloud: - nacos: - config: - # ⭐ 本地默认关闭 nacos(profile=local 时完全不连,无 403 噪音,纯走 application.yml) - # CI 注入 NACOS_CONFIG_ENABLED=true 才启用,拉 prod namespace 配置覆盖 application.yml - enabled: ${NACOS_CONFIG_ENABLED:false} - # Nacos 配置中心地址;CI 注入 NACOS_ADDR=nacos:8848(容器内网别名) - server-addr: ${NACOS_ADDR:nacos.yunhaixingtong.com:8848} - # 默认指向 prod namespace UUID,避免本地误开时连到空的 dev 命名空间 - # CI 用 SPRING_CLOUD_NACOS_CONFIG_NAMESPACE 覆盖(注意:NACOS_NAMESPACE 这个 env 名不生效,必须用 SPRING_CLOUD_NACOS_CONFIG_NAMESPACE) - namespace: ${SPRING_CLOUD_NACOS_CONFIG_NAMESPACE:6196f0de-a28d-4894-8f10-e2982b57c6bc} - # 主配置 group:userbase.yaml 在 USERBASE group(与下方 shared-configs 的 DEFAULT_GROUP 不同组,各自指定) - group: SCHCLASSMANAGE - # 配置文件格式;最终主配置 dataId = ${spring.application.name}.${file-extension} = userbase.yaml - file-extension: yaml - encode: UTF-8 - # nacos 不可达时不强制退出,回退到本地 application.yml 兜底 - fail-fast: false - # 只读账号(仅读取配置权限);CI 注入 SPRING_CLOUD_NACOS_USERNAME/PASSWORD - # 注意:凭据必须用顶层 SPRING_CLOUD_NACOS_* env,放在 spring.cloud.nacos.config.* 下不生效(403) - username: ${SPRING_CLOUD_NACOS_USERNAME:yh-reader} - password: ${SPRING_CLOUD_NACOS_PASSWORD:123456} - - # ============================================================ - # ⭐⭐⭐ 共享配置加载顺序(决定优先级!:排在数组越靠后 = 优先级越高 = 覆盖前面的同 key) - # 低 1) public 命名空间 application-default.yaml(跨环境公共:日期格式/上传大小等,所有应用都能继承) - # 中 2) prod 命名空间 application-infra.yaml(仅生产:mysql/redis/rabbitmq 中间件连接) - # 高 3) prod 命名空间 userbase.yaml(应用级主配置:上传路径/context-path/CAS等,覆盖前两个) - # 最高 4) 启动命令 -D 参数 / 环境变量(覆盖一切) - # ============================================================ - shared-configs: - # ① 1 号(最低优先级):public 命名空间(namespace="" 固定写空字符串)的 application-default.yaml - - data-id: application-default.yaml - group: DEFAULT_GROUP - namespace: "" # ⭐ 固定 = "",强制指向 Nacos "public" 命名空间,不读上面的全局 prod namespace - refresh: false - - # ② 2 号(中等优先级):prod 命名空间(不写 namespace = 继承顶部全局 prod namespace id)的 application-infra.yaml - - data-id: application-infra.yaml - group: DEFAULT_GROUP - refresh: false \ No newline at end of file diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index 20612de..91c0f5f 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -16,8 +16,8 @@ /app/logs/app.log - /app/logs/app.%d{yyyy-MM-dd}.log - 30 + /app/logs/app.%d{yyyy-MM-dd}.log.zip + 60 5GB