部署
框架 repo 的 deploy/ 附了可直接參考的 Dockerfile(multi-stage、distroless、在映像內用 pinned 工具重新產生 proto)與 docker-compose(含 otelcol、Prometheus、Grafana、PgBouncer 設定)。以下三件事是框架刻意不代勞、部署者必須自己接的。
Scaffold 的 secret preflight
Section titled “Scaffold 的 secret preflight”新 scaffold 會帶有本機開發用設定;在第一次 git add、Docker build 或交給 CI 前,先檢查 secret 是否已外部化。不要把可用 JWT signing secret 留在版控或 image layer。
- 將 real secret 交給 secret manager、mounted file 或 runtime environment,以 GORTEXA_AUTH__JWT_SECRET 注入。
- 讓 repo 只保留不可用的 placeholder 或不含 secret 的範例設定;local override 應被忽略。
- 讓 Docker build context 與 runtime image 都不含 local secret config,並驗證 image 只由 runtime injection 啟動。
- 規劃 rotation、issuer 與 audience;共享 secret 的服務應設定不同 audience。
這是 deployment gate,不是可選的「稍後再做」。同樣地,scaffold 的 in-memory resource 只適合 demo;在 readiness 之前先建立真實的 storage、cache、MQ lifecycle。
TLS 在前面終結
Section titled “TLS 在前面終結”服務的 port 是 cleartext h2c,伺服器本身不做 TLS。bearer token 經過這個 port 是明文的。把服務放在反向代理、service mesh 或 load balancer 後面終結 TLS,不要把 h2c port 直接暴露到公網。
Readiness 接真實依賴
Section titled “Readiness 接真實依賴”/readyz 預設只反映行程本身活著。用 app.Health().Register(...) 註冊 DB、cache、MQ 的真實檢查,readiness 才有參考價值:
app.Health().Register("postgres", func(ctx context.Context) health.State { if err := pool.Ping(ctx); err != nil { return health.Unhealthy } return health.Healthy})每個 check 有 5 秒逾時,單一慢依賴不會拖垮整個查詢。
health probe 可綁在私有 ops 埠、與對外埠分離:kernel.WithAdminListener(addr) 在獨立的 plain-HTTP 埠只服務 /healthz 與 /readyz,讓 orchestrator 探測健康時不必碰到公開的 h2c 埠(app.AdminAddr() 可查實綁位址)。要在獨立埠上掛 pprof 或自訂 ops handler,用 kernel.WithExtraListener(lis, h)。兩者皆 opt-in,主 h2c 埠的單埠多工不變。
Authorization 是應用程式的事
Section titled “Authorization 是應用程式的事”框架只做 authentication:驗 JWT 簽章、把 claims 放進 context。誰能做什麼(role、permission policy)由應用程式在 handler 或自己的攔截器裡判斷:
claims, ok := auth.ClaimsFrom(ctx)if !ok || !slices.Contains(claims.Roles, "admin") { // 拒絕}Graceful shutdown
Section titled “Graceful shutdown”收到 SIGTERM 後,伺服器在 server.shutdown_timeout(預設 20s)內排空 in-flight 請求再退出。負載中中斷的行為驗證見範例 05。
server.reflection保持false:不對外暴露服務結構。observ.otlp_insecure連遠端 collector 時必須false。- 真實 secret 走 runtime injection,且不得存在於 Git 或 image layer,見設定。