The following Dockerfile builds a working Fastapi demo app running under a single instance of uvicorn:
# 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"]
As you cen see from the heavily commented file I am using a multistage build using the 3.11 image to build the environment and then the slim image to copy the source, rebuild the environment and run the app.
Now I tried changing the last line to:
ENTRYPOINT ["python", "-m", "gunicorn", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000", "src.mylib.mymod:app"]
but get the following error:
(.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
please help fix. Thanks
The issue is that you are not copying the
gunicornpackage into your secondruntimestage.In the first stage
builder:gunicorngets/usr/local/lib/python3.11/gunicorn(+ dependencies)/usr/local/bin/gunicornBoth are missing in your second stage.
The easiest solution would be to also install the missing package in your second stage:
RUN pip install --no-cache-dir gunicornEDIT:
Note that you possibly have a typo:
uvicornvsgunicorn