Skip to Content
🚀 APSO is now in public beta. Get started →
GuidesDeploymentOverview

Deployment

APSO backends can be deployed anywhere that runs Node.js, Python, or Go. Choose the deployment option that fits your infrastructure.

Deployment Options

Comparison

FeatureAPSO CloudSelf-Hosted
Setup timeMinutesHours
MaintenanceManagedYour team
ScalingAutomaticManual/Config
CostUsage-basedInfrastructure
ControlLimitedFull
ComplianceStandardCustom

Pre-Deployment Checklist

1. Environment Configuration

# Required variables DATABASE_URL=postgresql://... JWT_SECRET=your-production-secret NODE_ENV=production # Optional PORT=3001 LOG_LEVEL=info

2. Database Migration

# Run migrations npm run migration:run # Or for production NODE_ENV=production npm run migration:run

3. Build Verification

# Build the application npm run build # Test the build locally npm start

4. Security Review

  • Environment variables configured
  • JWT secrets rotated
  • Database credentials secured
  • CORS settings reviewed
  • Rate limiting enabled
  • HTTPS configured

Quick Deploy

APSO Cloud

# Login to APSO Cloud apso login # Deploy apso deploy

Docker

# Build image docker build -t my-api . # Run container docker run -p 3001:3001 --env-file .env.production my-api

Railway

# Install Railway CLI npm install -g @railway/cli # Login and deploy railway login railway init railway up

Render

# render.yaml services: - type: web name: my-api env: node buildCommand: npm install && npm run build startCommand: npm start envVars: - key: NODE_ENV value: production - key: DATABASE_URL fromDatabase: name: my-db property: connectionString

Fly.io

# Install Fly CLI curl -L https://fly.io/install.sh | sh # Launch fly launch # Deploy fly deploy

Production Optimizations

Node.js

// Enable cluster mode import cluster from 'cluster'; import { cpus } from 'os'; if (cluster.isPrimary) { const numCPUs = cpus().length; for (let i = 0; i < numCPUs; i++) { cluster.fork(); } } else { bootstrap(); }

Database Connection Pooling

// TypeORM configuration { type: 'postgres', url: process.env.DATABASE_URL, extra: { max: 20, // Maximum connections idleTimeoutMillis: 30000, connectionTimeoutMillis: 2000, }, }

Caching

// Enable response caching app.use(cacheControl({ maxAge: 60, public: true, }));

Health Checks

// src/health/health.controller.ts @Controller('health') export class HealthController { @Get() check() { return { status: 'ok', timestamp: new Date().toISOString() }; } @Get('ready') async ready() { // Check database connection await this.dataSource.query('SELECT 1'); return { status: 'ready' }; } }

Logging

// Production logging configuration import { WinstonModule } from 'nest-winston'; import * as winston from 'winston'; WinstonModule.forRoot({ transports: [ new winston.transports.Console({ format: winston.format.combine( winston.format.timestamp(), winston.format.json(), ), }), ], });

Monitoring

  • Application: Sentry, New Relic, DataDog
  • Infrastructure: Prometheus, Grafana
  • Logs: Loki, CloudWatch, Papertrail

Basic Metrics

// Track response times app.use((req, res, next) => { const start = Date.now(); res.on('finish', () => { const duration = Date.now() - start; console.log(`${req.method} ${req.url} ${res.statusCode} ${duration}ms`); }); next(); });
Last updated on