三轮审查修复(60+ 项),相对远端 main(b536672)的关键变更:
- 安全: 数据面 SSRF 拨号防护(防 DNS rebinding)/上游凭据剥离/登录防枚举
与锁定态统一/可信代理(X-Forwarded-For)限流加固/会话版本失效机制/
撤销即时传播/弱密钥拒绝启动/脱敏字节级重写(保签名契约)
- 业务逻辑: 裸 body 上传 panic/bootstrap 审计管线卡死/定价通配符优先级/
全局工具可见性/调度器停机补跑/TOTP 挑战令牌消费顺序/熔断探针语义/
>4MB 响应 token 计量/管理员重置密码作废会话 等
- 前端: 新 logo(语枢 AI 网关主题)/Provider 凭据异常警示/删除入口/
后端错误消息透传/localStorage 敏感数据收敛
- 部署: CREDENTIAL_MASTER_KEY 持久化与弱值拒绝/Provider DELETE 接口/
nginx 安全头/worker 内存限制
- 新增迁移 000029(key_hash 索引)/000030(usage_daily 币种维度)
5.1 KiB
Production deployment
This bundle builds the Go services and both Art Design Pro applications from
source. PostgreSQL (with pgvector), two Redis roles, MinIO (object storage, M8)
and a local Ollama container (vectorization, M8) are included; ClickHouse is not
required. Neither MinIO nor Ollama is a startup dependency: the gateway warns
and refuses file uploads until the bucket is reachable, and knowledge-base
documents are still stored (with embedding set to NULL) when Ollama is down,
with retrieval falling back to full-text search.
The scheduler is a separate stateless worker backed by PostgreSQL leases; run at
least one scheduler-worker replica whenever scheduled tasks are enabled.
Prerequisites
- Docker Engine with Compose v2
- At least 4 CPU cores, 8 GiB RAM and 30 GiB free disk for an initial build
- An external TLS reverse proxy or load balancer
- A backup destination for the PostgreSQL volume
First deployment
Run all commands from the repository root:
cp deploy/production.env.example deploy/production.env
chmod 600 deploy/production.env
# Edit deploy/production.env and replace every CHANGE_ME value.
docker compose \
--env-file deploy/production.env \
-f deploy/docker-compose.production.yml \
config --quiet
docker compose \
--env-file deploy/production.env \
-f deploy/docker-compose.production.yml \
up -d --build
Create the initial administrator once:
docker compose \
--env-file deploy/production.env \
-f deploy/docker-compose.production.yml \
--profile tools run --rm bootstrap-admin
Then remove BOOTSTRAP_ADMIN_PASSWORD from deploy/production.env and use the
admin UI to create database-backed gateway API keys.
Endpoints
- API and OpenAI-compatible gateway:
127.0.0.1:8080 - Admin UI:
http://127.0.0.1:8081/admin/ - Portal UI:
http://127.0.0.1:8082/portal/ - Liveness/readiness:
/healthzand/readyz
Ports bind to loopback by default. Terminate TLS at a reverse proxy and forward
to these endpoints. Change *_BIND_IP only when the host firewall and network
policy are already in place.
Operations
Check status and logs:
docker compose --env-file deploy/production.env -f deploy/docker-compose.production.yml ps
docker compose --env-file deploy/production.env -f deploy/docker-compose.production.yml logs --tail=200 gateway-api
docker compose --env-file deploy/production.env -f deploy/docker-compose.production.yml logs --tail=200 scheduler-worker
curl --fail http://127.0.0.1:8080/readyz
For upgrades, back up PostgreSQL first, change GATEWAY_VERSION, then run the
same up -d --build command. The one-shot migrator applies forward migrations
before the API starts. Do not use docker compose down -v in production because
it removes persistent data.
The bundled database URLs use sslmode=disable only for the private Compose
network. When using an external PostgreSQL or Redis service, require TLS and use
sslmode=verify-full / rediss:// as supported by that service.
Scheduled tasks
scheduler-workercalls the gateway overSCHEDULER_GATEWAY_BASE_URL; keep it on the private application network and do not expose a scheduler port.- Task API keys are encrypted with
CREDENTIAL_MASTER_KEY. Back up the active key and its historical keyring together with PostgreSQL before rotation. SCHEDULER_MAX_ATTEMPTScontrols both ordinary execution retries and stale lease recovery. Final success/failure is published through outbox and can be delivered to the selected notification channel and the creator's inbox.- Multiple replicas are safe because due tasks and runs are claimed with
PostgreSQL row locks and
SKIP LOCKED.
Vectorization and object storage
- The PostgreSQL image is
pgvector/pgvector:pg17(data-volume compatible withpostgres:17-alpine); migration000024creates thevectorextension and adds the HNSW embedding column.EMBEDDING_DIMmust stay at1024to match thevector(1024)column. - Ollama runs locally and lazily pulls
bge-m3(~1.2 GiB) on first embedding request. SetEMBEDDINGS_ENABLED=falseto disable vectorization entirely. - Back up the
minio-dataandollama-modelsvolumes alongside PostgreSQL. - If you previously deployed with
postgres:17-alpine, back up the PostgreSQL volume before switching images.
CREDENTIAL_MASTER_KEY 持久化(重要)
- 所有加密凭据(Provider API Key、TOTP 密钥、Webhook 签名、调度任务 Key、
应用运行时 Key)都用
CREDENTIAL_MASTER_KEY加密。该密钥必须持久化: 每次部署换新 key 会让全部已存凭据无法解密。 - 本地 compose 首次启动前执行
openssl rand -base64 32 > deploy/.env(compose 自动读取该文件), 之后重启/重建复用同一 key;.gitignore已排除deploy/.env。 - 需要轮换时使用管理端「供应商 → 凭据轮换」接口(同一 KEK 版本内重加密),
并保留历史 keyring;不要直接更换
CREDENTIAL_MASTER_KEY值。 - 若误换 key:管理端 Provider 列表会降级显示「凭据无法解密」警示(不会 让整个页面报错),需重新保存各 Provider 的 API Key 恢复。