Guide for deploying the backend to Fly.io and optionally deploying the frontend.
- Fly.io account (Sign up)
- Fly CLI installed (Install guide)
- Fly.io auth token (run
fly auth login)
# Create backend app
fly apps create <your-backend-app> --org your-org-name
# Create PostgreSQL database
fly postgres create --name <your-database-app> --region <region>
# Recommended regions: sjc (San Jose), ord (Chicago), lax (Los Angeles)
# See: https://fly.io/docs/reference/regions/cd backend
fly postgres attach <your-database-app> --app <your-backend-app>This automatically sets the DATABASE_URL secret.
# Generate encryption key
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
# Set secrets
fly secrets set ENCRYPTION_KEY="<generated-key>" --app <your-backend-app>
fly secrets set OPENROUTER_API_KEY="sk-or-v1-..." --app <your-backend-app>
fly secrets set PUBLIC_URL="https://<your-backend-app>.fly.dev" --app <your-backend-app>Optional (for MCP server deployments):
fly secrets set FLY_API_TOKEN="<your-fly-token>" --app <your-backend-app>
fly secrets set FLY_MCP_APP_NAME="<your-mcp-app>" --app <your-backend-app>
fly secrets set FLY_MCP_IMAGE="registry.fly.io/<your-backend-app>:mcp-host" --app <your-backend-app>Edit backend/fly.toml:
app = '<your-backend-app>'
primary_region = '<your-region>' # e.g., 'sjc', 'ord', 'lax'
# Rest of file stays the samecd backend
fly deploy --app <your-backend-app>First deployment runs database migrations automatically via release_command.
# Check health
curl https://<your-backend-app>.fly.dev/api/health
# View logs
fly logs --app <your-backend-app>
# Check status
fly status --app <your-backend-app>-
Connect to GitHub:
- Go to Vercel
- Import your fork of
zenchantlive/catwalk - Select the
frontenddirectory as root
-
Configure Environment:
- Set
NEXT_PUBLIC_API_URLto your backend URL:NEXT_PUBLIC_API_URL=https://<your-backend-app>.fly.dev/api/:path*
- Set
-
Deploy: Vercel auto-deploys on every push to
main
-
Create frontend app:
cd frontend fly apps create <your-frontend-app>
-
Create
Dockerfile(Nextjs on Fly.io) -
Deploy:
fly deploy --app <your-frontend-app>
Just run bun run dev locally and configure .env.local:
NEXT_PUBLIC_API_URL=https://<your-backend-app>.fly.dev/api/:path*
Error: psycopg.OperationalError: connection failed
Fix:
# Check database status
fly status --app <your-database-app>
# View database logs
fly logs --app <your-database-app>
# Verify DATABASE_URL is set
fly secrets list --app <your-backend-app>
# If missing, manually attach
fly postgres attach <your-database-app> --app <your-backend-app>Error: App keeps restarting, health checks fail
Debug:
# View logs
fly logs --app <your-backend-app>
# Common causes:
# 1. Database migrations failing (check DATABASE_URL)
# 2. Missing secrets (ENCRYPTION_KEY, OPENROUTER_API_KEY)
# 3. Wrong port (must be 8080)
# 4. Import errors (missing dependencies in requirements.txt)Fix:
# SSH into container to debug
fly ssh console --app <your-backend-app>
# Inside container, check:
python -c "import app.main" # Should not errorError: Error: no active leader found
This means your Postgres cluster is broken. The only fix is to recreate it:
# 1. Destroy broken database
fly apps destroy <your-database-app>
# 2. Create fresh database
fly postgres create --name <your-database-app> --region <region>
# 3. Re-attach to backend
fly postgres attach <your-database-app> --app <your-backend-app>
# 4. Redeploy backend (runs migrations)
fly deploy --app <your-backend-app>Error: ModuleNotFoundError: No module named 'xyz'
Fix:
- Add package to
backend/requirements.txt - Redeploy:
fly deploy --app <your-backend-app>
Error: Docker build fails during fly deploy
Debug locally:
cd backend
docker build -t catwalk-backend .If build succeeds locally, try:
fly deploy --no-cache --app <your-backend-app># Scale to 1GB RAM, dedicated CPU
fly scale vm dedicated-cpu-1x --app <your-backend-app>
# Scale to 2GB RAM
fly scale memory 2048 --app <your-backend-app># Run 2 instances (auto load-balanced)
fly scale count 2 --app <your-backend-app># Upgrade to larger database
fly postgres create --name <new-db-app> --vm-size dedicated-cpu-2x
# Migrate data (see Fly.io docs)Estimated monthly costs (as of 2025):
| Component | Configuration | Cost |
|---|---|---|
| Backend | 512MB RAM, shared CPU, always-on | ~$5/month |
| Database | 256MB RAM, single-node | ~$3/month |
| Frontend (Vercel) | Hobby plan | Free |
| MCP deployments | Per machine, hourly billing | ~$0.02/hour each |
See: Fly.io Pricing
-
Rotate secrets regularly:
fly secrets set ENCRYPTION_KEY="<new-key>" --app <your-backend-app>
-
Use internal networking:
- Fly apps can communicate via
<app-name>.internal(no public internet)
- Fly apps can communicate via
-
Enable SSL/TLS:
- Fly.io provides free SSL certificates automatically
-
Monitor logs:
fly logs --app <your-backend-app> | grep ERROR
-
Set up alerts: Use Fly.io monitoring or external services (Sentry, etc.)
# Fly.io auto-backups Postgres daily
# Manual backup
fly postgres db backup <your-database-app>
# Restore from backup (see Fly.io docs)# List previous releases
fly releases --app <your-backend-app>
# Rollback to specific version
fly releases rollback <version> --app <your-backend-app>- Set up monitoring (Sentry, Datadog, etc.)
- Configure custom domain (Fly.io supports this)
- Enable auto-scaling based on traffic
- Set up staging environment
Need help? Open an issue on GitHub!