Deployment
Production Environment Checklist
Before deploying to production, ensure you've configured all critical settings properly. Missing or incorrect configuration can lead to security vulnerabilities or broken functionality.
Critical Security Settings
Required - Security Risk if Skipped
These settings are critical for security. Never deploy without configuring them.
- SECRET_KEY ⚠️ MUST CHANGE
- Generate a new secret key:
openssl rand -hex 32 - Never use the default or example value
- Keep this secret - don't commit to version control
-
Used for JWT token signing and session security
-
CORS_ORIGINS
- For browser clients, set to your actual frontend domain(s)
- For public APIs using Bearer tokens,
*is acceptable but will log a warning - Example:
CORS_ORIGINS=https://app.example.com,https://www.example.com - Multiple origins separated by commas
Database Configuration
- DB_USER, DB_PASSWORD, DB_NAME - Must match your production database
- DB_ADDRESS, DB_PORT - Point to your production database server
- Database must exist - Create it before running migrations
- Run migrations -
api-admin db init --force(see Database Migration Strategy below) - Consider using connection pooling for better performance
- Enable SSL/TLS for database connections if available
Email Settings (Required for Password Reset)
Email Required in Production
Password reset and verification emails won't work without proper email configuration.
- MAIL_USERNAME, MAIL_PASSWORD - SMTP credentials
- MAIL_FROM - Sender email address (e.g.,
[email protected]) - MAIL_SERVER, MAIL_PORT - SMTP server details (usually port 587 for TLS)
- MAIL_FROM_NAME - Friendly sender name
- Test email functionality before going live
Admin Panel Configuration
- ADMIN_PAGES_ENABLED - Set to
Trueif using admin panel - ADMIN_PAGES_ENCRYPTION_KEY - Generate with:
python -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())' - Leave empty to auto-generate (regenerates on each restart - sessions lost)
- Set explicitly for persistent sessions across restarts
- ADMIN_PAGES_TIMEOUT - Session timeout in seconds (default: 86400 = 24 hours)
Observability & Monitoring
- METRICS_ENABLED - Set to
truefor production monitoring - Enables
/metricsendpoint for Prometheus scraping - Essential for tracking performance and errors
- See Metrics Documentation
- Configure your monitoring system to scrape
/metrics - Set up health check monitoring on
/heartbeat
Logging Configuration
- LOG_LEVEL - Set to
INFOorWARNINGin production (notDEBUG) - LOG_PATH - Ensure path exists and is writable
- LOG_ROTATION - Consider
1 dayor500 MBfor production - LOG_RETENTION - Balance between disk space and audit requirements
- LOG_COMPRESSION - Use
ziporgzto save disk space - LOG_CATEGORIES - Recommend
ERRORS,AUTH,DATABASE,REQUESTSfor production
Optional Settings
- BASE_URL - Your production API URL (e.g.,
https://api.example.com) - FRONTEND_URL - If using custom frontend for password reset
- API_ROOT - If serving API from subpath (e.g.,
/api/v1) - ACCESS_TOKEN_EXPIRE_MINUTES - Default 120 (2 hours), adjust as needed
Pre-Deployment Verification
Before going live, verify:
- [ ] SECRET_KEY is unique and secure
- [ ] Database is accessible and migrated
- [ ] Email sending works (test password reset)
- [ ] CORS is configured for your frontend domain(s)
- [ ] Admin panel accessible (if enabled)
- [ ] Metrics endpoint returns data (if enabled)
- [ ] Logs are being written correctly
- [ ] At least one admin user exists
- [ ] SSL/TLS certificate is valid
- [ ] Health check endpoint (
/heartbeat) responding - [ ] All external dependencies (database, SMTP) are accessible
Deploying to Production
There are quite a few ways to deploy a FastAPI app to production. There is a very good discussion about this on the FastAPI Deployment Guide which covers using Uvicorn, Gunicorn and Containers.
Environment Setup
Whichever method you choose, you still need to set up a virtual environment, install all the dependencies, setup your .env file (or use Environment variables if your hosting provider uses these - for example Railway or Heroku) and set up and migrate your Database.
Database Migration Strategy
Proper database migration management is crucial for production deployments.
Initial Deployment
-
Create the database on your production server:
psql -U postgres CREATE DATABASE your_production_db; -
Run migrations to create tables:
api-admin db init --force -
Create your first admin user:
api-admin user create --admin
Updating an Existing Deployment
When deploying code changes that include new migrations:
Critical - Do NOT use 'db init' on existing databases
Never run api-admin db init --force on an existing production database - it will clear all data! Use api-admin db upgrade instead.
-
Backup your database first (critical!):
pg_dump -U postgres your_production_db > backup_$(date +%Y%m%d_%H%M%S).sql -
Test migrations locally on a copy of production data if possible
-
Put application in maintenance mode (if zero-downtime is not required)
-
Pull latest code and install dependencies:
git pull origin main uv sync # or pip install -r requirements.txt -
Run migrations (applies new migrations only):
api-admin db upgrade -
Restart the application
-
Verify the application is working correctly
Rollback Procedure
If a migration fails or causes issues:
-
Restore from backup:
psql -U postgres your_production_db < backup_YYYYMMDD_HHMMSS.sql -
Revert to previous code version:
git checkout <previous-commit> uv sync -
Restart the application
Best Practices
- Always backup before running migrations
- Test migrations on a staging environment first
- Review migration files generated by Alembic before deployment
- Plan for rollback - have a tested rollback procedure ready
- Monitor logs during and after migration
- Consider scheduled maintenance windows for complex migrations
Managed Platform Options
These platforms offer straightforward FastAPI deployment with managed infrastructure:
- Railway - Simple deploys from GitHub, generous free tier, automatic HTTPS
- Fly.io - Edge deployment, global distribution, Dockerfile-based
- Render - Auto-deploy from Git, managed PostgreSQL, free tier available
- DigitalOcean App Platform - Managed platform with databases and scaling
- Heroku - Classic PaaS, easy deployment, many add-ons available
- Vercel - Serverless deployment, edge functions (requires ASGI adapter)
All support PostgreSQL databases and environment variables. Refer to their documentation for FastAPI-specific deployment instructions.
Self-Hosted Deployment
Nginx
My Personal preference is to serve with Gunicorn, using uvicorn workers behind an Nginx proxy, though this does require you having your own server. There is a pretty decent tutorial on this at Vultr.
AWS Lambda
For deploying to AWS Lambda with API Gateway, there is a really excellent Medium post (and it's followup) Here
AWS Elastic Beanstalk
For AWS Elastic Beanstalk there is a very comprehensive tutorial at testdriven.io
Docker Container
Deploy a Docker container or Kubernetes cluster. There are many services which allow this including AWS, Google Cloud and more. See Develop with Docker in this documentation for how to containerize this project, and the Offical FastAPI docs section for more information.