Render
Render is a unified cloud platform for deploying web services, databases, and background workers with automatic scaling and free SSL.
Why Render?
- Simple pricing: Predictable, straightforward costs
- Built-in databases: Managed PostgreSQL and Redis
- Auto-deploy: Automatic deploys from Git
- Free tier: Limited free services for testing
Architecture
┌─────────────────────────────────────────┐
│ Render Account │
│ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ Web Service │ │Background Worker│ │
│ │ (API) │ │ (Worker) │ │
│ └──────┬──────┘ └────────┬────────┘ │
│ │ │ │
│ ┌──────┴───────────────────┴──────┐ │
│ │ Private Network │ │
│ └──────┬───────────────────┬──────┘ │
│ │ │ │
│ ┌──────┴──────┐ ┌──────┴──────┐ │
│ │ PostgreSQL │ │ Redis │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────┘
Quick Start
1. Create PostgreSQL Database
- Go to render.com and sign in
- Click New > PostgreSQL
- Configure:
- Name:
boards-db - Database:
boards - User:
boards - Region: Choose closest to users
- Name:
- Click Create Database
- Copy the Internal Database URL
2. Create Redis Instance
- Click New > Redis
- Configure:
- Name:
boards-redis - Region: Same as database
- Name:
- Click Create Redis
- Copy the Internal Redis URL
3. Deploy API Service
- Click New > Web Service
- Select Deploy an existing image from a registry
- Configure:
Image Settings:
- Image URL:
ghcr.io/weirdfingers/boards-backend:latest
Service Settings:
- Name:
boards-api - Region: Same as database
- Instance Type: Starter ($7/month) or higher
Environment Variables:
BOARDS_DATABASE_URL=<internal-database-url>
BOARDS_REDIS_URL=<internal-redis-url>
BOARDS_GENERATOR_API_KEYS={"fal": "your-key", "openai": "your-key"}
BOARDS_AUTH_PROVIDER=none
BOARDS_LOG_FORMAT=json
PORT=8800
Docker Command:
uvicorn boards.api.app:app --host 0.0.0.0 --port 8800
- Click Create Web Service
4. Deploy Worker Service
- Click New > Background Worker
- Select Deploy an existing image from a registry
- Configure:
Image Settings:
- Image URL:
ghcr.io/weirdfingers/boards-backend:latest
Service Settings:
- Name:
boards-worker - Region: Same as database
- Instance Type: Starter or higher
Environment Variables:
BOARDS_DATABASE_URL=<internal-database-url>
BOARDS_REDIS_URL=<internal-redis-url>
BOARDS_GENERATOR_API_KEYS={"fal": "your-key", "openai": "your-key"}
BOARDS_INTERNAL_API_URL=http://boards-api:8800
BOARDS_LOG_FORMAT=json
Docker Command:
boards-worker --log-level info --processes 1 --threads 1
- Click Create Background Worker
Blueprint (Infrastructure as Code)
Create a render.yaml for one-click deployment:
services:
# API Service
- type: web
name: boards-api
env: docker
dockerfilePath: ./Dockerfile
dockerCommand: uvicorn boards.api.app:app --host 0.0.0.0 --port 8800
healthCheckPath: /health
envVars:
- key: BOARDS_DATABASE_URL
fromDatabase:
name: boards-db
property: connectionString
- key: BOARDS_REDIS_URL
fromService:
name: boards-redis
type: redis
property: connectionString
- key: BOARDS_GENERATOR_API_KEYS
sync: false
- key: BOARDS_AUTH_PROVIDER
value: none
- key: BOARDS_LOG_FORMAT
value: json
- key: PORT
value: 8800
# Worker Service
- type: worker
name: boards-worker
env: docker
dockerfilePath: ./Dockerfile
dockerCommand: boards-worker --log-level info --processes 1 --threads 1
envVars:
- key: BOARDS_DATABASE_URL
fromDatabase:
name: boards-db
property: connectionString
- key: BOARDS_REDIS_URL
fromService:
name: boards-redis
type: redis
property: connectionString
- key: BOARDS_GENERATOR_API_KEYS
sync: false
- key: BOARDS_INTERNAL_API_URL
fromService:
name: boards-api
type: web
property: hostport
databases:
- name: boards-db
databaseName: boards
user: boards
# Note: Redis is a paid feature, add manually if needed
Deploy with blueprint:
- Push
render.yamlto your repository - Click New > Blueprint
- Connect your repository
- Render creates all services automatically
Environment Groups
Share environment variables across services:
- Go to Environment Groups
- Create group
boards-shared - Add common variables:
BOARDS_GENERATOR_API_KEYS={"fal": "key", "openai": "key"}
BOARDS_AUTH_PROVIDER=jwt
BOARDS_JWT_SECRET=your-secret
- Link to services in their settings
Custom Domain
- Go to your API service Settings
- Under Custom Domains, click Add Custom Domain
- Enter your domain (e.g.,
api.boards.example.com) - Add the provided CNAME record to your DNS
- Render automatically provisions SSL
Private Network
Services on Render communicate via private network:
- Use internal URLs (e.g.,
boards-api:8800) - No external traffic charges
- Lower latency
Reference internal services:
BOARDS_INTERNAL_API_URL=http://boards-api:8800
Scaling
Horizontal Scaling
- Go to service Settings
- Under Scaling, adjust instance count
Vertical Scaling
- Go to service Settings
- Change Instance Type:
| Type | RAM | CPU | Monthly |
|---|---|---|---|
| Starter | 512 MB | 0.5 CPU | $7 |
| Standard | 2 GB | 1 CPU | $25 |
| Pro | 4 GB | 2 CPU | $85 |
| Pro Plus | 8 GB | 4 CPU | $175 |
Deploy Frontend
Option 1: Static Site
- Click New > Static Site
- Connect your frontend repository
- Configure:
- Build Command:
pnpm build - Publish Directory:
out(for exported Next.js)
- Build Command:
- Add environment variables:
NEXT_PUBLIC_API_URL=https://boards-api.onrender.com
NEXT_PUBLIC_GRAPHQL_URL=https://boards-api.onrender.com/graphql
Option 2: Web Service
For SSR or API routes:
- Click New > Web Service
- Connect your frontend repository
- Configure:
- Build Command:
pnpm build - Start Command:
pnpm start
- Build Command:
Disk Storage
For persistent storage (if using local storage):
- Go to service Settings
- Under Disks, click Add Disk
- Configure:
- Name:
storage - Mount Path:
/app/data/storage - Size: 10 GB (minimum)
- Name:
Monitoring
Logs
View logs in dashboard:
- Click on service
- Go to Logs tab
Or use the CLI:
render logs --service boards-api
Metrics
Render provides basic metrics:
- CPU usage
- Memory usage
- Request count
- Response times
Health Checks
Configure health checks:
- Go to service Settings
- Set Health Check Path:
/health - Render restarts unhealthy instances automatically
CI/CD
Automatic Deploys
Enable in service settings:
- Go to Settings
- Under Build & Deploy, enable Auto-Deploy
- Deploys trigger on push to connected branch
Deploy Hooks
Use webhooks for custom CI:
- Go to service Settings
- Find Deploy Hook URL
- POST to this URL to trigger deploy
Cost Estimation
| Service | Type | Monthly |
|---|---|---|
| API | Starter | $7 |
| Worker | Starter | $7 |
| PostgreSQL | Starter | $7 |
| Redis | Starter | $10 |
| Total | ~$31 |
Scale up as needed. Free tier available for static sites.
Troubleshooting
Build Failures
- Check build logs in dashboard
- Verify Dockerfile/commands are correct
- Test build locally first
Service Not Starting
- Check logs for errors
- Verify environment variables
- Check Docker command syntax
Database Connection
- Verify using internal URL
- Check database is in same region
- Test connection:
render shell boards-api
python -c "from boards.db import engine; print(engine.connect())"
Slow Cold Starts
Render spins down free/starter instances. To prevent:
- Upgrade to Standard or higher
- Use health check pings to keep warm
Next Steps
- Storage Configuration - Configure S3 for production storage
- Authentication - Set up auth providers
- Monitoring - Add external monitoring