使用UV在Docker部署Django应用:依赖安装失败致Django包缺失
问题诊断与修复方案
核心问题
你遇到的ModuleNotFoundError: No module named 'django',本质是系统级gunicorn未使用uv创建的虚拟环境依赖:
- 通过
apt-get install gunicorn安装的是系统Python版本的gunicorn,它只会查找系统Python的site-packages目录,无法识别/app/.venv虚拟环境中的依赖。 - 虽然设置了
PATH="/app/.venv/bin:$PATH",但切换到appuser后,PATH的生效逻辑可能存在优先级问题,导致系统版gunicorn被优先调用。
具体修复步骤
1. 移除系统级gunicorn,改用uv安装到虚拟环境
修改Dockerfile中apt安装的部分,删除gunicorn:
RUN apt-get update && \ apt-get install -y --no-install-recommends gcc python3-dev libpq-dev &&\ apt-get clean && \ rm -rf /var/lib/apt/lists/*
在本地通过uv add gunicorn将其添加到项目依赖,更新uv.lock和pyproject.toml,确保uv sync会把gunicorn安装到虚拟环境中。
2. 调整环境变量与用户切换顺序
将PATH设置放在用户创建前,确保appuser能继承正确的环境变量:
# 先设置虚拟环境PATH,再创建用户 ENV PATH="/app/.venv/bin:$PATH" RUN useradd -m appuser && chown -R appuser:appuser /app USER appuser WORKDIR /app/myproject EXPOSE 9090 CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:9090"]
3. 可选:显式指定虚拟环境中的gunicorn路径
如果PATH设置仍有问题,直接调用虚拟环境内的gunicorn可彻底规避路径冲突:
CMD ["/app/.venv/bin/gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:9090"]
修复后的完整Dockerfile示例
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim WORKDIR /app # Enable bytecode compilation ENV UV_COMPILE_BYTECODE=1 # Copy from the cache instead of linking since it's a mounted volume ENV UV_LINK_MODE=copy RUN apt-get update && \ apt-get install -y --no-install-recommends gcc python3-dev libpq-dev &&\ apt-get clean && \ rm -rf /var/lib/apt/lists/* # Install the project's dependencies using the lockfile and settings RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=uv.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ uv sync --frozen --no-install-project --no-dev # Then, add the rest of the project source code and install it ADD . /app RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --frozen --no-dev # Set PATH for virtual environment before creating user ENV PATH="/app/.venv/bin:$PATH" RUN useradd -m appuser && chown -R appuser:appuser /app USER appuser WORKDIR /app/myproject EXPOSE 9090 CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:9090"]
内容的提问来源于stack exchange,提问作者fccoelho
相关产品推荐
相关产品推荐

