Deploy to Render
Render provides an easy way to deploy Bunty applications with automatic HTTPS, deployments from Git, and managed databases.
Quick Deploy
1. Connect Repository
- Sign up at render.com
- Click βNew +β β βWeb Serviceβ
- Connect your Git repository (GitHub/GitLab)
2. Configure Service
# render.yaml
services:
- type: web
name: bunty-app
env: docker
region: oregon
plan: starter
branch: main
dockerfilePath: ./Dockerfile
envVars:
- key: NODE_ENV
value: production
- key: PORT
value: 3000
- key: DATABASE_URL
fromDatabase:
name: bunty-db
property: connectionString
- key: REDIS_URL
fromService:
name: bunty-redis
type: redis
property: connectionString
healthCheckPath: /health
autoDeploy: true
databases:
- name: bunty-db
databaseName: bunty
user: bunty
region: oregon
plan: starter
- name: bunty-redis
type: redis
plan: starter
maxmemoryPolicy: allkeys-lru
3. Deploy
Push to your main branch - Render will automatically:
- Build your Docker image
- Deploy the application
- Provision SSL certificate
- Assign a URL:
https://your-app.onrender.com
Using Dockerfile
Create Dockerfile
FROM oven/bun:1-alpine
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile --production
COPY . .
EXPOSE 3000
CMD ["bun", "run", "src/main.ts"]
Using Native Environment
If you prefer not to use Docker:
# render.yaml
services:
- type: web
name: bunty-app
env: node
buildCommand: curl -fsSL https://bun.sh/install | bash && bun install
startCommand: bun run src/main.ts
envVars:
- key: NODE_ENV
value: production
Environment Variables
Via Dashboard
- Go to your service
- Environment β Add Environment Variable
- Set key-value pairs
Via render.yaml
envVars:
- key: NODE_ENV
value: production
- key: JWT_SECRET
generateValue: true
- key: DATABASE_URL
fromDatabase:
name: bunty-db
property: connectionString
- key: API_KEY
sync: false # Secret value, set manually
Secret Files
envVars:
- key: SECRET_FILE
fromFile: ./secrets/key.pem
Database Setup
PostgreSQL
databases:
- name: bunty-db
databaseName: bunty
user: bunty
region: oregon
plan: starter # or standard, pro
services:
- type: web
name: bunty-app
envVars:
- key: DATABASE_URL
fromDatabase:
name: bunty-db
property: connectionString
Access in your app:
import { DatabaseModule } from '@bunty/orm';
@Module({
imports: [
DatabaseModule.forRoot({
url: process.env.DATABASE_URL,
ssl: true,
}),
],
})
export class AppModule {}
Redis
databases:
- name: bunty-redis
type: redis
plan: starter
maxmemoryPolicy: allkeys-lru
region: oregon
services:
- type: web
name: bunty-app
envVars:
- key: REDIS_URL
fromService:
name: bunty-redis
type: redis
property: connectionString
Background Workers
services:
- type: web
name: bunty-api
dockerfilePath: ./Dockerfile
- type: worker
name: bunty-worker
env: docker
dockerfilePath: ./Dockerfile
dockerCommand: bun run src/worker.ts
envVars:
- key: REDIS_URL
fromService:
name: bunty-redis
type: redis
property: connectionString
Cron Jobs
services:
- type: cron
name: bunty-cleanup
env: docker
schedule: "0 0 * * *" # Daily at midnight
dockerfilePath: ./Dockerfile
dockerCommand: bun run src/cleanup.ts
Custom Domains
Add Custom Domain
- Go to Settings β Custom Domain
- Add your domain:
api.example.com - Add DNS records (Render will show you which ones)
CNAME api.example.com -> your-app.onrender.com
- Render automatically provisions SSL certificate
Via render.yaml
services:
- type: web
name: bunty-app
customDomains:
- api.example.com
- www.api.example.com
Health Checks
services:
- type: web
name: bunty-app
healthCheckPath: /health
Implement in your app:
import { Controller, Get } from '@bunty/http';
@Controller()
export class HealthController {
@Get('/health')
health() {
return { status: 'ok', timestamp: new Date().toISOString() };
}
}
Auto-Deploy
Enable Auto-Deploy
services:
- type: web
autoDeploy: true
branch: main
Deploy Hooks
Get webhook URL from Render dashboard to trigger deploys:
curl -X POST https://api.render.com/deploy/srv-xxx?key=yyy
Build Configuration
Custom Build Command
services:
- type: web
buildCommand: bun install && bun run build
startCommand: bun run start:prod
Build Environment Variables
services:
- type: web
buildCommand: bun run build
envVars:
- key: BUILD_ENV
value: production
preDeployCommand: bun run migrate
Scaling
Via Dashboard
- Go to Settings β Scaling
- Select plan (Starter, Standard, Pro, Pro Plus)
- Adjust instance count
Via render.yaml
services:
- type: web
name: bunty-app
plan: standard # starter, standard, pro, pro_plus
numInstances: 3
scaling:
minInstances: 2
maxInstances: 10
targetMemoryPercent: 80
targetCPUPercent: 70
Disk Storage
Persistent Disks
services:
- type: web
name: bunty-app
disk:
name: uploads
mountPath: /app/uploads
sizeGB: 10
Use in your app:
import { writeFile } from 'fs/promises';
import { join } from 'path';
const uploadPath = join(process.cwd(), 'uploads', filename);
await writeFile(uploadPath, buffer);
Monitoring & Logs
View Logs
# Via Render CLI
render logs --service bunty-app --tail
# Via dashboard
# Go to Logs tab
Metrics
Render provides built-in metrics:
- CPU usage
- Memory usage
- Response times
- Request count
- Bandwidth
Alerts
Configure in Settings β Notifications:
- Email alerts
- Slack notifications
- Discord webhooks
Private Services
services:
- type: web
name: bunty-internal
plan: starter
publish: false # Not publicly accessible
Access from other services:
const response = await fetch('http://bunty-internal:3000/api');
Blue-Green Deployments
Render automatically does zero-downtime deployments:
- Builds new version
- Starts new instances
- Health checks pass
- Routes traffic to new instances
- Terminates old instances
Regions
Available regions:
oregon(US West)ohio(US East)frankfurt(Europe)singapore(Asia)
services:
- type: web
region: frankfurt
Cost Optimization
Tips
- Use appropriate plan sizes
- Enable auto-scaling
- Use background workers for heavy tasks
- Implement caching
- Use CDN for static assets
Pricing Tiers
- Starter: $7/month (512MB RAM)
- Standard: $25/month (2GB RAM)
- Pro: $85/month (4GB RAM)
- Pro Plus: $250/month (8GB RAM)
CI/CD Integration
GitHub Actions
# .github/workflows/deploy.yml
name: Deploy to Render
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Trigger Render Deploy
run: |
curl -X POST ${{ secrets.RENDER_DEPLOY_HOOK }}
Troubleshooting
Build Fails
# Check build logs in dashboard
# Common issues:
# - Missing dependencies
# - Build command errors
# - Memory limits
Health Check Fails
// Ensure health endpoint responds quickly
@Get('/health')
health() {
return { status: 'ok' };
}
Database Connection Issues
// Ensure SSL is enabled for Render databases
{
ssl: {
rejectUnauthorized: false
}
}
Example render.yaml (Full)
services:
# Main API
- type: web
name: bunty-api
env: docker
plan: standard
region: oregon
branch: main
dockerfilePath: ./Dockerfile
healthCheckPath: /health
autoDeploy: true
numInstances: 2
envVars:
- key: NODE_ENV
value: production
- key: DATABASE_URL
fromDatabase:
name: bunty-db
property: connectionString
- key: REDIS_URL
fromService:
name: bunty-redis
type: redis
property: connectionString
- key: JWT_SECRET
generateValue: true
customDomains:
- api.example.com
# Background Worker
- type: worker
name: bunty-worker
env: docker
plan: starter
dockerfilePath: ./Dockerfile
dockerCommand: bun run src/worker.ts
autoDeploy: true
envVars:
- key: REDIS_URL
fromService:
name: bunty-redis
type: redis
property: connectionString
# Cron Job
- type: cron
name: bunty-cleanup
schedule: "0 2 * * *"
env: docker
dockerfilePath: ./Dockerfile
dockerCommand: bun run src/cleanup.ts
databases:
- name: bunty-db
databaseName: bunty
plan: starter
region: oregon
- name: bunty-redis
type: redis
plan: starter
maxmemoryPolicy: allkeys-lru
Next Steps
- Set up monitoring
- Configure CI/CD
- Add caching strategies
- Implement rate limiting