This page covers how to migrate DevMetrics from the default free-tier stack (Railway + Vercel + Atlas + Upstash) to a full AWS deployment. It includes an architecture overview, service mapping, infrastructure setup, and the code changes required in each layer.
The current stack works fine for portfolio purposes. Choose AWS if you want to demonstrate cloud infrastructure knowledge, need more control over networking, or are targeting roles where AWS experience is evaluated.
┌─────────────────────────────────────┐
│ GitHub │
│ OAuth App + Webhooks │
└──────────┬──────────────────────────┘
│
┌──────────────▼──────────────┐
│ CloudFront CDN │
│ (React SPA, global edge) │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ S3 Bucket (static files) │
│ dist/ from Vite build │
└─────────────────────────────┘
┌─────────────────────────────┐
│ Application Load │
│ Balancer (ALB) │
└──────────────┬──────────────┘
│
┌──────────────────────┴──────────────────────┐
│ │
┌───────────▼───────────┐ ┌────────────▼──────────┐
│ ECS Fargate Service │ │ ECS Fargate Service │
│ devmetrics-api │ │ devmetrics-worker │
│ (Express, port 3001) │ │ (BullMQ worker) │
└───────────┬────────────┘ └────────────┬──────────┘
│ │
└──────────────┬──────────────────────────────┘
│ (both read/write)
┌──────────────┴──────────────────────────────┐
│ │
┌───────────▼───────────┐ ┌────────────▼──────────┐
│ MongoDB Atlas M0 │ │ ElastiCache Redis │
│ (unchanged) │ │ (replaces Upstash) │
└────────────────────────┘ └───────────────────────┘
┌─────────────────────────────────────────────┐
│ AWS Secrets Manager │
│ (stores all env vars / secrets) │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ GitHub Actions (CI/CD) │
│ builds image → pushes to ECR → deploys │
│ to ECS + invalidates CloudFront cache │
└─────────────────────────────────────────────┘
| Current | AWS Equivalent | Notes |
|---|---|---|
| Vercel | S3 + CloudFront | Static files on S3, served via CloudFront CDN |
| Railway (API) | ECS Fargate (devmetrics-api) | Containerized Express, behind ALB |
| Railway (Worker) | ECS Fargate (devmetrics-worker) | Same image, different start command |
| Upstash Redis | ElastiCache (Serverless Redis) | In-VPC, no public endpoint |
| MongoDB Atlas | MongoDB Atlas (unchanged) | Atlas runs on AWS anyway; DocumentDB is an alternative |
| GitHub Actions | GitHub Actions (updated steps) | Same CI, new deploy targets |
| .env file | AWS Secrets Manager | Secrets injected into ECS task definitions |
aws configure)Both ECS services run from the same Docker image with different start commands. Create server/Dockerfile:
FROM node:20-alpine
WORKDIR /app
# Install dependencies first (layer caching)
COPY package*.json ./
RUN npm ci --only=production
COPY src/ ./src/
# Default start command — overridden per ECS service
CMD ["node", "src/index.js"]
Create server/.dockerignore: