nginx可通过proxy_pass转发websocket至unix domain socket(uds),需同时满足四点:使用http/1.1并设置upgrade与connection升级头、uds路径严格写为unix:/path(无协议前缀)、通过upstream定义+keepalive启用连接复用、确保socket文件权限与nginx worker用户匹配。

用 proxy_pass 转发 WebSocket 到 Unix Domain Socket(UDS)能显著降低延迟、提升连接复用率,尤其适合 Nginx 与本地 FastAPI、Uvicorn、Gunicorn 或 Node.js 等后端共机部署的场景。关键不在“能不能配”,而在于协议支持、路径写法、连接复用和权限四者必须同时对齐。
WebSocket 必须用 HTTP/1.1 + Connection 升级头
WebSocket 基于 HTTP 协议升级,Nginx 默认会关闭长连接并移除关键 header,导致握手失败(返回 400 或直接断连)。需显式保留升级语义:
-
必须设置
proxy_http_version 1.1和proxy_set_header Upgrade $http_upgrade -
必须设置
proxy_set_header Connection "upgrade"(注意双引号,不能写成空字符串或'') - 若使用
upstream,这些指令仍要放在location块内,不可省略
UDS 路径写法:只认 unix:/path,不接受 http://
Nginx 对 WebSocket over UDS 的解析更严格——它不接受带 http:// 前缀的写法,否则启动报 invalid URL prefix:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
- ✅ 正确:
proxy_pass unix:/run/myapp.sock;(无协议头、绝对路径、末尾分号) - ❌ 错误:
proxy_pass http://unix:/run/myapp.sock;(Nginx 拒绝加载) - ❌ 错误:
proxy_pass /run/myapp.sock;(被当域名处理,502) - 路径中不能有空格、
~、变量(如$socket_path),也不支持相对路径
启用 keepalive 复用 UDS 连接(WebSocket 场景下尤为重要)
WebSocket 是长连接,但默认 UDS 每次请求仍新建 socket 文件描述符。必须通过 upstream 启用连接池,否则高并发下极易耗尽 fd:
- 定义 upstream:
upstream ws_backend { server unix:/run/myapp.sock; keepalive 64; } - location 中引用:
proxy_pass http://ws_backend;(注意这里用http://+ upstream 名,不是直接写 unix:) -
keepalive 64表示每个 worker 缓存最多 64 个空闲 UDS 连接;值低于 16 易复用不足,高于 128 需确认系统fs.file-max和nofile限制
权限与路径位置:缺一不可
WebSocket 握手阶段即建立 UDS 连接,权限问题会在首次 upgrade 请求时暴露为 111: Connection refused 或 13: Permission denied:
- socket 文件建议放
/run/(tmpfs 内存文件系统),例如/run/myapp.sock - 后端启动时设好权限,如 Uvicorn 加参数
--umask 007 --chmod-socket=660 - Nginx worker 用户(如
www-data)必须属于 socket 所属组,或直接chown www-data:www-data /run/myapp.sock - 父目录
/run/需有x权限(允许进入),可用sudo -u www-data ls /run/验证










