最简单可靠的Uvicorn后台启动方式是nohup uvicorn main:app --host 0.0.0.0 --port 8000 > uvicorn.log 2>&1 &,它避免终端断开中断、统一记录日志并真正后台运行。

直接用 nohup 启动最简单可靠
Uvicorn 本身不提供 daemon 模式,--daemon 参数不存在,强行加会报错。所以必须靠 shell 工具托管进程。
最常用、最不容易出问题的方式是:
nohup uvicorn main:app --host 0.0.0.0 --port 8000 > uvicorn.log 2>&1 &-
nohup防止终端断开后进程被杀 -
> uvicorn.log把标准输出写入日志文件 -
2>&1把错误输出也合并进同一日志(否则错误全丢掉) -
&让命令真正后台执行(不卡住当前 shell)
运行后终端会返回一个 job 号和 PID,记下 PID(比如 12345),后续查杀都靠它。
为什么不用 systemd 或 supervisord?
不是不能用,而是容易多一层抽象导致排查变慢——尤其在开发或临时部署阶段。
常见踩坑点:
- systemd unit 文件里漏写
WorkingDirectory,导致main.py找不到模块 - 没设
EnvironmentFile,环境变量(如DB_URL)全失效 - supervisord 的
autostart=true在非 root 用户下可能静默失败
如果你只是单机跑一个 FastAPI 服务,nohup + 日志重定向已足够稳;真要上生产集群,再切 Gunicorn + systemd。
Uvicorn 0.52.1 是 Python ASGI Web 服务器,提供异步应用服务及 WebSocket 支持,常用于 FastAPI、Starlette 等应用的开发和部署。本下载为官方 PyPI 通用 wheel 包,可使用 pip 安装,并由包管理器处理所需依赖。
启动后怎么确认它真在跑?
别只信终端返回的 PID,得验证端口和进程树是否真实存在:
- 查端口占用:
lsof -i :8000或ss -tuln | grep :8000 - 查进程完整命令:
ps -ef | grep uvicorn | grep -v grep - 如果看到
python -m uvicorn或/path/to/venv/bin/uvicorn,说明是你要的那个进程 - 注意:
ps结果里带--reload的一定不能用于后台长期运行,它只适合开发
一旦发现端口被占但没对应 uvicorn 进程,大概率是上次异常退出没清理干净,得手动 kill -9 掉残留 PID。
想换端口或改配置,但不想手动 kill?
可以加个简单 wrapper 脚本自动处理旧进程:
#!/bin/bash
PORT=${1:-8000}
PID=$(lsof -t -i tcp:$PORT 2>/dev/null)
if [ -n "$PID" ]; then
echo "Killing existing process on port $PORT (PID: $PID)"
kill -9 $PID 2>/dev/null
fi
nohup uvicorn main:app --host 0.0.0.0 --port $PORT > uvicorn-$PORT.log 2>&1 &
echo "Started on port $PORT, log: uvicorn-$PORT.log"
保存为 start.sh,运行 bash start.sh 8001 就能一键换端口重启。关键点是:先清再启,避免 [Errno 98] Address already in use。
实际部署时,最容易被忽略的是日志文件权限和磁盘空间——nohup.log 不设轮转,跑两周就占满根分区。上线前务必确认日志路径可写,且有基础清理机制。

















