TempsTemps
  • Docs
  • Blog
  • Roadmap
  • Pricing
  • Enterprise
  • Security
  • Contact
Star—
TempsTemps

Open-source deployment platform with built-in error tracking, analytics, and monitoring. Runs on any VPS. No surprise bills, no data leaving your infrastructure.

  • Product
  • Features
  • AI Agents
  • Error Tracking
  • Observability
  • Analytics
  • Documentation
  • Changelog
  • Enterprise
  • Contact
  • Resources
  • Getting Started
  • Upgrade
  • GitHub
  • Reddit
  • Tools
  • VPS Security Scanner
  • PaaS Tax Calculator
  • Compare
  • vs Vercel
  • vs Netlify
  • vs Coolify
  • All Platforms
  • Deploy
  • Next.js
  • Node.js
  • Django
  • Laravel
  • Go
  • Rust
  • All Frameworks →
  • Legal & Compliance
  • Security & Trust
  • Data Ownership & Privacy
  • GDPR Compliance

© 2026 Temps. All rights reserved.

GitHubDocs
Back to all posts

Deploy FastAPI to Production: The Easy Way with Temps

Complete guide to deploying FastAPI applications with Temps. Zero-config Python deployment with automatic Dockerfile generation.

Temps Team

Temps Team

January 30, 2026 · 6mo ago

Free guide

Zero-Downtime Deployment Playbook

The deployment checklist used by teams shipping 10+ times per day without dropping a single request.

  • Blue-green vs rolling vs canary — when to use each
  • Health check configuration that actually catches failures
  • Preview environment setup for every PR
  • Automated rollback triggers and procedures

No spam. Unsubscribe anytime. Privacy policy

#fastapi#python#deployment#tutorial#api
Back to all posts

