Docker容器中无法通过Gunicorn运行Uvicorn的问题修复请求
问题描述
我通过多阶段构建的Dockerfile可正常运行单实例Uvicorn的FastAPI演示应用,但将启动命令改为Gunicorn+UvicornWorker后,容器启动报错:exec: "gunicorn": executable file not found in $PATH。
原正常运行的Dockerfile:
# example of a multistage build # Stage 1: Builder # Use the official larger Docker Python image FROM python:3.11-bookworm as builder # Install python modules with known release RUN pip install poetry==1.8.2 RUN pip install gunicorn==21.2.0 # Set Poetry environment variables for non-interactive installation ENV POETRY_NO_INTERACTION=1 \ POETRY_VIRTUALENVS_CREATE=1 \ POETRY_VIRTUALENVS_IN_PROJECT=1 \ POETRY_CACHE_DIR=/tmp/poetry_cache WORKDIR /app # Copy the project definition files COPY pyproject.toml poetry.lock README.md ./ # Install dependencies without the dev dependencies and without the project package itself RUN poetry install --no-root --no-dev && rm -rf $POETRY_CACHE_DIR # Stage 2: Runtime # now switch to the slimmer version and don't need poetry anymore FROM python:3.11-slim-bookworm as runtime # Copy the virtual environment from the builder stage ENV VIRTUAL_ENV=/app/.venv \ PATH="/app/.venv/bin:$PATH" COPY --from=builder /app/.venv /app/.venv # configurations, including the current working directory set by WORKDIR, do not persist from one stage to another. # Set the working directory in the container WORKDIR /app # Copy the application code and configuration into the container COPY src ./src COPY config ./config # Documentation of the port the app runs on EXPOSE 8000 # Define the entrypoint for running the application ENTRYPOINT ["python", "-m", "uvicorn", "--host", "0.0.0.0", "src.mylib.mymod:app"]
修改后的ENTRYPOINT命令:
ENTRYPOINT ["python", "-m", "gunicorn", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000", "src.mylib.mymod:app"]
报错信息:
(.venv) bob /Volumes/2TBWDB/code/uvitest [main] $ docker compose up -d [+] Running 0/1 ⠹ Container uvitest-uvitest-1 Starting 0.2s Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "gunicorn": executable file not found in $PATH: unknown
修复方案
问题核心是Gunicorn未被安装到Poetry创建的虚拟环境中:你在builder阶段用pip install gunicorn直接安装到了系统Python环境,而非Poetry生成的/app/.venv虚拟环境,导致runtime阶段复制的虚拟环境里没有Gunicorn,自然找不到可执行文件。
有两种可行修复方式:
方式一:让Poetry管理Gunicorn依赖
- 在项目的
pyproject.toml中,将Gunicorn添加到生产依赖列表:
[tool.poetry.dependencies] python = "^3.11" fastapi = "^0.109.0" uvicorn = "^0.27.0" gunicorn = "^21.2.0" # 新增该行
- 删除builder阶段中单独安装Gunicorn的命令
RUN pip install gunicorn==21.2.0 - 重新构建镜像,此时Poetry会将Gunicorn安装到虚拟环境中,runtime阶段复制后即可正常调用。
方式二:在builder阶段的虚拟环境内安装Gunicorn
若不想将Gunicorn加入项目依赖,可修改builder阶段的命令,通过Poetry进入虚拟环境后安装:
# 在builder阶段的`poetry install`命令后添加以下内容 RUN poetry run pip install gunicorn==21.2.0
这样Gunicorn会被安装到/app/.venv虚拟环境中,复制到runtime阶段后就能被PATH找到。
另外,你当前用python -m gunicorn的写法可以直接简化为gunicorn命令(只要虚拟环境的bin目录在PATH中),两种写法均有效,但核心是确保Gunicorn存在于复制到runtime的虚拟环境内。
内容的提问来源于stack exchange,提问作者Robert Alexander
相关产品推荐
相关产品推荐

