sub2api/deploy/nginx/nginx.conf
win 888b7eeb21
Some checks failed
CI / test (push) Failing after 3s
CI / golangci-lint (push) Failing after 3s
Security Scan / backend-security (push) Failing after 2s
Security Scan / frontend-security (push) Failing after 2m0s
feat: add opus-4-7 support + nginx load balancer docker-compose
2026-04-17 11:43:38 +08:00

156 lines
5.5 KiB
Nginx Configuration File
Raw Permalink 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.

# =============================================================================
# Nginx 负载均衡配置 for Sub2APICloudflare 前置 + 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;
# -------------------------------------------------------------------------
# 还原真实客户端 IPCloudflare 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;
}
}
# =========================================================================
# HTTPSCloudflare 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;
}
}
}