9.1 KiB
9.1 KiB
Keys for All - Deployment Guide
Prerequisites
- Node.js 18+ (API server)
- PostgreSQL 14+ (Database)
- Redis 7+ (Caching & rate limiting)
- Docker & Docker Compose (Optional)
- AWS Account or similar cloud provider
Local Development
1. Clone Repository
git clone https://github.com/your-org/keys-for-all.git
cd keys-for-all
2. Environment Setup
Create .env files in each component:
keys-api/.env
NODE_ENV=development
PORT=3000
DATABASE_URL=postgresql://postgres:password@localhost:5432/keysforall
REDIS_URL=redis://localhost:6379
JWT_SECRET=your-jwt-secret-here
API_KEY_SALT=your-salt-here
keys-web-components/.env
REACT_APP_API_URL=http://localhost:3000/v1
REACT_APP_PUBLIC_URL=http://localhost:3001
3. Database Setup
# Create database
createdb keysforall
# Run migrations
cd keys-api
npm run migrate
# Seed development data
npm run seed
4. Start Services
Option A: Docker Compose
docker-compose up -d
Option B: Manual
# Terminal 1: Database
postgres -D /usr/local/var/postgres
# Terminal 2: Redis
redis-server
# Terminal 3: API
cd keys-api
npm install
npm run dev
# Terminal 4: Web
cd keys-web-components
npm install
npm start
Production Deployment
AWS Infrastructure
1. RDS Database
# Create RDS instance
aws rds create-db-instance \
--db-instance-identifier keysforall-prod \
--db-instance-class db.t3.medium \
--engine postgres \
--engine-version 14.9 \
--master-username dbadmin \
--master-user-password $DB_PASSWORD \
--allocated-storage 100 \
--backup-retention-period 7 \
--multi-az
2. ElastiCache Redis
# Create Redis cluster
aws elasticache create-cache-cluster \
--cache-cluster-id keysforall-cache \
--engine redis \
--cache-node-type cache.t3.micro \
--num-cache-nodes 1
3. ECS Deployment
Dockerfile for API
FROM node:18-alpine
WORKDIR /app
# Copy package files
COPY package*.json ./
RUN npm ci --only=production
# Copy application
COPY . .
# Run migrations on start
CMD ["sh", "-c", "npm run migrate && npm start"]
EXPOSE 3000
ECS Task Definition
{
"family": "keysforall-api",
"taskRoleArn": "arn:aws:iam::xxx:role/keysforall-task-role",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"containerDefinitions": [{
"name": "api",
"image": "xxx.dkr.ecr.us-east-1.amazonaws.com/keysforall-api:latest",
"portMappings": [{
"containerPort": 3000,
"protocol": "tcp"
}],
"environment": [
{"name": "NODE_ENV", "value": "production"},
{"name": "PORT", "value": "3000"}
],
"secrets": [
{"name": "DATABASE_URL", "valueFrom": "arn:aws:secretsmanager:xxx"},
{"name": "REDIS_URL", "valueFrom": "arn:aws:secretsmanager:xxx"}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/keysforall-api",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "api"
}
}
}]
}
Kubernetes Deployment
k8s/api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: keysforall-api
spec:
replicas: 3
selector:
matchLabels:
app: keysforall-api
template:
metadata:
labels:
app: keysforall-api
spec:
containers:
- name: api
image: keysforall/api:latest
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: keysforall-secrets
key: database-url
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: keysforall-api
spec:
selector:
app: keysforall-api
ports:
- port: 80
targetPort: 3000
type: LoadBalancer
CI/CD Pipeline
GitHub Actions: .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: |
cd keys-api
npm ci
npm test
npm run lint
deploy-api:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Build and push Docker image
run: |
cd keys-api
docker build -t keysforall-api .
docker tag keysforall-api:latest $ECR_REGISTRY/keysforall-api:latest
docker push $ECR_REGISTRY/keysforall-api:latest
- name: Deploy to ECS
run: |
aws ecs update-service \
--cluster keysforall-prod \
--service keysforall-api \
--force-new-deployment
deploy-web:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build web components
run: |
cd keys-web-components
npm ci
npm run build
- name: Deploy to S3/CloudFront
run: |
aws s3 sync keys-web-components/build/ s3://keysforall-web/ --delete
aws cloudfront create-invalidation \
--distribution-id $CLOUDFRONT_ID \
--paths "/*"
Monitoring Setup
1. CloudWatch Alarms
# High error rate alarm
aws cloudwatch put-metric-alarm \
--alarm-name keysforall-high-error-rate \
--alarm-description "Alert when API error rate is high" \
--metric-name 4XXError \
--namespace AWS/ApiGateway \
--statistic Sum \
--period 300 \
--threshold 100 \
--comparison-operator GreaterThanThreshold
2. Application Monitoring
Prometheus Metrics
// keys-api/src/metrics.js
const prometheus = require('prom-client');
const httpRequestDuration = new prometheus.Histogram({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status']
});
const keyValidations = new prometheus.Counter({
name: 'key_validations_total',
help: 'Total number of key validations',
labelNames: ['result']
});
3. Grafana Dashboard
{
"dashboard": {
"title": "Keys for All Monitoring",
"panels": [
{
"title": "API Request Rate",
"targets": [{
"expr": "rate(http_requests_total[5m])"
}]
},
{
"title": "Key Validations",
"targets": [{
"expr": "sum(rate(key_validations_total[5m])) by (result)"
}]
},
{
"title": "Error Rate",
"targets": [{
"expr": "rate(http_requests_total{status=~'5..'}[5m])"
}]
}
]
}
}
Backup and Recovery
1. Automated Backups
# RDS automated backups (already enabled)
# Additional backup to S3
0 2 * * * pg_dump $DATABASE_URL | gzip | aws s3 cp - s3://keysforall-backups/db/$(date +%Y%m%d).sql.gz
2. Disaster Recovery Plan
- RTO: 1 hour (Recovery Time Objective)
- RPO: 15 minutes (Recovery Point Objective)
- Multi-region failover: Route53 health checks
- Data replication: Cross-region RDS read replicas
Security Hardening
1. SSL/TLS Configuration
server {
listen 443 ssl http2;
ssl_certificate /etc/nginx/ssl/keysforall.crt;
ssl_certificate_key /etc/nginx/ssl/keysforall.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000" always;
}
2. WAF Rules
{
"Rules": [{
"Name": "RateLimitRule",
"Priority": 1,
"Action": { "Block": {} },
"Statement": {
"RateBasedStatement": {
"Limit": 2000,
"AggregateKeyType": "IP"
}
}
}]
}
Maintenance
Regular Tasks
- Daily: Check error logs, monitor key generation rate
- Weekly: Review security alerts, update dependencies
- Monthly: Analyze usage patterns, optimize database
- Quarterly: Security audit, disaster recovery test
Scaling Considerations
- API Servers: Auto-scale based on CPU/memory
- Database: Upgrade instance class or add read replicas
- Cache: Increase Redis memory or add nodes
- CDN: Ensure static assets are cached properly
Rollback Procedure
# Quick rollback to previous version
aws ecs update-service \
--cluster keysforall-prod \
--service keysforall-api \
--task-definition keysforall-api:previous-version
# Database rollback
pg_restore -d keysforall < backup.sql
Support Contacts
- DevOps Team: devops@keysforall.com
- On-call Engineer: +1-555-KEYS-911
- Escalation: engineering-lead@keysforall.com