Back to Blog
Backend
July 7, 2026
5 min read

Guide to structuring efficient microservices with FastAPI and Docker

Tomás Ledesma
Tomás Ledesma
Founder & Software Architect
Guide to structuring efficient microservices with FastAPI and Docker

FastAPI has become the go-to framework for building high-performance APIs and microservices in Python due to its speed and native support for asynchronous operations. However, when taking these services to production, containerizing them properly with Docker is crucial.

An oversized container not only slows down deployment in environments like Kubernetes or AWS ECS, but also increases the attack surface and storage costs.

The Problem with Heavy Docker Images

A standard Python base image (python:3.11) can easily exceed 1 GB once all dependencies are installed. This is unsustainable in efficient microservices architectures. The solution is to use multi-stage builds and lightweight base images such as Alpine or "slim" versions.

Optimized Dockerfile for FastAPI

Want to optimize your technology?

We design and build bespoke AI automation pipelines and cloud architectures.

Here is a secure, production-ready Dockerfile configuration structured in two stages to separate compilation tools from the final runtime environment:

dockerfile
# Stage 1: Build & Dependencies
FROM python:3.11-slim AS builder

WORKDIR /app

RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

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

# Stage 2: Final lightweight image
FROM python:3.11-slim AS runner

WORKDIR /app

# Copy dependencies installed in builder stage
COPY --from=builder /root/.local /root/.local
COPY . .

ENV PATH=/root/.local/bin:$PATH
ENV PYTHONUNBUFFERED=1

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Additional Best Practices

  • Do not run as root: For security, create a non-privileged user within the container to execute the application.
  • Use .dockerignore: Avoid copying local development files like .git, __pycache__, or virtual environments (.venv).
  • Pin versions: Always lock package versions in your requirements.txt to prevent unexpected failures when rebuilding the image.

Related Articles

Frontend

Why Zustand is the best alternative to Redux in React

We compare Zustand against Redux Toolkit for state management in React, analyzing simplicity, performance, and the massive reduction of boilerplate.

Read post
Automatización & IA

How to build autonomous AI Agents with LangGraph and Python

Discover how to move beyond simple LLM API calls to persistent stateful multi-agent systems capable of self-correcting using LangGraph.

Read post
Tomás Ledesma
Written by

Tomás Ledesma

Tomás Ledesma is a software architect and technical consultant specializing in intelligent process automation, scalable cloud architectures, and cross-platform app engineering.