AWS Deployment

AWS Deployment Guide

Deploy SelfHostedDB on Amazon Web Services

This guide covers deploying SelfHostedDB on AWS using EC2, ECS, or EKS.


Option 1: AWS EC2 with Docker

Best for: Simple deployments, single instance

Steps

  1. Launch EC2 Instance

    • Use Amazon Linux 2 or Ubuntu 22.04 LTS
    • Instance type: t3.small or larger (2 vCPU, 2GB RAM minimum)
    • Security group: Allow inbound on port 3001 (or 80/443 with reverse proxy)
  2. Install Docker on EC2

    Amazon Linux 2:

    sudo yum update -y
    sudo yum install docker -y
    sudo systemctl start docker
    sudo systemctl enable docker
    sudo usermod -aG docker ec2-user

    Ubuntu:

    sudo apt-get update
    sudo apt-get install docker.io docker-compose -y
    sudo systemctl start docker
    sudo systemctl enable docker
    sudo usermod -aG docker ubuntu
  3. Deploy Application

    # Clone or pull Docker image
    docker pull your-registry/selfhosteddb:latest
     
    # Create .env file
    cat > .env << EOF
    DATABASE_URL=postgres://user:pass@your-rds-endpoint:5432/dbname?sslmode=require
    AUTH_USER=admin
    AUTH_PASS=your-strong-password-here
    PORT=3001
    NODE_ENV=production
    EOF
     
    # Run container
    docker run -d \
      --name selfhosteddb \
      --restart unless-stopped \
      -p 3001:3001 \
      --env-file .env \
      your-registry/selfhosteddb:latest
  4. Set Up Reverse Proxy (Optional but Recommended)

    # Install nginx
    sudo yum install nginx -y  # or apt-get for Ubuntu
     
    # Configure nginx
    sudo nano /etc/nginx/conf.d/selfhosteddb.conf
    server {
        listen 80;
        server_name your-domain.com;
        
        location / {
            proxy_pass http://localhost:3001;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
    # Install Certbot for HTTPS
    sudo yum install certbot python3-certbot-nginx -y
    sudo certbot --nginx -d your-domain.com

Database Options

  • AWS RDS PostgreSQL: Use RDS endpoint in DATABASE_URL
  • Self-hosted on EC2: Run PostgreSQL container alongside app
  • External: Point to existing PostgreSQL instance

Security Group Rules

  • Inbound: Port 3001 (or 80/443) from your IP or load balancer
  • Outbound: Port 5432 to RDS security group (if using RDS)

Option 2: AWS ECS (Elastic Container Service)

Best for: Scalable deployments, multiple instances

Steps

  1. Push Image to ECR

    # Create ECR repository
    aws ecr create-repository --repository-name selfhosteddb
     
    # Login to ECR
    aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com
     
    # Tag and push
    docker tag selfhosteddb:latest <account-id>.dkr.ecr.us-east-1.amazonaws.com/selfhosteddb:latest
    docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/selfhosteddb:latest
  2. Create Task Definition

    {
      "family": "selfhosteddb",
      "networkMode": "awsvpc",
      "requiresCompatibilities": ["FARGATE"],
      "cpu": "512",
      "memory": "1024",
      "containerDefinitions": [{
        "name": "selfhosteddb",
        "image": "<account-id>.dkr.ecr.us-east-1.amazonaws.com/selfhosteddb:latest",
        "portMappings": [{
          "containerPort": 3001,
          "protocol": "tcp"
        }],
        "environment": [
          {"name": "NODE_ENV", "value": "production"},
          {"name": "PORT", "value": "3001"}
        ],
        "secrets": [
          {
            "name": "DATABASE_URL",
            "valueFrom": "arn:aws:secretsmanager:us-east-1:<account-id>:secret:selfhosteddb/db-url"
          },
          {
            "name": "AUTH_USER",
            "valueFrom": "arn:aws:secretsmanager:us-east-1:<account-id>:secret:selfhosteddb/auth-user"
          },
          {
            "name": "AUTH_PASS",
            "valueFrom": "arn:aws:secretsmanager:us-east-1:<account-id>:secret:selfhosteddb/auth-pass"
          }
        ],
        "logConfiguration": {
          "logDriver": "awslogs",
          "options": {
            "awslogs-group": "/ecs/selfhosteddb",
            "awslogs-region": "us-east-1",
            "awslogs-stream-prefix": "ecs"
          }
        }
      }]
    }
  3. Create ECS Service

    • Use Application Load Balancer (ALB) for HTTPS
    • Configure health checks: /api/health
    • Set desired count: 2+ for high availability

Best Practices

  • Use AWS Secrets Manager for credentials (not environment variables)
  • Enable CloudWatch Logs for monitoring
  • Use ALB with SSL certificate (ACM) for HTTPS
  • Configure auto-scaling based on CPU/memory

Option 3: AWS EKS (Kubernetes)

Best for: Enterprise deployments, complex orchestration needs

Kubernetes Deployment YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: selfhosteddb
spec:
  replicas: 2
  selector:
    matchLabels:
      app: selfhosteddb
  template:
    metadata:
      labels:
        app: selfhosteddb
    spec:
      containers:
      - name: selfhosteddb
        image: <account-id>.dkr.ecr.us-east-1.amazonaws.com/selfhosteddb:latest
        ports:
        - containerPort: 3001
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: selfhosteddb-secrets
              key: database-url
        - name: AUTH_USER
          valueFrom:
            secretKeyRef:
              name: selfhosteddb-secrets
              key: auth-user
        - name: AUTH_PASS
          valueFrom:
            secretKeyRef:
              name: selfhosteddb-secrets
              key: auth-pass
        - name: NODE_ENV
          value: "production"
        - name: PORT
          value: "3001"
        livenessProbe:
          httpGet:
            path: /api/health
            port: 3001
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /api/health
            port: 3001
          initialDelaySeconds: 10
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: selfhosteddb-service
spec:
  selector:
    app: selfhosteddb
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3001
  type: LoadBalancer

Create Secrets

kubectl create secret generic selfhosteddb-secrets \
  --from-literal=database-url='postgres://...' \
  --from-literal=auth-user='admin' \
  --from-literal=auth-pass='your-password'

Monitoring

CloudWatch

  • Logs: Configured automatically with ECS/EKS
  • Metrics: CPU, memory, network usage
  • Alarms: Set up for high CPU, memory, or error rates

Health Checks

Use /api/health endpoint for:

  • ECS target group health checks
  • EKS liveness/readiness probes
  • CloudWatch alarms

Cost Optimization

  • EC2: Use Reserved Instances for long-term deployments
  • ECS: Use Fargate Spot for non-critical workloads
  • EKS: Use managed node groups with auto-scaling
  • RDS: Use Reserved Instances for database

Security Best Practices

  • Use AWS Secrets Manager for all credentials
  • Enable VPC for network isolation
  • Use security groups to restrict access
  • Enable RDS encryption at rest
  • Use SSL/TLS for all database connections

Related Documentation


Last Updated: 2025-01-27