Files
FruitServer/fruitshorts-app-api/src/main/resources/application.yml
T
jianghaifeng b567365460 feat(deploy): D1 后端部署就绪(配置外置 + prod fail-fast + 自包含 Compose + 冒烟/回滚)
为什么:用户下午要部署,但全仓没有任何部署产物;且生产漏配密钥会静默使用代码里的 dev 默认值,
属上线阻塞项(04-部署架构 / 12-上线检查清单)。

- 配置外置(三件):DB_URL、JWT 双密钥(**发现 app-secret 此前没外置,一直用 dev 默认值**)、
  MEDIA_SIGNATURE_SECRET、MEDIA_SIGNATURE_REQUIRED、CORS_ALLOWED_ORIGINS、MEDIA_ROOT_DIR
- 新增三份 application-prod.yml:签名强制开启、CORS 收紧、媒资指向挂载点、日志级别
- 新增 ProdSecretGuard(@Profile("prod")):密钥缺失/仍是 dev 默认值/不足 32 位、签名未开、
  DB_URL 或 CORS 为空 → 一次列全并终止启动(exit 1)
- 新增 /healthz 轻量健康端点:查明 /actuator/health 的"超时"是旧 jar 未重启所致,项目本就
  没有 actuator 依赖,故不引新依赖;同时把 /healthz 加进安全白名单
- Docker 化:多阶段 Dockerfile(非 root、tini、依赖层缓存、ffmpeg 只给 worker)、.dockerignore、
  自包含 docker-compose.yml(含 PostgreSQL 18 + Redis + 命名卷 + 按序初始化 sql + healthcheck)
- tools/smoke.sh(失败非 0 退出)+ DEPLOY.md(Compose 主线 / 裸 jar 兜底 / 回滚 / 故障速查)
- 实测:mvn test 83 条全过;两入口 package 通过;prod 缺密钥退出码 1 且报错明确、配齐后正常启动;
  冒烟脚本全 PASS;本机无 Docker,镜像与 compose 未经构建验证(已在回执如实标注)
2026-10-16 13:01:08 +08:00

92 lines
3.5 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Author: fruit.com.cn
server:
port: 8081
spring:
application:
name: fruitshorts-app-api
autoconfigure:
exclude: org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration
datasource:
driver-class-name: org.postgresql.Driver
# 地址必须外置:不同环境(本机 / 测试 / 生产)连的库不一样,
# 生产请用 DB_URL 注入(prod profile 会校验它非空)
url: ${DB_URL:jdbc:postgresql://127.0.0.1:5432/fruitshorts}
username: ${DB_USER:fruitshorts}
password: ${DB_PASSWORD:fruitshorts}
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: Asia/Shanghai
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
global-config:
banner: false
db-config:
# 主键由应用侧雪花算法生成(S0),数据库不再自增
id-type: assign_id
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
sequence:
# 单机开发用固定值;上多实例前必须改成按实例分配(环境变量注入),否则会撞 ID
worker-id: 1
datacenter-id: 1
# 接口文档:/doc.html 打开 Swagger UI,/v3/api-docs 是机器可读契约(前端联调按它写)
springdoc:
swagger-ui:
path: /doc.html
api-docs:
path: /v3/api-docs
fruitshorts:
interaction:
# MACHINE_FIRST:机审通过即发布,命中 REVIEW 级敏感词才转人工
# PRE_REVIEW :全部先审后发(生产建议)
comment-audit-mode: MACHINE_FIRST
comment-max-length: 500
comment-per-minute: 5
download:
# 这些值会通过 /app/downloads/policy 下发给客户端,改这里不用发版
max-per-device: 20
license-days: 30
wifi-only-default: true
max-quality: AUTO
commerce:
store:
# 商店票据校验实现:disabled = 明确报"未配置"(默认,无凭据时对外行为不变)
# google-play = 走 Google Play Developer API
verifier: ${STORE_VERIFIER:disabled}
# 下面两项属付费凭据:只从环境变量/配置注入,不入库、不提交、不打进镜像
google-play-package-name: ${GOOGLE_PLAY_PACKAGE_NAME:}
# 服务账号 JSON:文件路径 \| JSON 内容 \| base64(建议用环境变量给 base64)
google-play-service-account-json: ${GOOGLE_PLAY_SERVICE_ACCOUNT_JSON:}
google-play-timeout-seconds: 10
media:
# 媒体根目录:容器里指向挂载卷;本地默认 ./data/uploads
root-dir: ${MEDIA_ROOT_DIR:./data/uploads}
public-prefix: /files
chunk-size: 5242880
max-file-size: 2147483648
# 播放地址签名:生产必开(docs/12-上线检查清单),prod profile 里强制为 true
signature-secret: ${MEDIA_SIGNATURE_SECRET:fruitshorts-media-dev-secret-change-me-in-production-32b}
signature-required: ${MEDIA_SIGNATURE_REQUIRED:false}
signature-ttl-minutes: 15
jwt:
# 双密钥:管理端与客户端物理隔离,token 不能互换(AGENTS.md 强制约束 2)
# 注意 app-secret 以前没写在这里,一直用代码里的 dev 默认值 —— 生产必须注入 JWT_APP_SECRET
admin-secret: ${JWT_ADMIN_SECRET:fruitshorts-admin-dev-secret-change-me-in-production-32b}
admin-ttl-hours: 12
app-secret: ${JWT_APP_SECRET:fruitshorts-app-dev-secret-change-me-in-production-32bytes}
app-access-ttl-minutes: 120
app-refresh-ttl-days: 30
cors:
allowed-origins: ${CORS_ALLOWED_ORIGINS:*}
logging:
level:
com.fruitshorts: info