AI Gateway Go 0.10.0 源码快照 + 旗舰版需求规划报告
M0-M7 已完成:核心网关(身份/RBAC/TOTP/OIDC/SAML/Provider/配额/路由/内容策略/审计/定价)+ 资源市场(MCP/Skills/数字员工)。 含 22 个 PostgreSQL 迁移、管理端/门户端前端源码、OpenAPI 契约、部署 compose。 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
FROM golang:1.26.5-alpine AS builder
|
||||
WORKDIR /src
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
COPY cmd ./cmd
|
||||
COPY internal ./internal
|
||||
ARG VERSION=dev
|
||||
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w -X main.version=${VERSION}" -o /out/gateway-api ./cmd/gateway-api
|
||||
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/gateway-migrator ./cmd/gateway-migrator
|
||||
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/gateway-bootstrap ./cmd/gateway-bootstrap
|
||||
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/gateway-outbox-worker ./cmd/gateway-outbox-worker
|
||||
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/gateway-maintenance ./cmd/gateway-maintenance
|
||||
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/gateway-notification-worker ./cmd/gateway-notification-worker
|
||||
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/gateway-loadtest ./cmd/gateway-loadtest
|
||||
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/gateway-legacy-import ./cmd/gateway-legacy-import
|
||||
|
||||
FROM alpine:3.22
|
||||
RUN apk add --no-cache ca-certificates tzdata \
|
||||
&& addgroup -S gateway \
|
||||
&& adduser -S -G gateway gateway
|
||||
WORKDIR /app
|
||||
COPY --from=builder /out/gateway-api /usr/local/bin/gateway-api
|
||||
COPY --from=builder /out/gateway-migrator /usr/local/bin/gateway-migrator
|
||||
COPY --from=builder /out/gateway-bootstrap /usr/local/bin/gateway-bootstrap
|
||||
COPY --from=builder /out/gateway-outbox-worker /usr/local/bin/gateway-outbox-worker
|
||||
COPY --from=builder /out/gateway-maintenance /usr/local/bin/gateway-maintenance
|
||||
COPY --from=builder /out/gateway-notification-worker /usr/local/bin/gateway-notification-worker
|
||||
COPY --from=builder /out/gateway-loadtest /usr/local/bin/gateway-loadtest
|
||||
COPY --from=builder /out/gateway-legacy-import /usr/local/bin/gateway-legacy-import
|
||||
COPY migrations ./migrations
|
||||
USER gateway
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["gateway-api"]
|
||||
@@ -0,0 +1,16 @@
|
||||
FROM node:24-alpine AS builder
|
||||
ARG APP=admin
|
||||
WORKDIR /src/web
|
||||
RUN corepack enable
|
||||
COPY web/package.json web/pnpm-lock.yaml web/pnpm-workspace.yaml ./
|
||||
COPY web/apps ./apps
|
||||
COPY web/packages ./packages
|
||||
RUN CI=1 corepack pnpm@10.15.1 install --frozen-lockfile
|
||||
RUN corepack pnpm@10.15.1 --filter @aigateway/${APP} build
|
||||
|
||||
FROM nginx:1.29-alpine
|
||||
ARG APP=admin
|
||||
COPY deploy/nginx-web.conf /etc/nginx/conf.d/default.conf
|
||||
RUN sed -i "s/__APP__/${APP}/g" /etc/nginx/conf.d/default.conf
|
||||
COPY --from=builder /src/web/apps/${APP}/dist /usr/share/nginx/html/${APP}
|
||||
EXPOSE 80
|
||||
@@ -0,0 +1,74 @@
|
||||
# Production deployment
|
||||
|
||||
This bundle builds the Go services and both Art Design Pro applications from
|
||||
source. PostgreSQL and two Redis roles are included; MinIO/S3 and ClickHouse are
|
||||
not required.
|
||||
|
||||
## 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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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: `/healthz` and `/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:
|
||||
|
||||
```bash
|
||||
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
|
||||
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.
|
||||
@@ -0,0 +1,189 @@
|
||||
name: ai-gateway
|
||||
|
||||
x-backend-build: &backend-build
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile
|
||||
args:
|
||||
VERSION: ${GATEWAY_VERSION:-0.10.0}
|
||||
|
||||
x-gateway-environment: &gateway-environment
|
||||
APP_ENV: production
|
||||
HTTP_ADDR: :8080
|
||||
DATABASE_URL: ${DATABASE_URL:?DATABASE_URL is required}
|
||||
REDIS_CRITICAL_URL: ${REDIS_CRITICAL_URL:?REDIS_CRITICAL_URL is required}
|
||||
REDIS_CACHE_URL: ${REDIS_CACHE_URL:-}
|
||||
GATEWAY_BOOTSTRAP_API_KEY_ENABLED: ${GATEWAY_BOOTSTRAP_API_KEY_ENABLED:-false}
|
||||
GATEWAY_BOOTSTRAP_API_KEY: ${GATEWAY_BOOTSTRAP_API_KEY:-}
|
||||
CREDENTIAL_MASTER_KEY: ${CREDENTIAL_MASTER_KEY:?CREDENTIAL_MASTER_KEY is required}
|
||||
CREDENTIAL_KEK_VERSION: ${CREDENTIAL_KEK_VERSION:-1}
|
||||
CREDENTIAL_KEK_KEYRING: ${CREDENTIAL_KEK_KEYRING:-}
|
||||
ALLOW_PRIVATE_PROVIDER_URLS: ${ALLOW_PRIVATE_PROVIDER_URLS:-false}
|
||||
ALLOW_PRIVATE_TOOL_URLS: ${ALLOW_PRIVATE_TOOL_URLS:-false}
|
||||
ALLOW_PRIVATE_WEBHOOK_URLS: ${ALLOW_PRIVATE_WEBHOOK_URLS:-false}
|
||||
UPSTREAM_FALLBACK_ENABLED: ${UPSTREAM_FALLBACK_ENABLED:-false}
|
||||
UPSTREAM_BASE_URL: ${UPSTREAM_BASE_URL:-https://api.openai.com}
|
||||
UPSTREAM_API_KEY: ${UPSTREAM_API_KEY:-}
|
||||
SHADOW_BASE_URL: ${SHADOW_BASE_URL:-}
|
||||
SHADOW_API_KEY: ${SHADOW_API_KEY:-}
|
||||
SHADOW_SAMPLE_RATE: ${SHADOW_SAMPLE_RATE:-0}
|
||||
|
||||
x-backend-service: &backend-service
|
||||
image: ai-gateway-go:${GATEWAY_VERSION:-0.10.0}
|
||||
build: *backend-build
|
||||
environment: *gateway-environment
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /tmp:size=64m,mode=1777
|
||||
cap_drop:
|
||||
- ALL
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:17-alpine
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB:-gateway}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-gateway}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
restart: unless-stopped
|
||||
|
||||
redis-critical:
|
||||
image: redis:8.2-alpine
|
||||
environment:
|
||||
REDIS_PASSWORD: ${REDIS_PASSWORD:?REDIS_PASSWORD is required}
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- exec redis-server --requirepass "$${REDIS_PASSWORD}" --appendonly yes --appendfsync everysec --maxmemory-policy noeviction
|
||||
volumes:
|
||||
- redis-critical-data:/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "redis-cli --no-auth-warning -a \"$${REDIS_PASSWORD}\" ping | grep -q PONG"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
restart: unless-stopped
|
||||
|
||||
redis-cache:
|
||||
image: redis:8.2-alpine
|
||||
environment:
|
||||
REDIS_PASSWORD: ${REDIS_PASSWORD:?REDIS_PASSWORD is required}
|
||||
REDIS_CACHE_MAXMEMORY: ${REDIS_CACHE_MAXMEMORY:-256mb}
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- exec redis-server --requirepass "$${REDIS_PASSWORD}" --maxmemory "$${REDIS_CACHE_MAXMEMORY}" --maxmemory-policy allkeys-lfu --save ""
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "redis-cli --no-auth-warning -a \"$${REDIS_PASSWORD}\" ping | grep -q PONG"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
restart: unless-stopped
|
||||
|
||||
migrator:
|
||||
<<: *backend-service
|
||||
entrypoint: ["gateway-migrator"]
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
restart: "no"
|
||||
|
||||
gateway-api:
|
||||
<<: *backend-service
|
||||
ports:
|
||||
- "${GATEWAY_BIND_IP:-127.0.0.1}:${GATEWAY_PORT:-8080}:8080"
|
||||
depends_on:
|
||||
migrator:
|
||||
condition: service_completed_successfully
|
||||
redis-critical:
|
||||
condition: service_healthy
|
||||
redis-cache:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -q -O /dev/null http://127.0.0.1:8080/readyz"]
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
start_period: 10s
|
||||
restart: unless-stopped
|
||||
|
||||
admin-web:
|
||||
image: ai-gateway-admin:${GATEWAY_VERSION:-0.10.0}
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile.web
|
||||
args:
|
||||
APP: admin
|
||||
ports:
|
||||
- "${WEB_BIND_IP:-127.0.0.1}:${ADMIN_PORT:-8081}:80"
|
||||
depends_on:
|
||||
gateway-api:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
portal-web:
|
||||
image: ai-gateway-portal:${GATEWAY_VERSION:-0.10.0}
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile.web
|
||||
args:
|
||||
APP: portal
|
||||
ports:
|
||||
- "${WEB_BIND_IP:-127.0.0.1}:${PORTAL_PORT:-8082}:80"
|
||||
depends_on:
|
||||
gateway-api:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
outbox-worker:
|
||||
<<: *backend-service
|
||||
entrypoint: ["gateway-outbox-worker"]
|
||||
depends_on:
|
||||
migrator:
|
||||
condition: service_completed_successfully
|
||||
redis-critical:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
maintenance-worker:
|
||||
<<: *backend-service
|
||||
entrypoint: ["gateway-maintenance"]
|
||||
depends_on:
|
||||
migrator:
|
||||
condition: service_completed_successfully
|
||||
restart: unless-stopped
|
||||
|
||||
notification-worker:
|
||||
<<: *backend-service
|
||||
entrypoint: ["gateway-notification-worker"]
|
||||
depends_on:
|
||||
migrator:
|
||||
condition: service_completed_successfully
|
||||
redis-critical:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
bootstrap-admin:
|
||||
<<: *backend-service
|
||||
profiles: ["tools"]
|
||||
entrypoint: ["gateway-bootstrap"]
|
||||
environment:
|
||||
<<: *gateway-environment
|
||||
BOOTSTRAP_ADMIN_USERNAME: ${BOOTSTRAP_ADMIN_USERNAME:-admin}
|
||||
BOOTSTRAP_ADMIN_PASSWORD: ${BOOTSTRAP_ADMIN_PASSWORD:-}
|
||||
depends_on:
|
||||
migrator:
|
||||
condition: service_completed_successfully
|
||||
restart: "no"
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
redis-critical-data:
|
||||
@@ -0,0 +1,154 @@
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:17-alpine
|
||||
environment:
|
||||
POSTGRES_DB: gateway
|
||||
POSTGRES_USER: gateway
|
||||
POSTGRES_PASSWORD: gateway
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U gateway -d gateway"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 20
|
||||
|
||||
redis-critical:
|
||||
image: redis:8.2-alpine
|
||||
command: ["redis-server", "--appendonly", "yes", "--appendfsync", "everysec", "--maxmemory-policy", "noeviction"]
|
||||
volumes:
|
||||
- redis-critical-data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 20
|
||||
|
||||
redis-cache:
|
||||
image: redis:8.2-alpine
|
||||
command: ["redis-server", "--maxmemory", "256mb", "--maxmemory-policy", "allkeys-lfu", "--save", ""]
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 20
|
||||
|
||||
migrator:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile
|
||||
args:
|
||||
VERSION: ${GATEWAY_VERSION:-0.10.0}
|
||||
entrypoint: ["gateway-migrator"]
|
||||
environment: &gateway-environment
|
||||
APP_ENV: local
|
||||
HTTP_ADDR: :8080
|
||||
DATABASE_URL: postgres://gateway:gateway@postgres:5432/gateway?sslmode=disable
|
||||
REDIS_CRITICAL_URL: redis://redis-critical:6379/0
|
||||
REDIS_CACHE_URL: redis://redis-cache:6379/0
|
||||
GATEWAY_BOOTSTRAP_API_KEY: ${GATEWAY_BOOTSTRAP_API_KEY:-}
|
||||
GATEWAY_BOOTSTRAP_API_KEY_ENABLED: ${GATEWAY_BOOTSTRAP_API_KEY_ENABLED:-false}
|
||||
CREDENTIAL_MASTER_KEY: ${CREDENTIAL_MASTER_KEY:-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=}
|
||||
CREDENTIAL_KEK_VERSION: 1
|
||||
CREDENTIAL_KEK_KEYRING: ${CREDENTIAL_KEK_KEYRING:-}
|
||||
ALLOW_PRIVATE_TOOL_URLS: ${ALLOW_PRIVATE_TOOL_URLS:-false}
|
||||
ALLOW_PRIVATE_WEBHOOK_URLS: ${ALLOW_PRIVATE_WEBHOOK_URLS:-false}
|
||||
UPSTREAM_BASE_URL: ${UPSTREAM_BASE_URL:-https://api.openai.com}
|
||||
UPSTREAM_API_KEY: ${UPSTREAM_API_KEY:-}
|
||||
SHADOW_BASE_URL: ${SHADOW_BASE_URL:-}
|
||||
SHADOW_API_KEY: ${SHADOW_API_KEY:-}
|
||||
SHADOW_SAMPLE_RATE: ${SHADOW_SAMPLE_RATE:-0}
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
|
||||
gateway-api:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile
|
||||
args:
|
||||
VERSION: ${GATEWAY_VERSION:-0.10.0}
|
||||
environment: *gateway-environment
|
||||
ports:
|
||||
- "${GATEWAY_PORT:-8080}:8080"
|
||||
depends_on:
|
||||
migrator:
|
||||
condition: service_completed_successfully
|
||||
redis-critical:
|
||||
condition: service_healthy
|
||||
redis-cache:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
admin-web:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile.web
|
||||
args:
|
||||
APP: admin
|
||||
ports:
|
||||
- "${ADMIN_PORT:-8081}:80"
|
||||
depends_on:
|
||||
gateway-api:
|
||||
condition: service_started
|
||||
restart: unless-stopped
|
||||
|
||||
portal-web:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile.web
|
||||
args:
|
||||
APP: portal
|
||||
ports:
|
||||
- "${PORTAL_PORT:-8082}:80"
|
||||
depends_on:
|
||||
gateway-api:
|
||||
condition: service_started
|
||||
restart: unless-stopped
|
||||
|
||||
outbox-worker:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile
|
||||
args:
|
||||
VERSION: ${GATEWAY_VERSION:-0.10.0}
|
||||
entrypoint: ["gateway-outbox-worker"]
|
||||
environment: *gateway-environment
|
||||
depends_on:
|
||||
migrator:
|
||||
condition: service_completed_successfully
|
||||
redis-critical:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
maintenance-worker:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile
|
||||
args:
|
||||
VERSION: ${GATEWAY_VERSION:-0.10.0}
|
||||
entrypoint: ["gateway-maintenance"]
|
||||
environment: *gateway-environment
|
||||
depends_on:
|
||||
migrator:
|
||||
condition: service_completed_successfully
|
||||
restart: unless-stopped
|
||||
|
||||
notification-worker:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile
|
||||
args:
|
||||
VERSION: ${GATEWAY_VERSION:-0.10.0}
|
||||
entrypoint: ["gateway-notification-worker"]
|
||||
environment: *gateway-environment
|
||||
depends_on:
|
||||
migrator:
|
||||
condition: service_completed_successfully
|
||||
redis-critical:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
redis-critical-data:
|
||||
@@ -0,0 +1,71 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
# Keep Location headers relative (Location: /admin/) instead of letting
|
||||
# nginx absolute_redirect rebuild them from $host + the listening port.
|
||||
# The gateway is commonly published behind a non-standard port (e.g. 18081),
|
||||
# and an absolute redirect would drop that port and send browsers to :80.
|
||||
absolute_redirect off;
|
||||
|
||||
# Match the gateway's HTTP_MAX_BODY_BYTES (default 32 MiB). nginx's default
|
||||
# of 1 MiB otherwise rejects large prompts and knowledge-base imports with
|
||||
# 413 before they ever reach the gateway.
|
||||
client_max_body_size 32m;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location = / {
|
||||
return 302 /__APP__/;
|
||||
}
|
||||
|
||||
location = /__APP__ {
|
||||
return 301 /__APP__/;
|
||||
}
|
||||
|
||||
location = /healthz {
|
||||
proxy_pass http://gateway-api:8080/healthz;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location = /readyz {
|
||||
proxy_pass http://gateway-api:8080/readyz;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://gateway-api:8080;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Request-ID $request_id;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
# nginx 是控制台(/api/)的唯一入口:用 $remote_addr 覆盖 X-Forwarded-For,
|
||||
# 避免客户端自带 X-Forwarded-For 头伪造来源 IP、绕过登录限流。
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
}
|
||||
|
||||
location /v1/ {
|
||||
proxy_pass http://gateway-api:8080;
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Request-ID $request_id;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
# Vite emits assets and client-side routes below /admin/ or /portal/.
|
||||
location /__APP__/ {
|
||||
try_files $uri $uri/ /__APP__/index.html;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 404;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
# Copy this file to deploy/production.env and replace every CHANGE_ME value.
|
||||
# Keep production.env outside version control and restrict it to the deploy user.
|
||||
GATEWAY_VERSION=0.10.0
|
||||
|
||||
POSTGRES_DB=gateway
|
||||
POSTGRES_USER=gateway
|
||||
POSTGRES_PASSWORD=CHANGE_ME_LONG_RANDOM_POSTGRES_PASSWORD
|
||||
REDIS_PASSWORD=CHANGE_ME_LONG_RANDOM_REDIS_PASSWORD
|
||||
|
||||
# URL-encode special characters in passwords used in URLs.
|
||||
DATABASE_URL=postgres://gateway:CHANGE_ME_URL_ENCODED_POSTGRES_PASSWORD@postgres:5432/gateway?sslmode=disable
|
||||
REDIS_CRITICAL_URL=redis://:CHANGE_ME_URL_ENCODED_REDIS_PASSWORD@redis-critical:6379/0
|
||||
REDIS_CACHE_URL=redis://:CHANGE_ME_URL_ENCODED_REDIS_PASSWORD@redis-cache:6379/0
|
||||
|
||||
# Generate once with: openssl rand -base64 32
|
||||
# Never rotate this value without following a KEK rotation procedure.
|
||||
CREDENTIAL_MASTER_KEY=CHANGE_ME_BASE64_32_BYTE_KEY
|
||||
CREDENTIAL_KEK_VERSION=1
|
||||
CREDENTIAL_KEK_KEYRING=
|
||||
|
||||
# Disabled by default. Create database-backed API keys after bootstrap.
|
||||
GATEWAY_BOOTSTRAP_API_KEY_ENABLED=false
|
||||
GATEWAY_BOOTSTRAP_API_KEY=
|
||||
|
||||
UPSTREAM_FALLBACK_ENABLED=false
|
||||
UPSTREAM_BASE_URL=https://api.openai.com
|
||||
UPSTREAM_API_KEY=
|
||||
|
||||
ALLOW_PRIVATE_PROVIDER_URLS=false
|
||||
ALLOW_PRIVATE_TOOL_URLS=false
|
||||
ALLOW_PRIVATE_WEBHOOK_URLS=false
|
||||
|
||||
GATEWAY_BIND_IP=127.0.0.1
|
||||
GATEWAY_PORT=8080
|
||||
WEB_BIND_IP=127.0.0.1
|
||||
ADMIN_PORT=8081
|
||||
PORTAL_PORT=8082
|
||||
REDIS_CACHE_MAXMEMORY=256mb
|
||||
|
||||
# Used only for the one-time bootstrap-admin command; remove after use.
|
||||
BOOTSTRAP_ADMIN_USERNAME=admin
|
||||
BOOTSTRAP_ADMIN_PASSWORD=CHANGE_ME_AT_LEAST_12_CHARACTERS
|
||||
Reference in New Issue
Block a user