Docker¶
This page covers practical container deployment patterns.
Probe-ready app example¶
from __future__ import annotations
import time
STARTED_AT = time.time()
async def app(scope, receive, send):
"""Serve liveness and readiness endpoints."""
if scope["type"] != "http":
return
path = scope.get("path", "/")
if path == "/healthz":
status = 200
body = b"ok"
elif path == "/readyz":
status = 200
body = f"ready uptime={time.time() - STARTED_AT:.2f}".encode()
else:
status = 404
body = b"not found"
await send(
{
"type": "http.response.start",
"status": status,
"headers": [
(b"content-type", b"text/plain; charset=utf-8"),
(b"content-length", str(len(body)).encode("ascii")),
],
}
)
await send({"type": "http.response.body", "body": body})
Minimal Dockerfile¶
FROM python:3.13-slim
WORKDIR /app
COPY . /app
RUN pip install --no-cache-dir palfrey
EXPOSE 8000
CMD ["palfrey", "docs_src.operations.docker_healthcheck:app", "--host", "0.0.0.0", "--port", "8000"]
Recommended multi-stage pattern¶
Use multi-stage builds when compiling optional components or installing build-only dependencies.
Runtime flags often used in containers¶
--host 0.0.0.0--port 8000--workers N(when resource limits justify)- proxy flags when behind ingress
Container health checks¶
Configure orchestrator probes for:
- liveness
- readiness
Example endpoint choices:
/healthz/readyz
Operational recommendations¶
- keep base images pinned
- keep images minimal
- avoid embedding secrets in image layers
- keep startup command explicit and reviewed
Non-technical summary¶
Containers package runtime behavior into repeatable units. Repeatability is what makes staging and production comparable.