Docker容器中使用UV替代PIP安装Flask依赖后应用无法识别库的问题排查与解决
Docker容器中使用UV替代PIP安装Flask依赖后应用无法识别库的问题排查与解决
我最近把自己的Flask应用从用PIP管理依赖改成了UV,Docker构建过程一切正常,也能看到所有包都装好了,但一运行容器,应用就报错说找不到Flask这类依赖库。折腾了好一阵,终于解决了,把过程分享给大家。
问题重现
我的Flask应用之前用PIP在Docker里跑完全没问题,换成UV之后,构建镜像时没有报错,但启动容器就弹出这个错误:
2024-12-14 23:11:35 Traceback (most recent call last): 2024-12-14 23:11:35 File "/app/app.py", line 3, in <module> 2024-12-14 23:11:35 from flask import Flask, render_template, request, send_file 2024-12-14 23:11:35 ModuleNotFoundError: No module named 'flask'
我最初的配置
Dockerfile
FROM python:3.9 COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ WORKDIR /app COPY . . RUN uv venv --python 3.9 && uv sync --frozen EXPOSE 5100 CMD ["python", "app.py"]
pyproject.toml
[project] name = "bgrm" version = "0.1.0" description = "Add your description here" readme = "README.md" requires-python = ">=3.9" dependencies = [ "flask>=3.1.0", "pillow>=9.3.0", "rembg==2.0.30", ]
排查过程
我对比了PIP版本和UV版本的容器里依赖的位置,发现了差异:
- PIP构建的容器里,Flask的元数据同时存在于
/app/.venv/lib/python3.9/site-packages/和/usr/local/lib/python3.9/site-packages/两个路径 - UV构建的容器里,Flask的元数据只在
/app/.venv/lib/python3.9/site-packages/路径下
这说明UV是把所有依赖都装到了它创建的.venv虚拟环境里,而不是全局的Python环境中。
解决方法
后来我翻了一些Docker中运行虚拟环境的旧文档,修改了Dockerfile里的CMD命令,指定用虚拟环境里的Python解释器来启动应用:
CMD [".venv/bin/python", "app.py"]
为什么这样能行?
我梳理了一下UV在Docker里的工作流程,终于搞懂了:
- UV默认会在当前目录创建
.venv虚拟环境文件夹 - 它会扫描系统找到Python 3.9的解释器,把这个版本绑定到虚拟环境中
uv sync会把依赖包都安装到这个.venv虚拟环境里- 之前我用全局的
python命令启动应用,全局环境里根本没装这些依赖,所以才会报错;而用.venv/bin/python启动时,会自动加载虚拟环境里的所有依赖,自然就能找到Flask了
备注:内容来源于stack exchange,提问作者Yury Zaryaninov




