---
title: "Nuitka + Docker: Building Minimal, Compiled Python Containers"
description: Discover how to build minimal, secure Python containers using Nuitka and Docker, reducing image size while enhancing performance and security.
image: https://images.unsplash.com/photo-1605745341112-85968b19335b?w=1400&q=80
---

[![Thought Parameters](https://legacy.thoughtparameters.com/logos/logo-horizontal-inverted.png)](https://thoughtparameters.com/)

Products

[Identity & Access Directory, SSO, SCIM and passkey MFA for every app.](https://thoughtparameters.com/products/identity) [SRE Reliability SLOs, error budgets, dependency graphs and status pages.](https://thoughtparameters.com/products/sre) [DORA Metrics Delivery metrics tied to reliability and error budgets.](https://thoughtparameters.com/products/dora) [Incident & On-call Schedules, escalations, SMS and voice paging.](https://thoughtparameters.com/products/oncall) [ITSM & Service Desk AI-triaged service desk with a shared CMDB.](https://thoughtparameters.com/products/itsm) [Developer Portal Service catalog, scorecards and golden paths.](https://thoughtparameters.com/products/portal) [Secrets & Feature Flags Secrets, config and edge-evaluated flags.](https://thoughtparameters.com/products/vault) [Platform overview → How the products fit together, plus early-access demos.](https://thoughtparameters.com/platform)

Services

[DevOps & CI/CD Automated pipelines and deployment workflows that ship safely.](https://thoughtparameters.com/services/devops-cicd) [Platform Engineering Internal platforms and golden paths for engineering teams.](https://thoughtparameters.com/services/platform-engineering) [Site Reliability Engineering SLOs, observability, and incident response that hold up.](https://thoughtparameters.com/services/site-reliability-engineering) [Cloud Infrastructure GCP and AWS architecture, migrations, and infrastructure as code.](https://thoughtparameters.com/services/cloud-infrastructure) [Cybersecurity & Compliance Security built into delivery, not bolted on after an incident.](https://thoughtparameters.com/services/cybersecurity-compliance) [Custom Software Development Web apps, APIs, and internal tools built to last.](https://thoughtparameters.com/services/custom-software-development) [Fractional CTO & Advisory Senior technical leadership without the executive headcount.](https://thoughtparameters.com/services/fractional-cto-advisory) 

[View all services →](https://thoughtparameters.com/services) 

Industries

[SaaS & Software Startups Scaling infrastructure ahead of growth, without over-engineering it.](https://thoughtparameters.com/industries/saas-startups) [Fintech & Financial Services Auditable, secure, and built to hold up under scrutiny.](https://thoughtparameters.com/industries/fintech-financial-services) [E-commerce & Retail Tech Infrastructure that survives your busiest day of the year.](https://thoughtparameters.com/industries/ecommerce-retail-tech) [Healthcare & Health Tech Software that respects the weight of the data it holds.](https://thoughtparameters.com/industries/healthcare-health-tech) [Enterprise & Mid-Market Modernization without the multi-year rewrite.](https://thoughtparameters.com/industries/enterprise-midmarket) [Developer Tools & Infrastructure Held to the standard your own customers hold you to.](https://thoughtparameters.com/industries/developer-tools-infrastructure) 

[View all industries →](https://thoughtparameters.com/industries) 

Company

[About Who we are, where we're based, and how we think about the work.](https://thoughtparameters.com/about) [How We Work Our process, from first call to delivered software.](https://thoughtparameters.com/how-we-work) [News Product launches, site updates, and other Thought Parameters news.](https://thoughtparameters.com/news) [Blog Engineering notes on DevOps, cloud infrastructure, and security.](https://thoughtparameters.com/thought-parameters-llc-blog) [Careers Open roles at Thought Parameters — when the work calls for one.](https://thoughtparameters.com/careers) 

[Latest news →](https://thoughtparameters.com/news) 

[Call toll-free: 1 (888) 875-1399](tel:+18888751399) [Free Consultation](https://thoughtparameters.com/free-consultation)

[1 (888) 875-1399](tel:+18888751399) [Free Consultation](https://thoughtparameters.com/free-consultation) ☰

[← Back to blog](https://thoughtparameters.com/thought-parameters-llc-blog)

Python

# Nuitka + Docker: Building Minimal, Compiled Python Containers

[Jason Miller](https://thoughtparameters.com/thought-parameters-llc-blog/author/jason-miller) · Sep 19, 2026, 7:27:30 AM

![](https://images.unsplash.com/photo-1605745341112-85968b19335b?w=1400&q=80)

![Nuitka + Docker: Building Minimal, Compiled Python Containers](https://images.unsplash.com/photo-1605745341112-85968b19335b?w=1400&q=80)

A standard Python container for a FastAPI service typically runs 150 MB to 1 GB depending on base image and dependencies. Compile the same app with Nuitka first and containerize the binary instead of the source, and that number drops under 40 MB — with faster cold starts and no interpreter left inside the container for an attacker to abuse post-exploitation.

The pattern is a standard multi-stage Docker build: compile in one stage, ship only the resulting binary in the next.

## Why compile before you containerize

The normal Python container workflow — copy source, install a full CPython runtime and every dependency — creates problems that compound at scale: bloated images slow down Kubernetes pod scheduling, anyone with image-pull access can read your application logic, and a live interpreter in the runtime container is a genuinely useful tool for an attacker who's already gotten in. A Nuitka-compiled container has none of that. The compiled binary *is* the application — no interpreter, no source, no pip.

## Multi-stage build: FastAPI

```
# Stage 1: Compile
FROM python:3.12-slim AS builder
WORKDIR /build

RUN apt-get update && apt-get install -y \
    gcc patchelf ccache libffi-dev \
    && rm -rf /var/lib/apt/lists/*

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

RUN python -m nuitka \
    --standalone --onefile \
    --include-package=fastapi \
    --include-package=uvicorn \
    --include-package=pydantic \
    --include-package=starlette \
    --output-filename=app \
    main.py

# Stage 2: Runtime — nothing but the binary
FROM debian:bookworm-slim AS runtime
WORKDIR /app
COPY --from=builder /build/app .

RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser

EXPOSE 8000
CMD ["/app/app"]
```

As with any Nuitka web app, `main.py` has to launch Uvicorn programmatically — a CLI-style `uvicorn main:app` module reference can't be statically traced:

```
# main.py
import uvicorn
from api import app

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000, workers=1)
```

`workers=1` is required, not optional — Nuitka compiled binaries and Uvicorn's multi-worker process spawning don't get along. See our [deeper walkthrough of the Flask/FastAPI/Django compilation trade-offs](https://thoughtparameters.com/contact) for why.

## Multi-stage build: Flask + Waitress

Flask compiles more predictably because Waitress uses threads rather than spawning processes, sidestepping the Uvicorn conflict entirely. The only extra step is telling Nuitka about your templates and static assets, which it won't discover on its own:

```
RUN python -m nuitka \
    --standalone --onefile \
    --include-data-dir=templates=templates \
    --include-data-dir=static=static \
    --include-package=waitress \
    --include-package=flask \
    --output-filename=app \
    main.py
```

```
# main.py
from waitress import serve
from myapp import create_app

if __name__ == "__main__":
    app = create_app()
    serve(app, host="0.0.0.0", port=8080, threads=8)
```

## Going distroless

Swap the Debian runtime base for Google's distroless image to strip out the shell and package manager entirely:

```
FROM gcr.io/distroless/cc-debian12 AS runtime
WORKDIR /app
COPY --from=builder /build/app .
EXPOSE 8000
ENTRYPOINT ["/app/app"]
```

`distroless/cc` ships the C standard library a Nuitka binary needs, and nothing else — no shell, no package manager, no `docker exec` for debugging. That's the point: plan your observability strategy (structured JSON logs to stdout, distributed tracing) around not having a shell to fall back on.

| Approach | Base image | Approximate size |
| --- | --- | --- |
| CPython + source | python:3.12 | 900 MB – 1.2 GB |
| CPython + source | python:3.12-slim | 150–300 MB |
| Nuitka compiled | debian:bookworm-slim | 60–100 MB |
| Nuitka compiled | distroless/cc | 35–60 MB |

## Caching the C compilation step

Nuitka's real cost is the C compile, not the Python analysis. Enable `ccache` in the builder stage and cache it across CI runs:

```
FROM python:3.12-slim AS builder
ENV CCACHE_DIR=/ccache
ENV PATH="/usr/lib/ccache:${PATH}"
RUN apt-get update && apt-get install -y gcc patchelf ccache
```

Paired with GitHub Actions' BuildKit layer caching (`cache-from: type=gha`, `cache-to: type=gha,mode=max`), a rebuild of an unchanged codebase drops from 5–10 minutes to 30–60 seconds.

## Deploying to Kubernetes

The compiled container behaves like any other container — with a couple of settings worth tightening specifically because it's a compiled binary:

```
        resources:
          requests:
            memory: "64Mi"   # lower than the equivalent CPython container
            cpu: "100m"
          limits:
            memory: "128Mi"
            cpu: "500m"
        readinessProbe:
          httpGet: { path: /health, port: 8000 }
          initialDelaySeconds: 1   # vs 5–10s for a CPython container
          periodSeconds: 5
        securityContext:
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 1000
          allowPrivilegeEscalation: false
          capabilities: { drop: ["ALL"] }
```

The aggressive `initialDelaySeconds: 1` isn't reckless — a compiled binary is genuinely ready in milliseconds, not the 5–10 seconds a CPython container needs to import its dependency tree.

## Debugging without a shell

Distroless means no `kubectl exec`. The tools that still work:

```
# Pull the binary out of a running pod for offline inspection
kubectl cp api-pod-xxx:/app/app ./app-binary

# Logs are your primary real-time signal
kubectl logs -f deployment/api

# Ephemeral debug containers (Kubernetes 1.23+) attach a separate,
# shell-having container to the same pod
kubectl debug -it api-pod-xxx --image=busybox --target=api
```

---

The trade-off is honest: longer CI build times for a dramatically smaller, faster, and harder-to-exploit runtime image. With ccache and layer caching in place, that becomes a 30–60 second tax for shipping a 40 MB container with no exposed source and no interpreter to attack — against a 30-second build that ships 900 MB with your source code readable by anyone who can pull the image.

*If you're moving a Python service to compiled containers, [talk to us](https://thoughtparameters.com/contact) — we've built this exact CI/CD pipeline enough times to save you the trial and error.*

## Have a project in mind?

The first call is always free — tell us what you're building.

[Book a free consultation](https://thoughtparameters.com/free-consultation)

[![Thought Parameters](https://legacy.thoughtparameters.com/logos/logo-horizontal-inverted.png)](https://thoughtparameters.com/)

Where Ideas Meet Intelligent Systems.

- <https://www.linkedin.com/company/thoughtparameters>
- <https://www.facebook.com/thoughtparameters>
- <https://x.com/thoughtparams>
- <https://www.instagram.com/thoughtparametersllc/>
- <https://www.threads.com/@thoughtparametersllc>
- <https://github.com/ThoughtParameters>

Products

[Identity & Access](https://thoughtparameters.com/products/identity) [SRE Reliability](https://thoughtparameters.com/products/sre) [DORA Metrics](https://thoughtparameters.com/products/dora) [Incident & On-call](https://thoughtparameters.com/products/oncall) [ITSM & Service Desk](https://thoughtparameters.com/products/itsm) [Developer Portal](https://thoughtparameters.com/products/portal) [Secrets & Feature Flags](https://thoughtparameters.com/products/vault) [Request a demo →](https://thoughtparameters.com/platform#request-demo)

Services

[DevOps & CI/CD](https://thoughtparameters.com/services/devops-cicd) [Platform Engineering](https://thoughtparameters.com/services/platform-engineering) [SRE](https://thoughtparameters.com/services/site-reliability-engineering) [Cloud Infrastructure](https://thoughtparameters.com/services/cloud-infrastructure) [Cybersecurity](https://thoughtparameters.com/services/cybersecurity-compliance) [View all services →](https://thoughtparameters.com/services)

Company

[About](https://thoughtparameters.com/about) [Industries](https://thoughtparameters.com/industries) [How We Work](https://thoughtparameters.com/how-we-work) [Get Started](https://thoughtparameters.com/get-started) [Careers](https://thoughtparameters.com/careers) [Blog](https://thoughtparameters.com/thought-parameters-llc-blog) [News](https://thoughtparameters.com/news)

Get in touch

[1 (888) 875-1399 (toll-free)](tel:+18888751399) [Free Consultation](https://thoughtparameters.com/free-consultation) [Contact](https://thoughtparameters.com/contact) [Newsletter](https://thoughtparameters.com/newsletter) [hello@thoughtparameters.com](mailto:hello@thoughtparameters.com)

© 2026 Thought Parameters LLC. All rights reserved. Placentia, CA

```json
{
  "@context" : "https://schema.org",
  "@type" : "ProfessionalService",
  "address" : {
    "@type" : "PostalAddress",
    "addressCountry" : "US",
    "addressLocality" : "Placentia",
    "addressRegion" : "CA"
  },
  "areaServed" : "US",
  "description" : "Senior DevOps, cloud infrastructure, cybersecurity, and custom software development consulting for startups and growing engineering teams.",
  "email" : "hello@thoughtparameters.com",
  "image" : "https://legacy.thoughtparameters.com/logos/logo-horizontal-inverted.png",
  "logo" : "https://legacy.thoughtparameters.com/logos/logo-horizontal-inverted.png",
  "name" : "Thought Parameters LLC",
  "priceRange" : "$$",
  "url" : "https://thoughtparameters.com"
}
```

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Jason Miller",
    "url" : "https://thoughtparameters.com/thought-parameters-llc-blog/author/jason-miller"
  },
  "dateModified" : "2026-09-19T11:27:30.944Z",
  "datePublished" : "2026-09-19T11:27:30.000Z",
  "headline" : "Nuitka + Docker: Building Minimal, Compiled Python Containers",
  "image" : [ "https://images.unsplash.com/photo-1605745341112-85968b19335b?w=1400&q=80" ],
  "mainEntityOfPage" : {
    "@id" : "https://thoughtparameters.com/thought-parameters-llc-blog/nuitka-docker-building-minimal-compiled-python-containers",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://thoughtparameters.com/hubfs/logo-horizontal-inverted-1.png"
    }
  }
}
```