How to Deploy Python to Docker Without Writing a Dockerfile
You can containerize any Python application without writing a Dockerfile using migetpacks. It auto-detects your package manager (pip, uv, poetry, or pipenv), reads your Python version from .python-version or pyproject.toml, installs dependencies in an isolated virtualenv, and produces an optimized production image. One command, zero configuration.
Why Is Writing a Dockerfile for Python So Complicated?
A production-ready Python Dockerfile requires:
- Multi-stage builds to separate build dependencies from runtime
- Virtualenv isolation to avoid polluting the system Python
- Correct layer ordering for pip caching
- Installing system libraries for packages like
psycopg2orlxml - Choosing the right base image (
python:slimvspython:alpine) - Setting
PYTHONUNBUFFERED=1for proper logging - Handling Django static files with
collectstatic
Most tutorials skip half of these. You end up with bloated images, missing dependencies, or broken Django deployments.
How Do I Containerize a Python App Without a Dockerfile?
Open your terminal, navigate to your Python project, and run:
cd ~/projects/my-django-app
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-django-app:latest \
miget/migetpacks:latest
That's it. migetpacks will:
- Detect Python from your
requirements.txt,pyproject.toml, orPipfile - Detect your package manager from lockfiles
- Read version from
.python-version,runtime.txt, orpyproject.toml - Create an isolated virtualenv
- Install dependencies with caching
- Run
collectstaticfor Django projects - Output a slim production image
What Package Managers Does migetpacks Support?
migetpacks automatically detects your package manager from lockfiles:
| File | Package Manager |
|---|---|
uv.lock | uv (native) |
requirements.txt | pip |
Pipfile / Pipfile.lock | pipenv |
poetry.lock | poetry |
pyproject.toml (no lock) | pip |
No configuration needed. uv projects get native uv sync support for faster installs.
How Does migetpacks Detect My Python Version?
Version is resolved in this order:
| Priority | Source | Example |
|---|---|---|
| 1 | PYTHON_VERSION env var | PYTHON_VERSION=3.12 |
| 2 | .python-version file | 3.12.8 |
| 3 | runtime.txt file | python-3.12.8 |
| 4 | requires-python in uv.lock | requires-python = ">=3.13" |
| 5 | requires-python in pyproject.toml | requires-python = ">=3.12" |
| 6 | Default | Latest stable |
Version constraints like >=3.13 are normalized automatically for Docker compatibility.
What Does the Generated Dockerfile Look Like?
migetpacks generates an optimized multi-stage Dockerfile with virtualenv isolation:
# Builder stage
FROM python:3.12 AS builder
WORKDIR /build
COPY requirements.txt* pyproject.toml* ./
ENV PYTHONUNBUFFERED=1
RUN python -m venv /opt/venv \
&& /opt/venv/bin/pip install --upgrade pip \
&& . /opt/venv/bin/activate \
&& pip install -r requirements.txt
COPY . .
RUN . /opt/venv/bin/activate \
&& python manage.py collectstatic --noinput
# Runtime stage
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /opt/venv /opt/venv
COPY --from=builder /build /app
ENV PATH="/opt/venv/bin:$PATH"
You never write or maintain this file - migetpacks handles it automatically.
How Do I Build a Django App with migetpacks?
The same command works for Django, FastAPI, Flask, or any Python framework. Just navigate to your project:
cd ~/projects/my-django-app
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-django:latest \
miget/migetpacks:latest
migetpacks automatically:
- Detects
manage.pyand runscollectstatic - Detects gunicorn/uvicorn and configures the run command
- Installs PostgreSQL/MySQL client libraries when detected in dependencies
How Do I Build a FastAPI App with migetpacks?
FastAPI works out of the box:
cd ~/projects/my-fastapi-app
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-fastapi:latest \
miget/migetpacks:latest
If uvicorn is in your dependencies, the default run command becomes:
uvicorn main:app --host 0.0.0.0 --port $PORT
What Database Libraries Are Auto-Detected?
migetpacks inspects your dependencies and installs required system packages:
| Python Package | System Package |
|---|---|
psycopg, asyncpg, aiopg | libpq5 |
mysqlclient, pymysql, aiomysql | libmariadb3 |
aiosqlite | libsqlite3-0 |
lxml | libxml2, libxslt1.1 |
No more "missing library" errors at runtime.
How Do I Build Secure Distroless Images?
Enable Docker Hardened Images for minimal, CVE-free containers:
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-app:latest \
-e USE_DHI=true \
miget/migetpacks:latest
DHI images are distroless - no shell, no package manager, minimal attack surface.
Next Steps
- Full Python documentation - version detection, caching, run commands
- Deploy on Miget - unlimited apps, one price
- Star on GitHub - migetpacks is open source
- Related guides: Node.js, Go, Ruby