Skip to content

Deploying to AWS with ECS

Procella can be self-hosted on AWS using ECS (Elastic Container Service) for the API server and PostgreSQL database, with static assets served via S3 and CloudFront. This approach is production-ready and significantly cheaper than managed alternatives.

Key Components:

  • API Server: ECS Fargate containers (2-10 replicas, auto-scaling on CPU > 70%)
  • Database: PostgreSQL on ECS with EFS for persistent storage
  • Static Assets: React SPA + Astro docs served via S3 + CloudFront
  • Load Balancing: Application Load Balancer with automatic health checks
  • Networking: VPC with public/private subnets, security groups, NAT Gateway
┌─────────────────────────────────────────────────────────┐
│ CloudFront CDN │
│ ├─ procella.procella.dev (React UI, 1-year cache) │
│ └─ docs.procella.dev (Astro docs, 1-hour cache) │
└──────────────────────┬──────────────────────────────────┘
│ HTTPS
┌──────────────────────┴──────────────────────────────────┐
│ ALB (Application Load Balancer) │
│ ├─ Health check: /healthz every 5s │
│ └─ Targets: ECS Procella server (port 9090) │
└──────────────────────┬──────────────────────────────────┘
│ Port 9090
┌──────────────────────┴──────────────────────────────────┐
│ ECS Cluster (procella) │
│ ├─ Procella Service (2-10 replicas) │
│ │ ├─ 0.5 vCPU, 1GB RAM per replica │
│ │ └─ Auto-scales on CPU > 70% │
│ │ │
│ └─ PostgreSQL Service (1 replica, always-on) │
│ ├─ 0.5 vCPU, 1GB RAM │
│ └─ Data stored on EFS volume │
└──────────────────────┬──────────────────────────────────┘
│ S3 buckets
┌──────────────────────┴──────────────────────────────────┐
│ S3 + EFS │
│ ├─ Static Assets: React build (versioned, long TTL) │
│ ├─ Checkpoint Blobs: Pulumi state snapshots │
│ └─ EFS Volume: PostgreSQL data (30GB typical) │
└─────────────────────────────────────────────────────────┘
ComponentCostDetails
ECS Fargate (Server)$40-802-10 replicas, auto-scaling
ECS Fargate (Database)$20-401 dedicated replica
EFS Storage~$930GB @ $0.30/GB/month
S3 + CloudFront$25-30Static assets + egress
ALB$15-20Load balancer + processing
Total~$150Scales with traffic

Compared to alternatives:

  • RDS PostgreSQL: $1,800+/month (managed database)
  • Pulumi Cloud: $10-500+/month (hosted service)
  • Procella on ECS: ~$150/month (self-hosted)

Before deploying, you need:

  • Permissions for EC2, ECS, S3, CloudFront, Route53, Secrets Manager, CloudWatch, IAM, EFS, ALB
  • Default VPC or ability to create new VPC
  • Domain name (e.g., procella.dev)
  • Access to Route53 or external domain registrar
  • Subdomains will be auto-configured:
    • procella.procella.dev — Web UI
    • api.procella.dev — API server
    • docs.procella.dev — Documentation
  • Descope account and project
  • Project ID from dashboard
  • Management API key for token creation
Terminal window
# Bun runtime
curl -fsSL https://bun.sh/install | bash
# AWS CLI (configured with credentials)
brew install awscli # or use your package manager
aws configure
# Git
git --version
Terminal window
git clone https://github.com/procella-dev/procella.git
cd procella
# Create environment file with Descope credentials
cp .env.example .env
# Edit .env with your Descope Project ID and Management Key
Terminal window
# Preview changes (optional but recommended)
bun run infra:deploy --dry-run
# Deploy to AWS
bun run infra:deploy

This takes 5-10 minutes. Once complete, your infrastructure is running.

Terminal window
# Health check
curl https://api.procella.dev/healthz
# Should return: HTTP 200 OK
# Access web UI
open https://procella.procella.dev
# Access documentation
open https://docs.procella.dev

For step-by-step instructions, environment variable details, troubleshooting, and operational runbooks, see the complete DEPLOYMENT.md guide.

Key sections in the detailed guide:

  • Environment variables and configuration
  • Step-by-step deployment with AWS CLI examples
  • DNS configuration for Route53 or external registrars
  • Database initialization
  • Deployment verification
  • Cost optimization
  • Updating and rollback procedures
  • Comprehensive troubleshooting
  • Monitoring and scaling

Instead of using RDS (AWS’s managed relational database), Procella can use PostgreSQL on ECS with EFS storage:

  • Pros: Cheap, full control, portable, no vendor lock-in
  • Cons: Requires some ops work, manual backups
  • Best for: Self-hosted projects, cost-conscious teams
  • Pros: Automatic backups, high availability, AWS support
  • Cons: Expensive, less control, vendor lock-in
  • Best for: Enterprise deployments, compliance requirements

For most self-hosted deployments, ECS + EFS is the right choice.

The Procella API server automatically scales based on demand:

  • Min replicas: 2 (always running)
  • Max replicas: 10 (under extreme load)
  • Scale-out trigger: CPU > 70% (adds replicas after 300s)
  • Scale-in trigger: CPU < 20% (removes replicas after 300s)

No manual configuration needed—scaling happens automatically.

Monitor your deployment via CloudWatch:

Terminal window
# Stream application logs
aws logs tail /ecs/procella-server --follow
# Stream database logs
aws logs tail /ecs/procella-db --follow
# View ECS service status
aws ecs describe-services --cluster procella --services procella-server

Logs are retained for 7 days. Increase retention in sst.config.ts if needed.

Push to main branch—GitHub Actions automatically:

  1. Builds Docker image
  2. Pushes to ECR
  3. Updates ECS service
  4. Waits for health checks

Edit sst.config.ts and redeploy:

Terminal window
git add sst.config.ts
git commit -m "config: add new resource"
git push
bun run infra:deploy

If something goes wrong, rollback to the previous version:

Terminal window
# Get previous task definition
aws ecs describe-task-definition --task-definition procella-server:N
# Update service to use it
aws ecs update-service \
--cluster procella \
--service procella-server \
--task-definition procella-server:N-1

Create EFS snapshots:

Terminal window
# Manual snapshot
aws ec2 create-snapshot \
--volume-id <efs-id> \
--description "Procella DB backup"

Or use AWS Backup for automated daily snapshots.

S3 buckets have versioning enabled:

Terminal window
# List object versions
aws s3api list-object-versions \
--bucket procella-checkpoints-xxx
# Restore old version
aws s3api get-object \
--bucket procella-checkpoints-xxx \
--key state.json \
--version-id <version-id> \
state.json
  1. Full Deployment Guide — Complete step-by-step instructions
  2. Configuration Reference — All PROCELLA_* variables
  3. Architecture Overview — How Procella works internally
  4. Pulumi CLI — Using Procella with pulumi up