# Django Dockerfile Generator

URL: /dockerizer/django

Generate a production Dockerfile for Django — Gunicorn, static files collected at build time and a non-root runtime image.

## Default configuration

- `appName` (App name): django — Used for the image tag, the compose service and the OCI labels.

- `port` (Port): 8000 — The port the app listens on inside the container. Keep it above 1024 so the process can bind it without root.

- `wsgiModule` (WSGI module): config.wsgi — The dotted path to your wsgi.py — usually <project>.wsgi, matching the folder next to manage.py.

- `workers` (Worker processes): 3 — A common starting point is (2 × CPU cores) + 1. Keep it low if the container has a small CPU limit.

- `collectstatic` (Run collectstatic at build time): true — Bakes the static files into the image so the container does not have to write to disk on boot.

- `pythonVersion` (Python version): 3.13

- `installer` (Dependency manager): uv — uv resolves and installs an order of magnitude faster than pip and reads the same pyproject.toml.

- `baseVariant` (Base image): slim — Debian slim is the right default for Python — Alpine has no manylinux wheels, so every C extension compiles from source.

- `database` (Database service): none — Adds the database to docker-compose.yml with a healthcheck, a named volume and a DATABASE_URL wired into the app.

- `redis` (Redis service): false — Adds Redis to docker-compose.yml and exposes REDIS_URL to the app.

- `cacheMounts` (BuildKit cache mounts): true — Persists the package manager store between builds. Repeat builds skip the download entirely.

- `multiArch` (Multi-architecture build): false — Adds BUILDPLATFORM/TARGETARCH so `docker buildx build --platform linux/amd64,linux/arm64` cross-compiles natively.

- `healthcheck` (Healthcheck): true — Adds a HEALTHCHECK so orchestrators can restart an unresponsive container.

- `tini` (tini init): false — Runs the app under tini so signals and zombie processes are handled properly.

- `ociLabels` (OCI labels): false — Adds org.opencontainers.image.* metadata to the final image.

- `buildSecret` (Build secret mount): false — Reads a private registry token via --mount=type=secret so it never lands in an image layer.

## Generated files

### Dockerfile

Multi-stage build: dependencies, compilation and the runtime image are separate, so only what the app needs at runtime ships.

```docker
# syntax=docker/dockerfile:1
# Generated by Easypanel Dockerizer — https://easypanel.io/dockerizer

# --- Base ---------------------------------------------
FROM python:3.13-slim AS base

# Unbuffered output so logs reach the daemon immediately
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
ENV PATH="/app/.venv/bin:$PATH"
WORKDIR /app

# --- Dependencies -------------------------------------
FROM base AS deps

# Toolchain for packages that have no prebuilt wheel
RUN apt-get update \
 && apt-get install -y --no-install-recommends build-essential libpq-dev libjpeg-dev zlib1g-dev \
 && rm -rf /var/lib/apt/lists/*

# uv ships as a static binary — copy it in rather than pip-installing it
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
ENV UV_COMPILE_BYTECODE=1
ENV UV_LINK_MODE=copy

# Lockfile only, so application edits never re-resolve the tree
COPY pyproject.toml uv.lock* ./
RUN --mount=type=cache,id=uv-cache,target=/root/.cache/uv,sharing=locked \
    uv sync --frozen --no-install-project --no-dev

# --- Runtime ------------------------------------------
FROM base AS runtime

# Shared libraries the compiled wheels link against
RUN apt-get update \
 && apt-get install -y --no-install-recommends libpq5 libjpeg62-turbo \
 && rm -rf /var/lib/apt/lists/*

# Only the resolved virtualenv comes across — no compilers, no headers
COPY --from=deps /app/.venv /app/.venv
RUN groupadd --system --gid 1001 app \
 && useradd --system --uid 1001 --gid app app
COPY --chown=app:app . .

# Collected at build time so the container starts read-only and boots instantly
# The dummy key satisfies Django's startup check and is discarded
RUN SECRET_KEY=build-only DJANGO_SETTINGS_MODULE=config.settings \
    python manage.py collectstatic --noinput --clear
ENV PORT=8000
USER app
EXPOSE 8000
STOPSIGNAL SIGTERM

# Lets Docker, Compose and Easypanel see when the app is wedged
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
  CMD ["python", "-c", "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8000/').status < 400 else 1)"]
CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "3", "--access-logfile", "-", "--error-logfile", "-"]

```

### .dockerignore

Keeps the build context small and stops secrets and local dependencies from reaching an image layer.

```bash
# Version control
.git
.gitignore
.github

# Secrets — never bake these into an image layer
.env
.env.*
!.env.example
*.pem
*.key

# Editor and OS noise
.vscode
.idea
.DS_Store
Thumbs.db

# Docs and local tooling
README.md
LICENSE
docs
.editorconfig
docker-compose*.yml
Dockerfile*
.dockerignore

# Python build and cache artefacts
__pycache__
**/__pycache__
*.py[cod]
*.egg-info
.venv
venv
env
.pytest_cache
.mypy_cache
.ruff_cache
.tox
htmlcov
.coverage

```

### docker-compose.yml

Runs the image locally with its backing services, wired together and health-gated.

```yaml
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    restart: unless-stopped
    ports:
      - "8000:8000"

```

## Frequently asked questions

### Why is collectstatic run during the build?

So the container has no writable-filesystem requirement and no work to do at boot. It also means every replica serves byte-identical assets.

### Should migrations run in the entrypoint?

No. With more than one replica they race each other. Run them as a separate one-off command before the new version starts taking traffic.

### How many Gunicorn workers should I use?

(2 × CPU cores) + 1 is the usual starting point, but a container with a 0.5 CPU limit should run 2 workers, not 5. Watch memory — each worker is a full copy of your app.

## Related generators

- [FastAPI](/dockerizer/fastapi)

- [Flask](/dockerizer/flask)

- [Ruby on Rails](/dockerizer/rails)

- [Node.js](/dockerizer/nodejs)