Skip to main content
← Back to articles
python

Deploying FastAPI on Ubuntu with systemd, Nginx, and Docker | redesign.ir

October 30, 202515 min read

From local app to hardened Ubuntu deployment: Docker image, Gunicorn/Uvicorn, Nginx reverse proxy with TLS, systemd units, environment secrets, blue-green updates, and rollback.

Deploying FastAPI on Ubuntu with systemd, Nginx, and Docker

Estimated reading time: 15 min · Published Oct 31, 2025

This is a hardened deploy path for a modern FastAPI service: one Docker image, Gunicorn/Uvicorn workers, Nginx TLS termination, and systemd supervision with blue-green rollouts and instant rollback.

1) Project Layout

.
app/
├── main.py
├── requirements.txt
├── gunicorn_conf.py
└── Dockerfile
      

2) App Entry


# main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/health")
def health():
    return {"ok": True}
      

3) Gunicorn/Uvicorn Config


# gunicorn_conf.py
bind = "0.0.0.0:8000"
workers = 2
worker_class = "uvicorn.workers.UvicornWorker"
accesslog = "-"
errorlog = "-"
timeout = 30
graceful_timeout = 30
      

4) Dockerfile (multi-stage)


# syntax=docker/dockerfile:1
FROM python:3.12-slim AS base
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

FROM base AS runtime
COPY . .
EXPOSE 8000
CMD ["gunicorn", "-c", "gunicorn_conf.py", "main:app"]
      

5) Build & Run


docker build -t redesign/fastapi:1.0.0 .
docker run -d --name fastapi -p 8000:8000 redesign/fastapi:1.0.0
      

6) Nginx Reverse Proxy (+ TLS)


# /etc/nginx/sites-available/fastapi.conf
server {
  listen 80;
  server_name api.example.com;
  location / {
    proxy_pass http://127.0.0.1:8000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_read_timeout 65;
  }
}
      

Enable site, then add TLS via certbot --nginx -d api.example.com.

7) systemd Service (supervision & restart)


# /etc/systemd/system/fastapi.service
[Unit]
Description=FastAPI container
After=docker.service
Requires=docker.service

[Service]
Restart=always
ExecStart=/usr/bin/docker run --rm --name fastapi -p 8000:8000 \
  --env-file /etc/fastapi.env redesign/fastapi:1.0.0
ExecStop=/usr/bin/docker stop fastapi

[Install]
WantedBy=multi-user.target
      

Then sudo systemctl enable --now fastapi.

8) Blue-Green Deploys


docker pull redesign/fastapi:1.1.0
docker run -d --name fastapi-blue -p 8001:8000 --env-file /etc/fastapi.env redesign/fastapi:1.1.0
# Switch Nginx upstream to 127.0.0.1:8001, reload Nginx, drain old container, stop it.
      

9) Health Checks & Logs

  • Expose /health and /metrics (Prometheus) for probes.
  • Log to stdout; let the platform (journald/Loki) handle storage and rotation.
  • Set readiness delays to avoid cold-start spikes post-deploy.

10) Secrets & Config

  • Use --env-file or Docker secrets; never bake secrets into images.
  • Prefer short-lived tokens; rotate via systemd reload and rolling restart.

11) Rollback


# Switch Nginx back to the previous upstream (green),
# stop the faulty version, and pin the tag.
docker stop fastapi-blue
docker tag redesign/fastapi:1.0.0 redesign/fastapi:stable
      
“Ship thin. Observe deeply. Roll forward with grace.” — redesign.ir
Tip: Keep stable and next tags for human-friendly rollouts; protect latest from accidental use in production.
Warning: Don’t bind Docker to 0.0.0.0 on public hosts without Nginx/TLS in front—exposes your app to the internet unfiltered.

Keywords: fastapi deploy, ubuntu, nginx, docker, systemd

Tags: deployment, devops, python, fastapi

Meta description: Deploy a FastAPI service on Ubuntu using Docker, Nginx, and systemd with HTTPS and safe rollouts.

© 2025 redesign.ir · Crafted by SCRIBE/CORE · “Illuminate through information.”

Topics
#python#deploying#fastapi#ubuntu#systemd#nginx#docker#redesign

Share this article

Help others discover it across your favourite communities.

Comments

Join the discussion. We keep comments private to your device until moderation tooling ships.

0 comments