Deploying FastAPI to production without a dedicated DevOps team means juggling Docker, Nginx, SSL certificates, and monitoring tools that rarely work together cleanly. Temps collapses that stack into a single Rust binary you control — git-push to deploy, automatic HTTPS via Pingora (Cloudflare's open-source proxy), built-in error tracking, and request analytics, all for ~$6/mo on Temps Cloud or free to self-host.

TL;DR: bunx @temps-sdk/cli deploy my-api -b main -e production -y — your FastAPI app is live with HTTPS and monitoring in under 5 minutes. Temps is Apache 2.0, self-hostable for free, or ~$6/mo on Temps Cloud (Hetzner cost + 30%, no per-seat fees).


How Do I Deploy FastAPI to Production Without DevOps?

The fastest path: push your code to a git repository, connect it to Temps, and run one CLI command. Temps detects Python projects, generates an optimized Dockerfile, builds the container, provisions a Let's Encrypt certificate, and starts routing traffic — all without you touching Nginx or Docker config.


What You'll Get

After this tutorial, your FastAPI app will have:

  • Production deployment with automatic HTTPS (Let's Encrypt via Pingora proxy)
  • Zero-config Python detection — Temps generates an optimized Dockerfile automatically
  • Encrypted environment variable management — variables injected at runtime, never in images
  • Built-in error tracking — exception capture with stack traces, no Sentry subscription needed
  • Request analytics — latency, error rates, geographic distribution in your dashboard
  • Auto-rollback — health checks every 5 seconds, 2 consecutive failures trigger rollback within 60 seconds

Prerequisites

  • A FastAPI application
  • Git repository (GitHub, GitLab, or Bitbucket)
  • Python 3.9+ project with requirements.txt or pyproject.toml

Project Structure

Temps works with any FastAPI project layout. Here's a minimal example:

my-fastapi-app/
├── main.py           # or app/main.py
├── requirements.txt  # or pyproject.toml
└── .env             # optional, for local development only

main.py:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello from FastAPI on Temps"}

@app.get("/health")
def health_check():
    return {"status": "healthy"}

requirements.txt:

fastapi>=0.109.0
uvicorn[standard]>=0.27.0

Deploy FastAPI with the Temps CLI

Step 1: Install Temps CLI

# macOS / Linux
curl -fsSL https://temps.sh/install.sh | bash

Step 2: Login and Create Project

bunx @temps-sdk/cli login

# Create project and connect your git repository
bunx @temps-sdk/cli projects create \
  -n "My FastAPI App" \
  -d "FastAPI application" \
  --repo your-org/your-fastapi-app \
  --branch main \
  --preset python

Temps automatically detects Python projects. Use --preset docker if you already have a Dockerfile.

Step 3: Deploy

bunx @temps-sdk/cli deploy my-fastapi-app -b main -e production -y

Temps will:

  1. Detect your FastAPI application
  2. Generate an optimized Dockerfile (unless you supply one)
  3. Build your container
  4. Deploy to production
  5. Provision an SSL certificate via Let's Encrypt

Your app is live at your-app.temps.sh within minutes.


Free guide

Zero-Downtime Deployment Playbook

The deployment checklist used by teams shipping 10+ times per day without dropping a single request.

  • Blue-green vs rolling vs canary — when to use each
  • Health check configuration that actually catches failures
  • Preview environment setup for every PR
  • Automated rollback triggers and procedures

No spam. Unsubscribe anytime. Privacy policy

Automatic Dockerfile Generation

You don't need Docker knowledge. Temps generates an optimized Dockerfile for your Python project:

Generated Dockerfile:

FROM python:3.11-slim

WORKDIR /app

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

# Copy application
COPY . .

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

If you have a custom Dockerfile, Temps uses that instead.


Configuring Your FastAPI App

Entry Point Detection

Temps detects your FastAPI app through your project files. Common entry point patterns it handles:

  1. main.py with app = FastAPI()
  2. app/main.py with app = FastAPI()
  3. src/main.py with app = FastAPI()

Custom Configuration

For custom resource limits or replica counts:

# Set CPU/memory limits and replica count
bunx @temps-sdk/cli projects config -p my-fastapi-app \
  --cpu-limit 1 \
  --memory-limit 512 \
  --replicas 2 \
  -y

Environment Variables

Adding Variables

# Single variable
bunx @temps-sdk/cli environments vars set DATABASE_URL "postgresql://..." -e production
bunx @temps-sdk/cli environments vars set OPENAI_API_KEY "sk-..." -e production

# Import from file
bunx @temps-sdk/cli environments vars import .env.production -e production

# List all (values hidden by default)
bunx @temps-sdk/cli environments vars list -e production

Accessing in FastAPI

import os
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    database_url: str
    openai_api_key: str
    debug: bool = False

settings = Settings()

Environment variables are encrypted at rest and injected at runtime — they never appear in your Docker image layers.


Database Connections

PostgreSQL

Add your database URL as an environment variable:

bunx @temps-sdk/cli environments vars set DATABASE_URL "postgresql://user:pass@host:5432/db" -e production

Use with SQLAlchemy or asyncpg:

from sqlalchemy.ext.asyncio import create_async_engine
import os

DATABASE_URL = os.getenv("DATABASE_URL")
engine = create_async_engine(DATABASE_URL)

Redis

bunx @temps-sdk/cli environments vars set REDIS_URL "redis://host:6379" -e production
import redis
import os

r = redis.from_url(os.getenv("REDIS_URL"))

MongoDB

bunx @temps-sdk/cli environments vars set MONGODB_URI "mongodb://user:pass@host:27017/db" -e production
from motor.motor_asyncio import AsyncIOMotorClient
import os

client = AsyncIOMotorClient(os.getenv("MONGODB_URI"))

Built-in Monitoring

After deployment, your Temps dashboard includes monitoring with no extra subscriptions:

Request Analytics

  • Request count and latency percentiles (p50, p95, p99)
  • Endpoint breakdown with per-route timing
  • Error rates by route
  • Geographic distribution of traffic

Error Tracking

  • Exception capture with full stack traces
  • Request context (headers, user, environment)
  • Error grouping and trend analysis

No Sentry, no Datadog, no additional setup. It's built into the same binary that runs your proxy.


Free guide

Zero-Downtime Deployment Playbook

The deployment checklist used by teams shipping 10+ times per day without dropping a single request.

  • Blue-green vs rolling vs canary — when to use each
  • Health check configuration that actually catches failures
  • Preview environment setup for every PR
  • Automated rollback triggers and procedures

No spam. Unsubscribe anytime. Privacy policy

API Documentation

FastAPI's automatic documentation works out of the box on Temps:

  • Swagger UI: https://your-app.temps.sh/docs
  • ReDoc: https://your-app.temps.sh/redoc

To restrict access in production:

from fastapi import FastAPI
import os

app = FastAPI(
    docs_url="/docs" if os.getenv("ENABLE_DOCS") else None,
    redoc_url="/redoc" if os.getenv("ENABLE_DOCS") else None,
)

Production Best Practices

Health Checks

Temps polls your health endpoint every 5 seconds. Two consecutive failures within the 60-second error window trigger automatic rollback to the last healthy deployment. Always expose a /health route:

@app.get("/health")
async def health():
    # Optionally check DB connectivity here
    return {"status": "healthy"}

CORS Configuration

from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://yourfrontend.com"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

Structured Logging

import logging
import json

class JSONFormatter(logging.Formatter):
    def format(self, record):
        return json.dumps({
            "timestamp": self.formatTime(record),
            "level": record.levelname,
            "message": record.getMessage(),
            "module": record.module,
        })

handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
logging.getLogger().addHandler(handler)

Temps aggregates container stdout/stderr logs in your dashboard, searchable and streamable via bunx @temps-sdk/cli runtime-logs -p my-fastapi-app -f.


Scaling Your Application

Horizontal Scaling

Scale to multiple replicas:

bunx @temps-sdk/cli environments scale -e production -r 3

Temps handles load balancing automatically via Pingora, Cloudflare's open-source Rust proxy.

Update Resource Allocation

bunx @temps-sdk/cli projects config -p my-fastapi-app \
  --cpu-limit 2 \
  --memory-limit 1024 \
  -y
bunx @temps-sdk/cli deploy my-fastapi-app -b main -e production -y

Custom Domains

DNS Configuration

Add an A record pointing to your Temps server IP:

TypeNameValue
AapiYOUR_SERVER_IP

Adding Your Domain

# HTTP-01 challenge (default, works for most domains)
bunx @temps-sdk/cli domains add -d api.yourdomain.com

# DNS-01 challenge (required for wildcard domains)
bunx @temps-sdk/cli domains add -d "*.yourdomain.com" --challenge dns-01

With --challenge dns-01, the CLI outputs a TXT record to add. Once DNS propagates, Temps completes ACME validation automatically. Let's Encrypt certificates are provisioned and renewed without manual intervention.


Comparing FastAPI Deployment Options

Temps vs Manual Docker + VPS

AspectTempsDocker + VPS manually
Setup time~5 minutes1–2 hours
Docker knowledgeNot requiredRequired
SSL setupAutomatic (Let's Encrypt)Manual (Certbot + Nginx config)
Reverse proxyPingora (built-in)Nginx or Caddy (manual config)
Error trackingBuilt-inSentry (~$26/mo Developer plan)
Request analyticsBuilt-inPrometheus + Grafana (manual)
Cost~$6/mo cloud or free self-hostVPS cost only, higher ops time

Temps vs Railway

AspectTempsRailway
Python detectionAutomatic (Dockerfile generated)Automatic (Nixpacks)
Pricing model~$6/mo flat (no per-seat fees)See Railway pricing page
Error trackingBuilt-inNot included
Self-host optionYes (Apache 2.0, free)No
Vendor lock-inNone — runs on any Linux serverProprietary platform
Health checksEvery 5s, auto-rollback in 60sHealth check support

Temps vs AWS Lambda (for FastAPI via Mangum)

AspectTempsLambda + API Gateway
Cold startsNone (persistent containers)100–500ms depending on runtime
Request timeoutUnlimited29s (API GW limit)
ComplexityLow — single binaryHigh — IAM, layers, API GW
Cost at scalePredictable flat ratePer-request variable billing
WebSocket/SSENative (Starlette)Requires separate tooling

Common FastAPI Patterns

Background Tasks

from fastapi import BackgroundTasks

@app.post("/send-email")
async def send_email(
    email: str,
    background_tasks: BackgroundTasks
):
    background_tasks.add_task(send_email_task, email)
    return {"message": "Email queued"}

Dependency Injection

from fastapi import Depends

async def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.get("/users")
async def get_users(db: Session = Depends(get_db)):
    return db.query(User).all()

Middleware

import time

@app.middleware("http")
async def add_timing(request, call_next):
    start = time.time()
    response = await call_next(request)
    response.headers["X-Process-Time"] = str(time.time() - start)
    return response

Troubleshooting

Build Fails

Check build logs in the Temps dashboard or stream them via CLI:

bunx @temps-sdk/cli deploy my-fastapi-app -b main -e production

Common issues:

  • Missing packages in requirements.txt
  • Python version mismatch (specify FROM python:3.11-slim in a custom Dockerfile)
  • Syntax errors caught at build time

App Crashes on Start

# Stream live logs
bunx @temps-sdk/cli runtime-logs -p my-fastapi-app -f
  1. Check that all required environment variables are set
  2. Confirm the app binds to 0.0.0.0:8000 (not 127.0.0.1)
  3. Test locally with the same env vars using pydantic-settings

Health Check Failures

Temps checks /health every 5 seconds. If your endpoint takes more than 2 seconds to respond under normal load, add a lightweight health check that bypasses slow database queries:

@app.get("/health")
async def health():
    return {"status": "ok"}  # Keep it fast and dependency-free

Free guide

Zero-Downtime Deployment Playbook

The deployment checklist used by teams shipping 10+ times per day without dropping a single request.

  • Blue-green vs rolling vs canary — when to use each
  • Health check configuration that actually catches failures
  • Preview environment setup for every PR
  • Automated rollback triggers and procedures

No spam. Unsubscribe anytime. Privacy policy

Quick Reference

# Install CLI
curl -fsSL https://temps.sh/install.sh | bash

# Login
bunx @temps-sdk/cli login

# Create project and connect repo
bunx @temps-sdk/cli projects create \
  -n "My FastAPI API" \
  -d "FastAPI application" \
  --repo myorg/my-fastapi-app \
  --branch main \
  --preset python

# Deploy
bunx @temps-sdk/cli deploy my-fastapi-api -b main -e production -y

# Stream logs
bunx @temps-sdk/cli runtime-logs -p my-fastapi-api -f

# Set environment variable
bunx @temps-sdk/cli environments vars set SECRET_KEY "value" -e production

# Scale replicas
bunx @temps-sdk/cli environments scale -e production -r 3

# Add domain (HTTP-01 by default, DNS-01 for wildcards)
bunx @temps-sdk/cli domains add -d api.example.com

Ready to deploy your FastAPI app? Get started at temps.sh — self-host for free (Apache 2.0) or use Temps Cloud at ~$6/mo with no per-seat fees:

curl -fsSL https://temps.sh/install.sh | bash && bunx @temps-sdk/cli login