Skip to Content
APSO is 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