If you’re ready to build real-world web apps with FastAPI, you’re also prepared to deploy them correctly. This guide shows you how to deploy FastAPI Docker applications using Uvicorn. We’ll walk you through a clean, easy, and secure way to get your FastAPI project production-ready.
Let’s go step by step and keep it simple.
Why FastAPI Is a Great Choice for Your App
FastAPI is one of the fastest web frameworks for Python. It’s built on top of Starlette and Pydantic. That makes it super fast and super smart when handling data.
Here’s why many developers love it:
- Speed: It’s one of the fastest frameworks available.
- Validation: It automatically checks the data coming in and going out.
- Docs: It creates docs for your API with almost no extra work.
- Typing: It uses Python type hints, which makes your code easier to write and understand.
But building a great app isn’t the full story. You also need to deploy it. That’s where Docker and Uvicorn come in.
Why Use Docker for Deployment?
Docker helps you package your app and everything (like dependencies, settings, and libraries) into a container. A container is like a mini-computer that runs your app the same way every time—no surprises.
With Docker, you get:
- Consistency: Your app runs the same everywhere.
- Isolation: It won’t mess with your system or other apps.
- Easy Sharing: You can pass your container to someone else, and it just works.
Docker is perfect for deployment, especially when setting up a FastAPI production setup.
What’s Uvicorn and Why Do We Need It?
Uvicorn is a lightning-fast web server built for Python’s async world. It’s the server that runs your FastAPI app. Think of it like a host for your code.
Here’s why Uvicorn is the go-to server:
- It supports async code, making it fast.
- It works with ASGI, which FastAPI needs.
- It’s easy to use and plays well with Docker.
We often pair Uvicorn with Gunicorn for production, which adds process management, logging, and better reliability. More on that later.
Step-by-Step Deploy FastAPI Docker: Create a Simple FastAPI App
Let’s make a tiny FastAPI app to get things rolling.
Create a file called main.py:
python
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Welcome to your FastAPI app!"}
That’s it. One route that sends back a friendly message.
Set Up Your Requirements
Next, you need to list all your app’s needs. Create a file called requirements.txt:
css
fastapi
uvicorn[standard]
This tells Docker what to install when setting up your app. You can add more later as your app grows.
Create a Production Dockerfile
Let’s create a Dockerfile to tell Docker how to build your container.
Dockerfile
# Use an official Python base image
FROM python:3.11-slim
# Set the working directory
WORKDIR /app
# Copy the requirements
COPY requirements.txt .
# Install Python packages
RUN pip install --no-cache-dir -r requirements.txt
# Copy your FastAPI app
COPY . .
# Run the app with Uvicorn
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Let’s break this down:
- We use a small Python image to keep it lightweight.
- We copy the code and install the packages.
- We run Uvicorn to serve the app.
This Dockerfile is clean, simple, and perfect for testing or small apps. But we can make it stronger for production.
Best Practice: Use Gunicorn + Uvicorn for Production
In production, we often use Gunicorn as a process manager. It helps handle multiple requests at once and restarts the app if it crashes.
Here’s how to update your Dockerfile for production:
Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt \
&& pip install gunicorn "uvicorn[standard]"
COPY . .
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker",
"main:app", "-b", "0.0.0.0:8000", "--workers", "4"]
This setup:
- Uses Gunicorn as the main process.
- Uses UvicornWorker to run FastAPI.
- Starts 4 worker processes to handle more traffic.
That’s a smart, production-ready FastAPI with Uvicorn setup.
Build and Run Your Docker Container
Now it’s time to see it all work.
Open your terminal and run:
bash
docker build -t fastapi-app .
This builds the Docker image. Next, run it:
bash
docker run -d -p 8000:8000 fastapi-app
Your app is now running at http://localhost:8000!
When you visit that page, you should see:
json
{
"message": "Welcome to your FastAPI app!"
}
That’s the power of Docker and FastAPI—working together smoothly.
Add a .dockerignore File
Like .gitignore, this file tells Docker what to skip when copying files. Create a .dockerignore:
markdown
__pycache__/
*.pyc
*.pyo
.env
.git
This helps keep your Docker image clean and small.
Add Environment Variables
You’ll want to keep secrets like API keys or DB passwords safe for real projects. Never hard-code them.
Instead, use environment variables.
Update your Dockerfile to load them if needed, or pass them when you run:
bash
docker run -d -p 8000:8000 -e "MY_SECRET_KEY=abc123" fastapi-app
Inside your code, grab them like this:
python
import os
secret_key = os.getenv("MY_SECRET_KEY")
This keeps your app secure and flexible.
Using Docker Compose (Optional, but Handy!)
If your app grows and needs a database (like Postgres or Redis), use Docker Compose. It helps you run multiple containers easily.
Example docker-compose.yml:
yaml
version: '3.8'
services:
web: build: .
ports:
- "8000:8000"
environment:
- MY_SECRET_KEY=abc123
Start it up with:
bash
docker-compose up --build
Docker Compose is a great tool when your app gets bigger.
Wrap-Up: Your FastAPI App Is Now Production-Ready
You’ve come a long way—from writing a FastAPI app to deploying it securely and reliably using Docker and Uvicorn. You created a requirements.txt file along the journey, wrote a clean Dockerfile, and even leveled up your deployment with Gunicorn for better performance.
Adding smart practices like environment variables and a .dockerignore file sets the stage for a solid and scalable setup. Whether you’re building a personal project, launching a startup, or creating tools for clients, this production-ready workflow has you covered.