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
-
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)
-
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-userUbuntu:
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 -
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 -
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.confserver { 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
-
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 -
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" } } }] } -
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: LoadBalancerCreate 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
- Production Deployment Guide - General production deployment
- Security Best Practices - Security configuration
- Troubleshooting Guide - Common issues
- Installation Guide - Initial setup
Last Updated: 2025-01-27