feat: add opus-4-7 support + nginx load balancer docker-compose
This commit is contained in:
parent
56a955e1d6
commit
888b7eeb21
@ -213,7 +213,7 @@ func (h *AntigravityHTTPHandler) GetModels(c *gin.Context) {
|
|||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"models": models,
|
"models": models,
|
||||||
"default_model": "claude-opus-4-6",
|
"default_model": "claude-opus-4-7",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -310,6 +310,24 @@ type ModelConfig struct {
|
|||||||
// GetAvailableModels 获取可用模型列表
|
// GetAvailableModels 获取可用模型列表
|
||||||
func (svc *LanguageServerService) GetAvailableModels(ctx context.Context) ([]ModelConfig, error) {
|
func (svc *LanguageServerService) GetAvailableModels(ctx context.Context) ([]ModelConfig, error) {
|
||||||
models := []ModelConfig{
|
models := []ModelConfig{
|
||||||
|
{
|
||||||
|
Name: "claude-opus-4-7",
|
||||||
|
DisplayName: "Claude Opus 4.7",
|
||||||
|
MaxTokens: 200000,
|
||||||
|
SupportsThinking: true,
|
||||||
|
ThinkingBudget: 32000,
|
||||||
|
SupportsImages: true,
|
||||||
|
Provider: "anthropic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "claude-sonnet-4-7",
|
||||||
|
DisplayName: "Claude Sonnet 4.7",
|
||||||
|
MaxTokens: 200000,
|
||||||
|
SupportsThinking: true,
|
||||||
|
ThinkingBudget: 16000,
|
||||||
|
SupportsImages: true,
|
||||||
|
Provider: "anthropic",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "claude-opus-4-6",
|
Name: "claude-opus-4-6",
|
||||||
DisplayName: "Claude Opus 4.6",
|
DisplayName: "Claude Opus 4.6",
|
||||||
|
|||||||
@ -1,57 +1,82 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Sub2API Docker Compose Configuration
|
# Sub2API Docker Compose Configuration (负载均衡版)
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Quick Start:
|
# Quick Start:
|
||||||
# 1. Copy .env.example to .env and configure
|
# 1. Copy .env.example to .env and configure
|
||||||
# 2. docker-compose up -d
|
# 2. docker compose up -d
|
||||||
# 3. Check logs: docker-compose logs -f sub2api
|
# 3. Check logs: docker compose logs -f
|
||||||
# 4. Access: http://localhost:8080
|
# 4. Access: http://localhost (via nginx)
|
||||||
#
|
#
|
||||||
# All configuration is done via environment variables.
|
# 扩缩容:
|
||||||
# No Setup Wizard needed - the system auto-initializes on first run.
|
# docker compose up -d --scale sub2api=5 # 扩到 5 个实例
|
||||||
|
# docker compose up -d --scale sub2api=2 # 缩回 2 个实例
|
||||||
|
#
|
||||||
|
# 注意事项:
|
||||||
|
# - JWT_SECRET / TOTP_ENCRYPTION_KEY 必须固定,多实例共享同一个值
|
||||||
|
# - PostgreSQL / Redis 单实例,不参与水平扩展
|
||||||
|
# - postgres 端口默认不对外暴露,如需调试取消注释 127.0.0.1:5433:5432
|
||||||
|
# - redis 端口默认不对外暴露,如需调试取消注释 127.0.0.1:6380:6379
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
# Sub2API Application
|
# Nginx 负载均衡(入口)
|
||||||
|
# ===========================================================================
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: sub2api-nginx
|
||||||
|
restart: unless-stopped
|
||||||
|
ulimits:
|
||||||
|
nofile:
|
||||||
|
soft: 65535
|
||||||
|
hard: 65535
|
||||||
|
ports:
|
||||||
|
- "0.0.0.0:80:80"
|
||||||
|
- "0.0.0.0:443:443"
|
||||||
|
volumes:
|
||||||
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
|
- ./nginx/certs:/etc/nginx/certs:ro
|
||||||
|
depends_on:
|
||||||
|
sub2api:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- sub2api-network
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "wget", "-q", "-T", "3", "-O", "/dev/null", "http://localhost/health" ]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
# ===========================================================================
|
||||||
|
# Sub2API Application(多实例,通过 --scale 控制数量)
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
sub2api:
|
sub2api:
|
||||||
image: weishaw/sub2api:latest
|
image: docker.io/zfc931912343/sub2api:latest
|
||||||
container_name: sub2api
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ulimits:
|
ulimits:
|
||||||
nofile:
|
nofile:
|
||||||
soft: 100000
|
soft: 100000
|
||||||
hard: 100000
|
hard: 100000
|
||||||
ports:
|
# 不直接暴露端口,由 nginx 代理
|
||||||
- "${BIND_HOST:-0.0.0.0}:${SERVER_PORT:-8080}:8080"
|
expose:
|
||||||
|
- "8080"
|
||||||
volumes:
|
volumes:
|
||||||
# Data persistence (config.yaml will be auto-generated here)
|
|
||||||
- sub2api_data:/app/data
|
- sub2api_data:/app/data
|
||||||
# Optional: Mount custom config.yaml (uncomment and create the file first)
|
# Optional: 挂载自定义 config.yaml(先从 config.example.yaml 复制并修改)
|
||||||
# Copy config.example.yaml to config.yaml, modify it, then uncomment:
|
|
||||||
# - ./config.yaml:/app/data/config.yaml
|
# - ./config.yaml:/app/data/config.yaml
|
||||||
# Optional: Mount a custom Codex instructions template file, then point
|
# Optional: 自定义 Codex instructions 模板
|
||||||
# gateway.forced_codex_instructions_template_file at /app/data/codex-instructions.md.tmpl
|
|
||||||
# in config.yaml.
|
|
||||||
# - ./codex-instructions.md.tmpl:/app/data/codex-instructions.md.tmpl:ro
|
# - ./codex-instructions.md.tmpl:/app/data/codex-instructions.md.tmpl:ro
|
||||||
environment:
|
environment:
|
||||||
# =======================================================================
|
|
||||||
# Auto Setup (REQUIRED for Docker deployment)
|
|
||||||
# =======================================================================
|
|
||||||
- AUTO_SETUP=true
|
- AUTO_SETUP=true
|
||||||
|
|
||||||
# =======================================================================
|
# --- Server ---
|
||||||
# Server Configuration
|
|
||||||
# =======================================================================
|
|
||||||
- SERVER_HOST=0.0.0.0
|
- SERVER_HOST=0.0.0.0
|
||||||
- SERVER_PORT=8080
|
- SERVER_PORT=8080
|
||||||
- SERVER_MODE=${SERVER_MODE:-release}
|
- SERVER_MODE=${SERVER_MODE:-release}
|
||||||
- RUN_MODE=${RUN_MODE:-standard}
|
- RUN_MODE=${RUN_MODE:-standard}
|
||||||
|
|
||||||
# =======================================================================
|
# --- Database (PostgreSQL) ---
|
||||||
# Database Configuration (PostgreSQL)
|
|
||||||
# =======================================================================
|
|
||||||
- DATABASE_HOST=postgres
|
- DATABASE_HOST=postgres
|
||||||
- DATABASE_PORT=5432
|
- DATABASE_PORT=5432
|
||||||
- DATABASE_USER=${POSTGRES_USER:-sub2api}
|
- DATABASE_USER=${POSTGRES_USER:-sub2api}
|
||||||
@ -63,9 +88,7 @@ services:
|
|||||||
- DATABASE_CONN_MAX_LIFETIME_MINUTES=${DATABASE_CONN_MAX_LIFETIME_MINUTES:-30}
|
- DATABASE_CONN_MAX_LIFETIME_MINUTES=${DATABASE_CONN_MAX_LIFETIME_MINUTES:-30}
|
||||||
- DATABASE_CONN_MAX_IDLE_TIME_MINUTES=${DATABASE_CONN_MAX_IDLE_TIME_MINUTES:-5}
|
- DATABASE_CONN_MAX_IDLE_TIME_MINUTES=${DATABASE_CONN_MAX_IDLE_TIME_MINUTES:-5}
|
||||||
|
|
||||||
# =======================================================================
|
# --- Redis ---
|
||||||
# Redis Configuration
|
|
||||||
# =======================================================================
|
|
||||||
- REDIS_HOST=redis
|
- REDIS_HOST=redis
|
||||||
- REDIS_PORT=6379
|
- REDIS_PORT=6379
|
||||||
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||||||
@ -74,74 +97,39 @@ services:
|
|||||||
- REDIS_MIN_IDLE_CONNS=${REDIS_MIN_IDLE_CONNS:-10}
|
- REDIS_MIN_IDLE_CONNS=${REDIS_MIN_IDLE_CONNS:-10}
|
||||||
- REDIS_ENABLE_TLS=${REDIS_ENABLE_TLS:-false}
|
- REDIS_ENABLE_TLS=${REDIS_ENABLE_TLS:-false}
|
||||||
|
|
||||||
# =======================================================================
|
# --- Admin(仅首次启动生效)---
|
||||||
# Admin Account (auto-created on first run)
|
|
||||||
# =======================================================================
|
|
||||||
- ADMIN_EMAIL=${ADMIN_EMAIL:-admin@sub2api.local}
|
- ADMIN_EMAIL=${ADMIN_EMAIL:-admin@sub2api.local}
|
||||||
- ADMIN_PASSWORD=${ADMIN_PASSWORD:-}
|
- ADMIN_PASSWORD=${ADMIN_PASSWORD:-}
|
||||||
|
|
||||||
# =======================================================================
|
# --- JWT(多实例必须固定,否则重启后 session 失效)---
|
||||||
# JWT Configuration
|
# 生成: openssl rand -hex 32
|
||||||
# =======================================================================
|
- JWT_SECRET=${JWT_SECRET:?JWT_SECRET is required for multi-instance}
|
||||||
# IMPORTANT: Set a fixed JWT_SECRET to prevent login sessions from being
|
|
||||||
# invalidated after container restarts. If left empty, a random secret
|
|
||||||
# will be generated on each startup.
|
|
||||||
# Generate a secure secret: openssl rand -hex 32
|
|
||||||
- JWT_SECRET=${JWT_SECRET:-}
|
|
||||||
- JWT_EXPIRE_HOUR=${JWT_EXPIRE_HOUR:-24}
|
- JWT_EXPIRE_HOUR=${JWT_EXPIRE_HOUR:-24}
|
||||||
|
|
||||||
# =======================================================================
|
# --- TOTP 2FA(多实例必须固定,否则 2FA 失效)---
|
||||||
# TOTP (2FA) Configuration
|
# 生成: openssl rand -hex 32
|
||||||
# =======================================================================
|
- TOTP_ENCRYPTION_KEY=${TOTP_ENCRYPTION_KEY:?TOTP_ENCRYPTION_KEY is required for multi-instance}
|
||||||
# IMPORTANT: Set a fixed encryption key for TOTP secrets. If left empty,
|
|
||||||
# a random key will be generated on each startup, causing all existing
|
|
||||||
# TOTP configurations to become invalid (users won't be able to login
|
|
||||||
# with 2FA).
|
|
||||||
# Generate a secure key: openssl rand -hex 32
|
|
||||||
- TOTP_ENCRYPTION_KEY=${TOTP_ENCRYPTION_KEY:-}
|
|
||||||
|
|
||||||
# =======================================================================
|
# --- Timezone ---
|
||||||
# Timezone Configuration
|
|
||||||
# This affects ALL time operations in the application:
|
|
||||||
# - Database timestamps
|
|
||||||
# - Usage statistics "today" boundary
|
|
||||||
# - Subscription expiry times
|
|
||||||
# - Log timestamps
|
|
||||||
# Common values: Asia/Shanghai, America/New_York, Europe/London, UTC
|
|
||||||
# =======================================================================
|
|
||||||
- TZ=${TZ:-Asia/Shanghai}
|
- TZ=${TZ:-Asia/Shanghai}
|
||||||
|
|
||||||
# =======================================================================
|
# --- Gemini OAuth ---
|
||||||
# Gemini OAuth Configuration (for Gemini accounts)
|
|
||||||
# =======================================================================
|
|
||||||
- GEMINI_OAUTH_CLIENT_ID=${GEMINI_OAUTH_CLIENT_ID:-}
|
- GEMINI_OAUTH_CLIENT_ID=${GEMINI_OAUTH_CLIENT_ID:-}
|
||||||
- GEMINI_OAUTH_CLIENT_SECRET=${GEMINI_OAUTH_CLIENT_SECRET:-}
|
- GEMINI_OAUTH_CLIENT_SECRET=${GEMINI_OAUTH_CLIENT_SECRET:-}
|
||||||
- GEMINI_OAUTH_SCOPES=${GEMINI_OAUTH_SCOPES:-}
|
- GEMINI_OAUTH_SCOPES=${GEMINI_OAUTH_SCOPES:-}
|
||||||
- GEMINI_QUOTA_POLICY=${GEMINI_QUOTA_POLICY:-}
|
- GEMINI_QUOTA_POLICY=${GEMINI_QUOTA_POLICY:-}
|
||||||
|
|
||||||
# Built-in OAuth client secrets (optional)
|
|
||||||
# SECURITY: This repo does not embed third-party client_secret.
|
|
||||||
- GEMINI_CLI_OAUTH_CLIENT_SECRET=${GEMINI_CLI_OAUTH_CLIENT_SECRET:-}
|
- GEMINI_CLI_OAUTH_CLIENT_SECRET=${GEMINI_CLI_OAUTH_CLIENT_SECRET:-}
|
||||||
- ANTIGRAVITY_OAUTH_CLIENT_SECRET=${ANTIGRAVITY_OAUTH_CLIENT_SECRET:-}
|
- ANTIGRAVITY_OAUTH_CLIENT_SECRET=${ANTIGRAVITY_OAUTH_CLIENT_SECRET:-}
|
||||||
|
|
||||||
# =======================================================================
|
# --- Security ---
|
||||||
# Security Configuration (URL Allowlist)
|
|
||||||
# =======================================================================
|
|
||||||
# Enable URL allowlist validation (false to skip allowlist checks)
|
|
||||||
- SECURITY_URL_ALLOWLIST_ENABLED=${SECURITY_URL_ALLOWLIST_ENABLED:-false}
|
- SECURITY_URL_ALLOWLIST_ENABLED=${SECURITY_URL_ALLOWLIST_ENABLED:-false}
|
||||||
# Allow insecure HTTP URLs when allowlist is disabled (default: false, requires https)
|
|
||||||
- SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=${SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP:-false}
|
- SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=${SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP:-false}
|
||||||
# Allow private IP addresses for upstream/pricing/CRS (for internal deployments)
|
|
||||||
- SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS=${SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS:-false}
|
- SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS=${SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS:-false}
|
||||||
# Upstream hosts whitelist (comma-separated, only used when enabled=true)
|
|
||||||
- SECURITY_URL_ALLOWLIST_UPSTREAM_HOSTS=${SECURITY_URL_ALLOWLIST_UPSTREAM_HOSTS:-}
|
- SECURITY_URL_ALLOWLIST_UPSTREAM_HOSTS=${SECURITY_URL_ALLOWLIST_UPSTREAM_HOSTS:-}
|
||||||
|
|
||||||
# =======================================================================
|
# --- Update Proxy(国内机器可配置代理访问 GitHub)---
|
||||||
# Update Configuration (在线更新配置)
|
|
||||||
# =======================================================================
|
|
||||||
# Proxy for accessing GitHub (online updates + pricing data)
|
|
||||||
# Examples: http://host:port, socks5://host:port
|
|
||||||
- UPDATE_PROXY_URL=${UPDATE_PROXY_URL:-}
|
- UPDATE_PROXY_URL=${UPDATE_PROXY_URL:-}
|
||||||
|
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@ -150,17 +138,7 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- sub2api-network
|
- sub2api-network
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test:
|
test: [ "CMD", "wget", "-q", "-T", "5", "-O", "/dev/null", "http://localhost:8080/health" ]
|
||||||
[
|
|
||||||
"CMD",
|
|
||||||
"wget",
|
|
||||||
"-q",
|
|
||||||
"-T",
|
|
||||||
"5",
|
|
||||||
"-O",
|
|
||||||
"/dev/null",
|
|
||||||
"http://localhost:8080/health",
|
|
||||||
]
|
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
@ -180,9 +158,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- postgres_data:/var/lib/postgresql/data
|
- postgres_data:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
# postgres:18-alpine 默认 PGDATA=/var/lib/postgresql/18/docker(位于镜像声明的匿名卷 /var/lib/postgresql 内)。
|
# postgres:18-alpine 默认 PGDATA 在镜像内部匿名卷,必须显式指定才能持久化到命名卷
|
||||||
# 若不显式设置 PGDATA,则即使挂载了 postgres_data 到 /var/lib/postgresql/data,数据也不会落盘到该命名卷,
|
|
||||||
# docker compose down/up 后会触发 initdb 重新初始化,导致用户/密码等数据丢失。
|
|
||||||
- PGDATA=/var/lib/postgresql/data
|
- PGDATA=/var/lib/postgresql/data
|
||||||
- POSTGRES_USER=${POSTGRES_USER:-sub2api}
|
- POSTGRES_USER=${POSTGRES_USER:-sub2api}
|
||||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
|
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
|
||||||
@ -191,19 +167,14 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- sub2api-network
|
- sub2api-network
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test:
|
test: [ "CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-sub2api} -d ${POSTGRES_DB:-sub2api}" ]
|
||||||
[
|
|
||||||
"CMD-SHELL",
|
|
||||||
"pg_isready -U ${POSTGRES_USER:-sub2api} -d ${POSTGRES_DB:-sub2api}",
|
|
||||||
]
|
|
||||||
interval: 10s
|
interval: 10s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
start_period: 10s
|
start_period: 10s
|
||||||
ports:
|
# 默认不对外暴露,如需本地调试取消注释
|
||||||
- 5432:5432
|
# ports:
|
||||||
# 注意:不暴露端口到宿主机,应用通过内部网络连接
|
# - "127.0.0.1:5433:5432"
|
||||||
# 如需调试,可临时添加:ports: ["127.0.0.1:5433:5432"]
|
|
||||||
|
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
# Redis Cache
|
# Redis Cache
|
||||||
@ -227,18 +198,19 @@ services:
|
|||||||
${REDIS_PASSWORD:+--requirepass "$REDIS_PASSWORD"}'
|
${REDIS_PASSWORD:+--requirepass "$REDIS_PASSWORD"}'
|
||||||
environment:
|
environment:
|
||||||
- TZ=${TZ:-Asia/Shanghai}
|
- TZ=${TZ:-Asia/Shanghai}
|
||||||
# REDISCLI_AUTH is used by redis-cli for authentication (safer than -a flag)
|
|
||||||
- REDISCLI_AUTH=${REDIS_PASSWORD:-}
|
- REDISCLI_AUTH=${REDIS_PASSWORD:-}
|
||||||
networks:
|
networks:
|
||||||
- sub2api-network
|
- sub2api-network
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "redis-cli", "ping"]
|
test: [ "CMD", "redis-cli", "ping" ]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
start_period: 5s
|
start_period: 5s
|
||||||
ports:
|
# 默认不对外暴露,如需本地调试取消注释
|
||||||
- 6379:6379
|
# ports:
|
||||||
|
# - "127.0.0.1:6380:6379"
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Volumes
|
# Volumes
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|||||||
155
deploy/nginx/nginx.conf
Normal file
155
deploy/nginx/nginx.conf
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# Nginx 负载均衡配置 for Sub2API(Cloudflare 前置 + Origin Certificate)
|
||||||
|
# =============================================================================
|
||||||
|
# 架构:Cloudflare (HTTPS) → VPS:443 (Docker nginx + CF Origin Cert) → sub2api
|
||||||
|
# - SSL 由 Cloudflare Origin Certificate 端到端加密
|
||||||
|
# - 真实客户端 IP 从 CF-Connecting-IP 头还原
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
worker_processes auto;
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 4096;
|
||||||
|
use epoll;
|
||||||
|
multi_accept on;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
log_format main '$realip_remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent '
|
||||||
|
'rt=$request_time urt=$upstream_response_time cf_ray=$http_cf_ray';
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
tcp_nopush on;
|
||||||
|
tcp_nodelay on;
|
||||||
|
keepalive_timeout 75s;
|
||||||
|
keepalive_requests 1000;
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
client_max_body_size 64m;
|
||||||
|
client_body_buffer_size 2m; # 避免请求体落盘(默认 8k/16k 对 AI 请求太小)
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_proxied any;
|
||||||
|
gzip_comp_level 4;
|
||||||
|
gzip_min_length 1024;
|
||||||
|
gzip_types text/plain text/css application/json application/javascript
|
||||||
|
text/xml application/xml text/javascript;
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# 还原真实客户端 IP(Cloudflare IP 段)
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
set_real_ip_from 103.21.244.0/22;
|
||||||
|
set_real_ip_from 103.22.200.0/22;
|
||||||
|
set_real_ip_from 103.31.4.0/22;
|
||||||
|
set_real_ip_from 104.16.0.0/13;
|
||||||
|
set_real_ip_from 104.24.0.0/14;
|
||||||
|
set_real_ip_from 108.162.192.0/18;
|
||||||
|
set_real_ip_from 131.0.72.0/22;
|
||||||
|
set_real_ip_from 141.101.64.0/18;
|
||||||
|
set_real_ip_from 162.158.0.0/15;
|
||||||
|
set_real_ip_from 172.64.0.0/13;
|
||||||
|
set_real_ip_from 173.245.48.0/20;
|
||||||
|
set_real_ip_from 188.114.96.0/20;
|
||||||
|
set_real_ip_from 190.93.240.0/20;
|
||||||
|
set_real_ip_from 197.234.240.0/22;
|
||||||
|
set_real_ip_from 198.41.128.0/17;
|
||||||
|
set_real_ip_from 2400:cb00::/32;
|
||||||
|
set_real_ip_from 2606:4700::/32;
|
||||||
|
set_real_ip_from 2803:f800::/32;
|
||||||
|
set_real_ip_from 2405:b500::/32;
|
||||||
|
set_real_ip_from 2405:8100::/32;
|
||||||
|
set_real_ip_from 2a06:98c0::/29;
|
||||||
|
set_real_ip_from 2c0f:f248::/32;
|
||||||
|
real_ip_header CF-Connecting-IP;
|
||||||
|
real_ip_recursive on;
|
||||||
|
|
||||||
|
# WebSocket upgrade 映射
|
||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# 上游实例池(least_conn)
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
upstream sub2api_backend {
|
||||||
|
# ip_hash 保证同一客户端 IP 始终路由到同一实例
|
||||||
|
# 解决 OAuth session 内存不共享问题(session 在实例内存中)
|
||||||
|
ip_hash;
|
||||||
|
server sub2api:8080;
|
||||||
|
}
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# HTTP → HTTPS 跳转
|
||||||
|
# =========================================================================
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
location = /health {
|
||||||
|
proxy_pass http://sub2api_backend;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_connect_timeout 5s;
|
||||||
|
proxy_read_timeout 10s;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# HTTPS(Cloudflare Origin Certificate)
|
||||||
|
# =========================================================================
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
http2 on;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/certs/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/nginx/certs/privkey.pem;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_timeout 1d;
|
||||||
|
|
||||||
|
location = /health {
|
||||||
|
proxy_pass http://sub2api_backend;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_connect_timeout 5s;
|
||||||
|
proxy_read_timeout 10s;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://sub2api_backend;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
|
||||||
|
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_cache off;
|
||||||
|
|
||||||
|
proxy_connect_timeout 10s;
|
||||||
|
proxy_send_timeout 600s;
|
||||||
|
proxy_read_timeout 600s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user