Last active
October 26, 2025 23:23
-
-
Save goten002/d7c2c24a6d94b77fe23b2f1d47dcd418 to your computer and use it in GitHub Desktop.
Optimized Dockerfile for deploying a FastAPI application using Gunicorn and UvicornWorker. Includes best practices like a non-root user, UV package manager for dependency management, and multi-stage builds using alpine for smaller images.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| FROM python:3.13-alpine AS base | |
| # Set environment variables for Python runtime behavior | |
| ENV PYTHONUNBUFFERED=1 \ | |
| PYTHONDONTWRITEBYTECODE=1 \ | |
| APP_DIR="/app" | |
| # Define build arguments for non-root user/group IDs (defaults provided) | |
| ARG APP_USER=appuser | |
| ARG APP_UID=1001 | |
| ARG APP_GID=1001 | |
| # Create the non-root group and user for security, setting APP_DIR as the home directory | |
| RUN addgroup -g $APP_GID $APP_USER \ | |
| && adduser -h $APP_DIR -u $APP_UID -G $APP_USER -D $APP_USER | |
| # Set working directory to the application root | |
| WORKDIR $APP_DIR | |
| # ------------------------ | |
| # Builder stage: Install system dependencies (optional) and project Python dependencies | |
| # Inherits base settings (Python, paths, user args) | |
| # ------------------------ | |
| FROM base AS builder | |
| # Set environment variables specifically for uv operations | |
| ENV UV_CACHE_DIR="/root/.cache/uv" \ | |
| UV_PROJECT="$APP_DIR" \ | |
| UV_FROZEN="true" \ | |
| UV_VENV_SEED="false" | |
| # Install system packages potentially needed for building Python extensions (e.g., C compilers) | |
| # This is optional if all your Python dependencies are pure Python wheels. | |
| RUN apk update \ | |
| && apk add --no-cache \ | |
| build-base \ | |
| && rm -rf /var/cache/apk/* | |
| # Copy the uv and uvx executables from an official uv image directly into the builder's /bin | |
| # This makes 'uv' available without needing the full base image or installer script. | |
| COPY --from=ghcr.io/astral-sh/uv /uv /uvx /bin/ | |
| # Install Python dependencies using uv sync | |
| RUN --mount=type=cache,target=$UV_CACHE_DIR \ | |
| --mount=type=bind,source=uv.lock,target=uv.lock,ro \ | |
| --mount=type=bind,source=pyproject.toml,target=pyproject.toml,ro \ | |
| uv sync --no-install-project | |
| # ------------------------ | |
| # Production stage: Build the final lean image | |
| # Inherits base settings (Python, paths, user args) - DOES NOT inherit builder contents directly | |
| # ------------------------ | |
| FROM base AS production | |
| # Copy the application code from the build context into the image | |
| # Set ownership to the non-root user defined earlier | |
| COPY --chown=$APP_UID:$APP_GID main_package $APP_DIR/main_package | |
| # Alternatively, in case of src project structure | |
| #COPY --chown=$APP_UID:$APP_GID src $APP_DIR/src | |
| # Copy the populated virtual environment (with installed dependencies) from the builder stage | |
| COPY --from=builder $APP_DIR/.venv $APP_DIR/.venv | |
| # Add the virtual environment's bin directory to the PATH | |
| ENV PATH="$APP_DIR/.venv/bin:$PATH" | |
| # Switch to the non-root user to run the application | |
| USER $APP_UID:$APP_GID | |
| # Expose the port the application will listen on (default for FastAPI/Gunicorn) | |
| EXPOSE 8000 | |
| # Define the command to run the application using Gunicorn | |
| # Gunicorn and uvicorn must be listed as dependencies in pyproject.toml (and thus uv.lock) | |
| # The PATH variable (set in base stage) ensures 'gunicorn' is found in the venv's bin directory. | |
| CMD ["gunicorn", "-b", "0.0.0.0:8000", "-k", "uvicorn.workers.UvicornWorker", "main_package.app:app"] | |
| # Alternatively, in case of src project structure | |
| #CMD ["gunicorn", "--chdir", "src", "-b", "0.0.0.0:8000", "-k", "uvicorn.workers.UvicornWorker", "main_package.app:app"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment