Uvicorn通过--ssl-keyfile和--ssl-certfile可直接启用HTTPS,但需确保私钥为PEM格式且权限600、证书链顺序正确、域名匹配、TLS版本兼容;生产环境应使用Nginx等反向代理终止SSL。

直接加 --ssl-keyfile 和 --ssl-certfile 就能启用 HTTPS,但私钥路径、证书格式、TLS 版本不匹配会导致启动失败或浏览器报错“不安全连接”。
Uvicorn 启动时传入 SSL 参数最简单
命令行是最直接的方式,Uvicorn 原生支持,无需额外封装或反向代理:
-
--ssl-keyfile必须是 PEM 格式私钥(不能是 .pfx/.p12),且权限建议设为600(chmod 600 key.pem),否则 uvicorn 会拒绝加载 -
--ssl-certfile可以是单个 PEM 证书,也支持拼接完整的证书链(如:域名证书 + 中间 CA),顺序必须是“域名证书在前,根/中间证书在后” - 如果私钥有密码,必须加
--ssl-keyfile-password;漏掉会卡在输入提示,导致服务无法自动启动(尤其在 systemd 或 Docker 中) - 默认
--ssl-version=2对应 TLS 1.2;如需 TLS 1.3,某些旧版 uvicorn 不支持,得确认版本 ≥ 0.29.0(用uvicorn --version查)
常见错误:证书校验失败或连接被重置
浏览器打不开、curl 报 SSL_ERROR_SYSCALL 或 ERR_SSL_PROTOCOL_ERROR,大概率不是代码问题,而是:
Uvicorn 0.52.1 是 Python ASGI Web 服务器,提供异步应用服务及 WebSocket 支持,常用于 FastAPI、Starlette 等应用的开发和部署。本下载为官方 PyPI 通用 wheel 包,可使用 pip 安装,并由包管理器处理所需依赖。
- 证书域名和请求 Host 不一致(比如用
localhost证书访问公网 IP) - 私钥和证书不配对(可用
openssl x509 -noout -modulus -in cert.pem | openssl md5和openssl rsa -noout -modulus -in key.pem | openssl md5对比模数) - 证书过期(
openssl x509 -in cert.pem -text -noout | grep "Not After") - 系统时间错误(尤其是 Docker 容器没同步宿主机时间,会导致证书“未生效”或“已过期”)
生产环境别裸跑 Uvicorn + SSL
Uvicorn 自带 SSL 能跑通,但不适合生产:
- 不支持 OCSP Stapling、HSTS、证书自动续期(比如 Let’s Encrypt 的 certbot hook)
- 多进程下每个 worker 都要重复加载证书和私钥,内存开销翻倍
- 无法做 TLS 1.3 Early Data、ALPN 协商优化,HTTP/2 支持也不如 Nginx 稳定
- 更关键的是:私钥文件直接暴露在应用进程里,一旦服务被攻破,私钥就丢了
用 Nginx 做 SSL 终止才是常规操作
把加密卸载给 Nginx,Uvicorn 回归纯 HTTP 内网通信,既安全又灵活:
- Nginx 监听 443,配置
ssl_certificate和ssl_certificate_key,处理 TLS 握手 - Uvicorn 只监听本地端口(如
--host 127.0.0.1 --port 8000)或 Unix socket(--uds /tmp/uvicorn.sock) - Nginx 的
proxy_set_header X-Forwarded-Proto https必须设置,否则 FastAPI 的request.url还是 http 开头 - WebSocket 要额外加
proxy_set_header Upgrade $http_upgrade和Connection "upgrade"
真正难的不是加参数,而是证书生命周期管理——自签名测试还行,上生产必须考虑续期、轮换、密钥隔离。裸跑 SSL 的 uvicorn 适合 demo 或内网调试,上线前务必切到反向代理模式。

















