# ═══════════════════════════════════════════════════════════ # 生产环境(prod) # # ⚠️⚠️ 这个文件里**一个密钥都没有,也永远不要加**。 # 全部由环境变量提供;缺失时 **ProdGuard 会拒绝启动** # (见 config/ProdGuard.java —— 那 6 条都是"配错了也能启动、 # 而且运行时完全不报错"的配置)。 # # ── 必需的环境变量 ────────────────────────────────────── # 数据库 PG_HOST PG_PORT PG_DB PG_USER PG_PASSWORD # 缓存 REDIS_HOST REDIS_PORT REDIS_PASSWORD # 密钥 XT_JWT_SECRET HS512,≥ 64 字节随机值 # XT_AES_KEY AES-256,base64,**用于证件号加密** # XT_HMAC_KEY HMAC,用于开放接口签名 # XT_RSA_PRIVATE_KEY PKCS#8 单行 base64(登录密码解密) # 存储 XT_STORAGE_PROVIDER=qiniu # QINIU_ACCESS_KEY QINIU_SECRET_KEY QINIU_BUCKET QINIU_DOMAIN # 微信 WX_MP_APP_ID WX_MP_APP_SECRET (小程序) # WX_H5_APP_ID WX_H5_APP_SECRET (公众号网页授权) # WX_H5_CALLBACK WX_H5_BASE_URL (必须是 https 正式域名) # 其他 H5_STATIC_DIR(H5 构建产物目录) # # ⚠️ 密钥怎么生成、怎么轮换、轮换时要注意什么,见 # docs/09-部署与运维.md §3「密钥与凭据」。 # ═══════════════════════════════════════════════════════════ spring: datasource: url: jdbc:postgresql://1Panel-postgresql-v7DP:5432/shenxue?stringtype=unspecified username: shenxue password: RC6Bhnmbz8mk4p4z hikari: # 生产把池子放大一些:导出打包是长事务,会占住连接 minimum-idle: 10 maximum-pool-size: 40 data: redis: host: 1Panel-redis-mIkk port: 6379 password: redis_GWnh6E database: 0 flyway: # ⚠️⚠️ 生产**禁止 clean**。它是"清空整个库再重建", # 在生产上执行等于把所有学校的填报数据删掉。 # 流水线里也不要用 flyway clean —— 见部署文档的回滚一节。 clean-disabled: true # 迁移文件发布后不许改(改了校验失败)。这是保护:它保证 # "生产跑的迁移"与"仓库里的迁移"逐字节一致 validate-on-migrate: true # ⚠️ 这里**没有** static-locations:H5 由 nginx/网关托管,不落在后端 # (2026-10 架构调整,见 application.yml 的 spring.web.resources.add-mappings)。 # 发布时要注意的是**换了个东西发**:H5 产物由部署流程放到 nginx 的站点目录, # 仍然要"和后端一起发" —— 前后端不同步还是会出现"页面调用了还不存在的接口"。 # # 历史(留着是有用的):它曾经是 `file:/opt/xt/h5/`,由本服务直接对外发 H5。 server: # 生产在反向代理后面:让 Spring 认 X-Forwarded-* , # 否则生成的回调地址会是 http://内网IP:8080 forward-headers-strategy: framework tomcat: # 上传是长连接,生产放宽(学生可能从聊天记录里选一个 40MB 的文件) connection-timeout: 120s threads: max: 200 min-spare: 20 logging: level: root: warn cn.tianbaotong.fill: info file: # ⚠️ 日志按天滚动并保留 30 天:审计要能回答"上周三谁看过那份证件号" name: ${XT_LOG_DIR:/var/log/xt}/xt-server.log logback: rollingpolicy: max-history: 30 max-file-size: 200MB total-size-cap: 20GB # 生产关掉接口文档:它会把全部接口与字段暴露给公网。 # ProdGuard 会检查这一条 —— 开着就拒绝启动。 springdoc: api-docs: enabled: false swagger-ui: enabled: false management: endpoints: web: exposure: # 生产只暴露健康检查(给负载均衡探活) include: health endpoint: health: show-details: never fill: jwt: secret: ${XT_JWT_SECRET} crypto: aes-key: ${XT_AES_KEY} hmac-key: ${XT_HMAC_KEY} rsa: private-key: ${XT_RSA_PRIVATE_KEY} security: login-max-fail: 5 login-lock-minutes: 15 captcha-after-fails: 2 storage: # 生产必须 qiniu(local 在多副本下必然丢文件,ProdGuard 会拦) provider: qiniu prefix: xiaotutongxue keep-raw: ${XT_STORAGE_KEEP_RAW:false} self-check-on-startup: ${XT_STORAGE_SELF_CHECK:true} qiniu: access-key: ${QINIU_ACCESS_KEY} secret-key: ${QINIU_SECRET_KEY} bucket: ${QINIU_BUCKET} domain: ${QINIU_DOMAIN} region: ${QINIU_REGION:auto} signed-url-expire-seconds: 1800 mini-program: app-id: ${WX_MP_APP_ID} app-secret: ${WX_MP_APP_SECRET} # ⚠️ 正式发布后用 release。用 trial/develop 生成的码扫开会提示 # 「小程序未发布」,而**接口不报错** —— 只会让人以为码生成得不对 env-version: ${WX_MP_ENV_VERSION:release} page: pages/index/index public-base-url: ${WX_MP_PUBLIC_BASE_URL} code-cache-days: 30 mp-h5: app-id: ${WX_H5_APP_ID} app-secret: ${WX_H5_APP_SECRET} callback-url: ${WX_H5_CALLBACK} h5-base-url: ${WX_H5_BASE_URL} # ⚠️⚠️ 生产**必须** false。开了它就是"任何人可登录任何学生"。 # 这是 ProdGuard 的第一条检查,写成 true 直接拒绝启动。 stub-enabled: false tenant-domain: enabled: ${XT_TENANT_DOMAIN_ENABLED:false} base: ${XT_TENANT_DOMAIN_BASE:} scheme: https