Deploy to Azure
Deploy FastSvelte using Azure's modern container and serverless services. This guide covers the essential Azure resources you'll need.
What You'll Use
- Azure Container Apps - Run your FastAPI backend container
- PostgreSQL Flexible Server - Managed PostgreSQL database
- Azure Static Web Apps - Host your SvelteKit frontend and landing page
- Azure Container Registry - Store your Docker images (built-in)
Prerequisites
- Azure account with active subscription
- Azure CLI installed (install guide)
- Docker installed locally
- Your FastSvelte codebase ready
Cost Estimate
For a small production app: - Container Apps: ~$15-30/month - PostgreSQL Flexible Server: ~$50-100/month (can use Neon for ~$20/month instead) - Static Web Apps: Free tier available, ~$10/month for standard - Container Registry: ~$5/month
Total: ~$70-145/month (or ~$50/month with Neon for database)
Architecture
Internet
↓
Azure Front Door (optional CDN)
↓
Static Web Apps (Frontend) → Container Apps (Backend) → PostgreSQL
Deployment Steps
1. Login to Azure
2. Create Resource Group
# Create resource group in your preferred region
az group create \
--name fastsvelte-prod-rg \
--location eastus
3. Create PostgreSQL Database
# Create PostgreSQL Flexible Server
az postgres flexible-server create \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-db \
--location eastus \
--admin-user fsadmin \
--admin-password <STRONG-PASSWORD> \
--sku-name Standard_B1ms \
--storage-size 32 \
--version 16
# Allow Azure services to connect
az postgres flexible-server firewall-rule create \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-db \
--rule-name AllowAzureServices \
--start-ip-address 0.0.0.0 \
--end-ip-address 0.0.0.0
# Create database
az postgres flexible-server db create \
--resource-group fastsvelte-prod-rg \
--server-name fastsvelte-prod-db \
--database-name fastsvelte
Alternative: Use Neon or Supabase for a more affordable managed Postgres option.
4. Run Database Migrations
cd db
# Add production database URL to .env
echo 'DATABASE_URL_PROD="postgres://fsadmin:<PASSWORD>@fastsvelte-prod-db.postgres.database.azure.com/fastsvelte?sslmode=require"' >> .env
# Deploy migrations
./sqitch.sh prod deploy
# Verify
./sqitch.sh prod status
5. Create Admin User
cd ../backend
# Create production admin account
python scripts/create_admin.py \
--env prod \
--password <ADMIN-PASSWORD> \
--domain yourdomain.com
6. Create Container Registry
# Create Azure Container Registry
az acr create \
--resource-group fastsvelte-prod-rg \
--name faststvelteregistry \
--sku Basic \
--admin-enabled true
# Get registry credentials
az acr credential show --name faststvelteregistry
7. Build and Push Backend Container
# Login to registry
az acr login --name faststvelteregistry
# Build and push backend image
cd backend
docker build -t faststvelteregistry.azurecr.io/fastsvelte-api:latest .
docker push faststvelteregistry.azurecr.io/fastsvelte-api:latest
8. Create Container Apps Environment
# Create Container Apps Environment
az containerapp env create \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-env \
--location eastus
9. Deploy Backend API
# Get registry credentials
REGISTRY_USERNAME=$(az acr credential show --name faststvelteregistry --query username -o tsv)
REGISTRY_PASSWORD=$(az acr credential show --name faststvelteregistry --query passwords[0].value -o tsv)
# Create Container App
az containerapp create \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-api \
--environment fastsvelte-prod-env \
--image faststvelteregistry.azurecr.io/fastsvelte-api:latest \
--target-port 3100 \
--ingress external \
--min-replicas 1 \
--max-replicas 5 \
--cpu 1.0 \
--memory 2Gi \
--registry-server faststvelteregistry.azurecr.io \
--registry-username $REGISTRY_USERNAME \
--registry-password $REGISTRY_PASSWORD
10. Configure Environment Variables
# Set environment variables for the API
az containerapp update \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-api \
--set-env-vars \
FS_ENVIRONMENT=prod \
FS_DB_URL="postgres://fsadmin:<PASSWORD>@fastsvelte-prod-db.postgres.database.azure.com/fastsvelte?sslmode=require" \
FS_JWT_SECRET_KEY="<RANDOM-SECRET-KEY>" \
FS_BASE_API_URL="https://<YOUR-CONTAINER-APP-URL>" \
FS_BASE_WEB_URL="https://app.yourdomain.com" \
FS_CORS_ORIGINS="https://app.yourdomain.com,https://yourdomain.com" \
FS_STRIPE_API_KEY="<YOUR-STRIPE-KEY>" \
FS_STRIPE_WEBHOOK_SECRET="<YOUR-STRIPE-WEBHOOK-SECRET>" \
FS_SENDGRID_API_KEY="<YOUR-SENDGRID-KEY>"
Get your Container App URL:
az containerapp show \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-api \
--query properties.configuration.ingress.fqdn \
--output tsv
11. Deploy Frontend to Static Web Apps
# Create Static Web App for frontend
az staticwebapp create \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-app \
--location eastus \
--source https://github.com/yourusername/your-fastsvelte-fork \
--branch main \
--app-location "frontend" \
--output-location "build" \
--login-with-github
This will: 1. Connect to your GitHub repository 2. Set up GitHub Actions for automatic deployments 3. Build and deploy your frontend
Configure environment variables in Azure Portal:
1. Go to Static Web App → Configuration
2. Add application settings:
- PUBLIC_API_BASE_URL: Your Container App URL
- PUBLIC_APP_NAME: Your app name
12. Deploy Landing Page
# Create Static Web App for landing
az staticwebapp create \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-landing \
--location eastus \
--source https://github.com/yourusername/your-fastsvelte-fork \
--branch main \
--app-location "landing" \
--output-location "build" \
--login-with-github
Custom Domains (Optional)
For Container App (API)
az containerapp hostname bind \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-api \
--hostname api.yourdomain.com
For Static Web Apps
az staticwebapp hostname set \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-app \
--hostname app.yourdomain.com
Scaling Configuration
Container Apps auto-scale based on HTTP requests by default. Configure custom scaling:
az containerapp update \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-api \
--min-replicas 2 \
--max-replicas 10 \
--scale-rule-name "http-scale" \
--scale-rule-type "http" \
--scale-rule-metadata "concurrentRequests=50"
Monitoring & Logs
View Container App logs:
# Stream live logs
az containerapp logs show \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-api \
--follow
# Recent logs
az containerapp logs show \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-api \
--tail 100
Updating Your Application
Update Backend
# Build new image
cd backend
docker build -t faststvelteregistry.azurecr.io/fastsvelte-api:v2 .
docker push faststvelteregistry.azurecr.io/fastsvelte-api:v2
# Update Container App
az containerapp update \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-api \
--image faststvelteregistry.azurecr.io/fastsvelte-api:v2
Update Frontend
Frontend updates automatically via GitHub Actions when you push to your repository.
Security Best Practices
-
Use Azure Key Vault for secrets instead of environment variables:
-
Enable managed identity for Container Apps to access Key Vault
-
Restrict database access to only Container Apps IP range
-
Enable Azure Front Door for DDoS protection and CDN
-
Set up Azure Monitor for alerts on errors and performance
Troubleshooting
Container App won't start:
# Check logs
az containerapp logs show \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-api \
--follow
Database connection issues:
- Verify firewall rules allow Container Apps
- Check connection string format
- Ensure SSL mode is set to require
Static Web App build fails:
- Check GitHub Actions logs in your repository
- Verify app-location and output-location paths
- Ensure Node.js version compatibility
Cost Optimization Tips
- Use Neon/Supabase for database - Save ~$30-80/month compared to Azure PostgreSQL
- Start with 1 replica - Scale up only when needed
- Use consumption-based Container Apps - Pay only for actual usage
- Combine frontend and landing - Host both on same Static Web App if possible
- Use Azure Reservations - Save up to 38% with 1-year commitment for predictable workloads
Next Steps
- Set up monitoring and alerts
- Configure backups for database
- Set up CI/CD pipeline for automated deployments
- Configure custom domains
- Set up Azure Front Door for CDN
Useful Commands
# View all resources
az resource list --resource-group fastsvelte-prod-rg --output table
# Get Container App URL
az containerapp show \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-api \
--query properties.configuration.ingress.fqdn
# Scale Container App
az containerapp update \
--resource-group fastsvelte-prod-rg \
--name fastsvelte-prod-api \
--min-replicas 2 \
--max-replicas 10
# Delete everything (careful!)
az group delete --name fastsvelte-prod-rg