欢迎光临
我们一直在努力

python的fastapi+uvicorn的linux离线部署

一.导出依赖清单,将所有的包打到requirement.txt文件中

两种方式
1.整个环境的包都写进去,可能包含很多与项目无关的依赖

pip freeze > requirements.txt

只想记录项目真正用到的包,可以配合虚拟环境或使用 pipreqs 等工具

pip install pipreqs
# 默认生成 requirements.txt
pipreqs .

# 如文件已存在,强制覆盖
pipreqs . –force

二、为 Python 3.11 下载兼容的离线包(关键步骤!)

下载离线包注意你生产环境的系统和python的版本号

pip download -r requirements.txt -d ./packages –only-binary=:all: –platform manylinux_2_17_x86_64 –python-version 311 –abi cp311

这条命令会把 requirements.txt 里所有包 的「manylinux_2_17_x86_64 + CPython-3.11 ABI」二进制 wheel 预先下载到 ./packages 目录,不做安装,留给后续离线/容器化部署使用

命令 含义
pip download 仅拉包,不装包
-r requirements.txt 按文件批量下载
-d ./packages 保存目录(自动生成)
–only-binary=:all:
只要 wheel,不要源码 tar.gz;缺 wheel 就直接报错
–platform manylinux_2_17_x86_64 wheel 标签:glibc≥2.17 的 64-bit Linux;不会下 win32/macOS 版本
–python-version 311 3.11.x
–abi cp311 CPython 3.11 ABI(与 PyPy/abi3 区分)

执行后 ./packages 里会出现类似文件

numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.whl
uvloop-0.21.0-cp311-cp311-manylinux_2_17_x86_64.whl

没有 .tar.gz,因此后续离线安装时无需编译,直接:

三、文件打包,上传服务器

 将源代码+package目录打包上传到服务器,注意不要打包本地的环境目录/venv 目录

your_project/
├── main.py # 你的应用主文件
├── requirements.txt # 依赖清单
├── packages/ # 存放所有.whl离线包的目录
└── … # 其他项目文件

四、在服务器离线安装:

4.1 安装python环境,可以直接安装python3.11,也可以安装虚拟环境

4.2 使用本地包安装依赖

pip install –no-index –find-links=./packages -r requirements.txt

注意如果某个包没有打包到packages目录,类似以下出错:

出错ERROR: Could not find a version that satisfies the requirement uvloop>=0.15.1; (sys_platform != "win32" and (sys_platform != "cygwin" and platform_python_implementation != "PyPy")) and extra == "standard" (from uvicorn[standard]) (from versions: none)
ERROR: No matching distribution found for uvloop>=0.15.1; (sys_platform != "win32" and (sys_platform != "cygwin" and platform_python_implementation != "PyPy")) and extra == "standard"

如果服务器可以联网,可以直接下到packages目录中

pip3.11 download uvloop==0.21.0 -d ./packages

然后重新运行安装命令:

sudo pip3.11 install –no-index –find-links=./packages -r requirements.txt

4.3 运行程序

python3.11 -m uvicorn main:app –host 0.0.0.0 –port 8000

五、加一个系统启动脚本

#!/bin/bash
# ————————————————————
# Uvicorn 一键启停脚本(CentOS + Python3.11)
# 放到项目根目录(/www/service)即可
# ————————————————————
set -e

APP_DIR="/www/service"
PID_FILE="$APP_DIR/tool-service-uvicorn.pid"
LOG_FILE="$APP_DIR/run.log"
PYTHON="/usr/bin/python" # 改成你的 3.11 路径
HOST="0.0.0.0"
PORT="9099"

# 确保在项目根下
cd "$APP_DIR"

# 获取 pid(若文件存在且进程存活)
get_pid(){
[ -s "$PID_FILE" ] || return 1
local pid=$(cat "$PID_FILE")
if kill -0 "$pid" 2>/dev/null; then
echo "$pid"
return 0
fi
rm -f "$PID_FILE"
return 1
}

# 启动
start(){
if get_pid >/dev/null; then
echo "uvicorn is already running ($(get_pid))"
return 0
fi
echo "Starting uvicorn …"
nohup $PYTHON -m uvicorn app:app –host $HOST –port $PORT \\
–access-log –use-colors >> "$LOG_FILE" 2>&1 &
echo $! > "$PID_FILE"
echo "started, pid=$(get_pid)"
}

# 停止
stop(){
PID=$(get_pid) || { echo "uvicorn not running"; return 0; }
echo "Stopping uvicorn ($PID) …"
kill -TERM "$PID"
for i in {1..10}; do
kill -0 "$PID" >/dev/null 2>&1 || { rm -f "$PID_FILE"; echo "stopped"; return 0; }
sleep 1
done
echo "force kill …"
kill -9 "$PID" && rm -f "$PID_FILE"
}

# 重启
restart(){
stop
sleep 1
start
}

# 状态
status(){
PID=$(get_pid) && echo "uvicorn is running, pid=$PID" || echo "uvicorn is stopped"
}

# 路由
case "$1" in
start) start ;;
stop) stop ;;
restart) restart ;;
status) status ;;
*) echo "Usage: $0 {start|stop|restart|status}"; exit 1 ;;
esac

操作命令

./uvicorn.sh start # 后台启动
./uvicorn.sh stop # 优雅停止
./uvicorn.sh restart # 先停后启
./uvicorn.sh status # 查看运行状态
tail -f run.log # 实时日志

赞(0)
未经允许不得转载:171主机测评 » python的fastapi+uvicorn的linux离线部署
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址