Detection

migetpacks detects Python when any of these files are present in your project root:
  • requirements.txt
  • setup.py
  • Pipfile
  • pyproject.toml

Version Detection

Python version is resolved in this order:
PrioritySourceExample
1PYTHON_VERSION env varPYTHON_VERSION=3.12
2.python-version file3.12.8
3runtime.txt filepython-3.12.8
4requires-python in uv.lockrequires-python = ">=3.13"
5requires-python in pyproject.tomlrequires-python = ">=3.12"
6Default3.12.8
Version constraints are normalized for Docker compatibility (e.g., >=3.13 becomes 3.13).

Build Process

migetpacks generates a multi-stage Dockerfile with virtualenv isolation:

Standard pip/pipenv/poetry

# Builder stage
FROM python:3.12 AS builder
WORKDIR /build

# Layer 1: Copy dependency files
COPY requirements.txt* pyproject.toml* poetry.lock* Pipfile* ./
ENV PYTHONUNBUFFERED=1

# Layer 2: Create virtualenv
RUN python -m venv /opt/venv \
    && /opt/venv/bin/pip install --upgrade pip

# Layer 3: Install dependencies (CACHED when only source code changes)
RUN . /opt/venv/bin/activate \
    && pip install -r requirements.txt

# Layer 4: Copy source code
COPY . .

# Layer 5: Collectstatic and cleanup
RUN . /opt/venv/bin/activate \
    && python manage.py collectstatic --noinput \
    && rm -rf .git test tests __pycache__ .pytest_cache .coverage htmlcov

# 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"
ENV PYTHONUNBUFFERED=1

uv Projects

When uv.lock is present, migetpacks uses the uv package manager natively:
# Builder stage
FROM python:3.13 AS builder
WORKDIR /build

COPY requirements.txt* pyproject.toml* uv.lock* ./
ENV PYTHONUNBUFFERED=1

# Install uv and sync dependencies
RUN pip install uv \
    && uv venv /app/.venv \
    && UV_PROJECT_ENVIRONMENT=/app/.venv uv sync --locked --no-dev

COPY . .

# Runtime stage
FROM python:3.13-slim
WORKDIR /app
COPY --from=builder /app/.venv /app/.venv
COPY --from=builder /build /app
ENV PATH="/app/.venv/bin:$PATH"

Package Manager Detection

FilePackage Manager
uv.lockuv (native)
requirements.txtpip
Pipfile / Pipfile.lockpipenv
poetry.lockpoetry
pyproject.toml (no lock)pip

Dependency Detection

migetpacks automatically detects database and XML libraries from your dependency files and installs the required system packages:
Python PackageSystem Package
psycopg, asyncpg, aiopglibpq5
mysqlclient, pymysql, aiomysqllibmariadb3
aiosqlitelibsqlite3-0
lxmllibxml2, libxslt1.1

Runtime Cleanup

The following are removed from the final image:
  • .git/, .github/
  • test/, tests/
  • __pycache__/, .pytest_cache/
  • .coverage, htmlcov/

Django Support

If manage.py is detected, python manage.py collectstatic --noinput is automatically run during the build.

Run Command

The default run command is determined in this order:
PrioritySourceCommand
1RUN_COMMAND env varUser-specified
2web: in ProcfileFrom Procfile
3Django + gunicorngunicorn project.wsgi:application --bind 0.0.0.0:$PORT
4Django + uvicornuvicorn project.asgi:application --host 0.0.0.0 --port $PORT
5gunicorn detectedgunicorn app:app --bind 0.0.0.0:$PORT
6uvicorn detecteduvicorn main:app --host 0.0.0.0 --port $PORT
7manage.py existspython manage.py runserver 0.0.0.0:$PORT
8Defaultpython app.py or python main.py

Caching

Docker Layer Caching

Dependencies are installed in a separate layer using a virtualenv. pip install is only re-run when dependency files change.

BuildKit Cache Mounts

When BUILD_CACHE_DIR is configured, BuildKit cache mounts are used:
Cache PathContents
/cache/pippip wheel cache
/cache/uvuv package cache

Registry Cache

Use CACHE_IMAGE to push/pull BuildKit inline cache layers to a registry for cross-build caching.

DHI Support

Python is fully supported with Docker Hardened Images.
StageImage
Builddhi.io/python:{version}-dev
Runtimedhi.io/python:{version}
The -dev variant includes a shell and build tools. The runtime image is distroless with no shell, providing a minimal attack surface.
The virtualenv is copied from the builder stage to the distroless runtime, ensuring all installed packages are available without needing pip in the runtime image.

Example

docker run --rm \
  -v /path/to/app:/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=my-python-app:latest \
  miget/migetpacks:latest

With Custom Options

docker run --rm \
  -v /path/to/app:/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=registry.io/app:v1 \
  -e PYTHON_VERSION=3.13 \
  -e RUN_COMMAND="gunicorn myapp.wsgi:application --bind 0.0.0.0:5000" \
  -e USE_DHI=true \
  miget/migetpacks:latest