Skip to content

Nginx 部署 ​

SSS-RUN 默认监听 127.0.0.1:9301,生产环境建议使用 Nginx 作为反向代理,以获得 SSL 终端、静态资源缓存、WebSocket 代理、安全加固等能力。

为什么需要 Nginx ​

能力说明
SSL/TLS提供 HTTPS 加密访问,无需在应用层处理证书
静态缓存/assets/ 资源可设置长期缓存,减少应用层压力
WebSocket 代理正确处理 WebSocket 升级请求
安全加固隐藏后端端口、添加安全响应头、限制请求大小
负载均衡多实例部署时实现流量分发
Gzip 压缩压缩响应体,减少传输体积

最小配置 ​

仅做反向代理的最简配置:

nginx
server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://127.0.0.1:9301;
        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 $scheme;
    }
}

完整生产配置 ​

nginx
upstream sss_run {
    server 127.0.0.1:9301;
    keepalive 32;
}

server {
    listen 80;
    server_name your-domain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name your-domain.com;

    ssl_certificate     /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;

    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript image/svg+xml;
    gzip_min_length 1024;
    gzip_comp_level 6;

    client_max_body_size 100m;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    location /assets/ {
        proxy_pass http://sss_run;
        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 $scheme;

        proxy_cache_valid 200 30d;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    location /sss/ws/ {
        proxy_pass http://sss_run;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header 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 $scheme;

        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }

    location / {
        proxy_pass http://sss_run;
        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 $scheme;

        proxy_connect_timeout 60s;
        proxy_read_timeout 120s;
        proxy_send_timeout 120s;
    }
}

配置要点说明 ​

反向代理 ​

proxy_pass 指向应用监听地址。使用 upstream 块可启用 keepalive 连接池,减少 TCP 握手开销。以下请求头必须传递:

请求头作用
Host让应用识别原始域名
X-Real-IP传递客户端真实 IP
X-Forwarded-For传递代理链路 IP
X-Forwarded-Proto让应用识别原始协议(http/https)

WebSocket 代理 ​

WebSocket 连接路径为 /sss/ws/,需要以下特殊配置:

nginx
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

同时需要增大超时时间,避免长连接被 Nginx 断开:

nginx
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;

静态资源缓存 ​

Vite 构建的前端资源在 /assets/ 路径下,文件名包含 content hash(如 index-abc123.js),内容变化时文件名会改变,因此可以设置长期缓存:

nginx
location /assets/ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}

immutable 标记告诉浏览器资源不会变化,无需发送条件请求验证。

SSL/TLS ​

推荐配置:

  • 协议版本:仅启用 TLSv1.2 和 TLSv1.3
  • 密码套件:使用 HIGH:!aNULL:!MD5 过滤弱加密
  • 会话缓存:shared:SSL:10m 约 4 万个会话

证书可使用 Let's Encrypt 免费获取,配合 certbot 自动续期。

安全响应头 ​

响应头作用
X-Frame-Options防止页面被嵌入 iframe(点击劫持)
X-Content-Type-Options防止 MIME 类型嗅探
X-XSS-Protection启用浏览器 XSS 过滤
Strict-Transport-Security强制使用 HTTPS 访问
Referrer-Policy控制 Referer 泄露

文件上传大小 ​

client_max_body_size 控制请求体最大大小,默认仅 1MB。如果应用涉及文件上传功能,需要根据实际需求调大:

nginx
client_max_body_size 100m;

Gzip 压缩 ​

对文本类资源启用压缩可显著减少传输体积:

nginx
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript image/svg+xml;
gzip_min_length 1024;
gzip_comp_level 6;

Docker + Nginx 部署 ​

使用 Docker Compose 部署 Nginx + SSS-RUN:

yaml
version: '3.8'
services:
  sss-run:
    image: ghcr.io/lsamu/sss_run:latest
    restart: unless-stopped
    volumes:
      - ./data:/app/data
      - ./config.yaml:/app/config.yaml
    expose:
      - "9301"
    environment:
      - TZ=Asia/Shanghai

  nginx:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/ssl:/etc/nginx/ssl
    depends_on:
      - sss-run

目录结构:

project/
├── docker-compose.yml
├── config.yaml
├── data/
├── nginx/
│   ├── conf.d/
│   │   └── default.conf
│   └── ssl/
│       ├── cert.pem
│       └── key.pem

启动:

bash
docker compose up -d

负载均衡 ​

多实例部署时,在 upstream 中添加多个服务器:

nginx
upstream sss_run {
    server 127.0.0.1:9301;
    server 127.0.0.1:9301;
    server 127.0.0.1:9302;
    keepalive 32;
}

注意:多实例部署时需要将 database.driver 从 sqlite 切换为 MySQL/PostgreSQL 等外部数据库,并确保 Redis 共享,否则会话和缓存无法跨实例共享。

同时需要将 ws.store_type 设置为 redis,否则 WebSocket 状态存储(ws.Store/Load)和并发锁(ws.Lock/Unlock)无法跨实例共享:

yaml
ws:
    store_type: redis

常见问题 ​

502 Bad Gateway ​

  • 检查SSS-RUN进程是否正常运行
  • 检查 config.yaml 中 server.host 是否为 0.0.0.0(Docker 环境)或 127.0.0.1(本机 Nginx)
  • 检查防火墙是否放行 9301 端口

WebSocket 连接失败 ​

  • 确认 Nginx 配置了 Upgrade 和 Connection 头
  • 确认 proxy_http_version 设置为 1.1
  • 确认 proxy_read_timeout 足够大(默认 60s 可能不够)
  • 检查 Nginx 错误日志:tail -f /var/log/nginx/error.log

静态资源 404 ​

  • 确认前端已正确构建并嵌入到二进制中
  • 确认 Nginx 的 proxy_pass 指向正确地址
  • 不要在 Nginx 中配置 try_files,应用自带 SPA 路由回退

HTTPS 重定向循环 ​

  • 确认 Nginx 正确设置了 X-Forwarded-Proto 头
  • 如果使用多层代理,确保每层都传递了该头

文件上传失败 413 ​

  • 增大 Nginx 的 client_max_body_size 值
  • 同时检查应用层的上传限制配置

请求超时 ​

  • 对于长时间运行的 API 接口,增大 proxy_read_timeout 和 proxy_send_timeout
  • WebSocket 连接需要单独的超时配置

版权所有.