lfg9-forums/DEPLOYMENT.md
Developer 097d5c4109 init
2025-09-02 14:05:42 -05:00

11 KiB

Deployment Guide

Complete deployment guide for the LFG9 Forums application.

AWS Infrastructure Setup

1. DynamoDB Tables

Create the following DynamoDB tables:

Users Table

aws dynamodb create-table \
  --table-name lfg9_forums_users \
  --attribute-definitions \
    AttributeName=userId,AttributeType=S \
  --key-schema \
    AttributeName=userId,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST

Categories Table

aws dynamodb create-table \
  --table-name lfg9_forums_categories \
  --attribute-definitions \
    AttributeName=categoryId,AttributeType=S \
  --key-schema \
    AttributeName=categoryId,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST

Threads Table

aws dynamodb create-table \
  --table-name lfg9_forums_threads \
  --attribute-definitions \
    AttributeName=threadId,AttributeType=S \
    AttributeName=categoryId,AttributeType=S \
    AttributeName=authorId,AttributeType=S \
  --key-schema \
    AttributeName=threadId,KeyType=HASH \
  --global-secondary-indexes \
    IndexName=CategoryIdIndex,KeySchema=[{AttributeName=categoryId,KeyType=HASH}],Projection={ProjectionType=ALL} \
    IndexName=AuthorIdIndex,KeySchema=[{AttributeName=authorId,KeyType=HASH}],Projection={ProjectionType=ALL} \
  --billing-mode PAY_PER_REQUEST

Posts Table

aws dynamodb create-table \
  --table-name lfg9_forums_posts \
  --attribute-definitions \
    AttributeName=postId,AttributeType=S \
    AttributeName=threadId,AttributeType=S \
    AttributeName=authorId,AttributeType=S \
  --key-schema \
    AttributeName=postId,KeyType=HASH \
  --global-secondary-indexes \
    IndexName=ThreadIdIndex,KeySchema=[{AttributeName=threadId,KeyType=HASH}],Projection={ProjectionType=ALL} \
    IndexName=AuthorIdIndex,KeySchema=[{AttributeName=authorId,KeyType=HASH}],Projection={ProjectionType=ALL} \
  --billing-mode PAY_PER_REQUEST

Files Table

aws dynamodb create-table \
  --table-name lfg9_forums_files \
  --attribute-definitions \
    AttributeName=fileId,AttributeType=S \
    AttributeName=userId,AttributeType=S \
  --key-schema \
    AttributeName=fileId,KeyType=HASH \
  --global-secondary-indexes \
    IndexName=UserIdIndex,KeySchema=[{AttributeName=userId,KeyType=HASH}],Projection={ProjectionType=ALL} \
  --billing-mode PAY_PER_REQUEST

2. S3 Bucket Setup

Create S3 bucket for file uploads:

aws s3 mb s3://lfg9-forums-uploads --region us-east-1

Configure bucket policy for proper access:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::lfg9-forums-uploads/*"
    }
  ]
}

Configure CORS for the bucket:

[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
    "AllowedOrigins": ["https://yourdomain.com"],
    "ExposeHeaders": ["ETag"]
  }
]

3. IAM Role and Policies

Create IAM role for the application:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:Query",
        "dynamodb:Scan",
        "dynamodb:UpdateItem",
        "dynamodb:DeleteItem"
      ],
      "Resource": [
        "arn:aws:dynamodb:*:*:table/lfg9_forums_*",
        "arn:aws:dynamodb:*:*:table/lfg9_forums_*/index/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:PutObjectAcl"
      ],
      "Resource": "arn:aws:s3:::lfg9-forums-uploads/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": "arn:aws:s3:::lfg9-forums-uploads"
    }
  ]
}

Backend Deployment

Option 1: AWS ECS with Fargate

  1. Create Dockerfile:
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY dist ./dist

EXPOSE 3000

CMD ["npm", "start"]
  1. Build and push to ECR:
# Build the application
npm run build

# Build Docker image
docker build -t lfg9-forums-backend .

# Tag and push to ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com
docker tag lfg9-forums-backend:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/lfg9-forums-backend:latest
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/lfg9-forums-backend:latest
  1. Create ECS Task Definition:
{
  "family": "lfg9-forums-backend",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::123456789012:role/lfg9-forums-task-role",
  "containerDefinitions": [
    {
      "name": "lfg9-forums-backend",
      "image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/lfg9-forums-backend:latest",
      "portMappings": [
        {
          "containerPort": 3000,
          "protocol": "tcp"
        }
      ],
      "environment": [
        {
          "name": "NODE_ENV",
          "value": "production"
        },
        {
          "name": "PORT",
          "value": "3000"
        }
      ],
      "secrets": [
        {
          "name": "JWT_SECRET",
          "valueFrom": "arn:aws:secretsmanager:us-east-1:123456789012:secret:lfg9-forums/jwt-secret"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/lfg9-forums-backend",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ]
}

Option 2: AWS Lambda with Serverless Framework

  1. Install Serverless Framework:
npm install -g serverless
npm install --save-dev serverless-offline
  1. Create serverless.yml:
service: lfg9-forums-backend

provider:
  name: aws
  runtime: nodejs18.x
  region: us-east-1
  environment:
    NODE_ENV: production
    DYNAMODB_TABLE_PREFIX: ${self:service}-${opt:stage, self:provider.stage}-
    S3_BUCKET_NAME: lfg9-forums-uploads-${opt:stage, self:provider.stage}
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource: "arn:aws:dynamodb:${self:provider.region}:*:table/${self:service}-${opt:stage, self:provider.stage}-*"
    - Effect: Allow
      Action:
        - s3:GetObject
        - s3:PutObject
        - s3:DeleteObject
      Resource: "arn:aws:s3:::lfg9-forums-uploads-${opt:stage, self:provider.stage}/*"

functions:
  api:
    handler: dist/lambda.handler
    events:
      - http:
          path: /{proxy+}
          method: ANY
          cors: true

plugins:
  - serverless-offline

Frontend Deployment

Option 1: AWS S3 + CloudFront

  1. Build the frontend:
cd frontend
npm run build
  1. Create S3 bucket for hosting:
aws s3 mb s3://lfg9-forums-frontend --region us-east-1
  1. Configure bucket for static website hosting:
aws s3 website s3://lfg9-forums-frontend --index-document index.html --error-document index.html
  1. Upload build files:
aws s3 sync dist/ s3://lfg9-forums-frontend --delete
  1. Create CloudFront distribution:
{
  "DistributionConfig": {
    "CallerReference": "lfg9-forums-frontend-2024",
    "Comment": "LFG9 Forums Frontend Distribution",
    "DefaultCacheBehavior": {
      "TargetOriginId": "S3-lfg9-forums-frontend",
      "ViewerProtocolPolicy": "redirect-to-https",
      "TrustedSigners": {
        "Enabled": false,
        "Quantity": 0
      },
      "ForwardedValues": {
        "QueryString": false,
        "Cookies": {
          "Forward": "none"
        }
      },
      "MinTTL": 0
    },
    "Origins": {
      "Quantity": 1,
      "Items": [
        {
          "Id": "S3-lfg9-forums-frontend",
          "DomainName": "lfg9-forums-frontend.s3.amazonaws.com",
          "S3OriginConfig": {
            "OriginAccessIdentity": ""
          }
        }
      ]
    },
    "Enabled": true,
    "PriceClass": "PriceClass_All"
  }
}

Option 2: Netlify Deployment

  1. Create netlify.toml:
[build]
  command = "npm run build"
  publish = "dist"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

[build.environment]
  VITE_API_URL = "https://api.yourdomain.com"
  1. Deploy via Netlify CLI:
npm install -g netlify-cli
netlify login
netlify deploy --prod --dir=dist

Environment Configuration

Production Environment Variables

Backend (.env)

NODE_ENV=production
PORT=3000
JWT_SECRET=your-production-jwt-secret
JWT_EXPIRES_IN=7d
AWS_REGION=us-east-1
DYNAMODB_TABLE_PREFIX=lfg9_forums_
S3_BUCKET_NAME=lfg9-forums-uploads
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
MAX_FILE_SIZE=10485760
MAX_FILES_PER_USER=100
CORS_ORIGIN=https://yourdomain.com

Frontend (.env.production)

VITE_API_URL=https://api.yourdomain.com
VITE_WS_URL=wss://api.yourdomain.com

SSL/TLS Configuration

AWS Certificate Manager

  1. Request SSL certificate:
aws acm request-certificate \
  --domain-name yourdomain.com \
  --subject-alternative-names "*.yourdomain.com" \
  --validation-method DNS
  1. Validate certificate through DNS validation

  2. Update CloudFront and ALB to use the certificate

Monitoring and Logging

CloudWatch Setup

  1. Create log groups:
aws logs create-log-group --log-group-name /aws/ecs/lfg9-forums-backend
aws logs create-log-group --log-group-name /aws/lambda/lfg9-forums-backend
  1. Set up CloudWatch dashboards for monitoring:
    • API response times
    • Error rates
    • DynamoDB read/write capacity
    • S3 upload metrics

Health Checks

Configure health checks for:

  • Backend API endpoint (/health)
  • Database connectivity
  • S3 access

Security Checklist

  • Enable AWS WAF on CloudFront
  • Configure proper CORS origins
  • Use HTTPS everywhere
  • Enable DynamoDB encryption at rest
  • Configure S3 bucket policies correctly
  • Use AWS Secrets Manager for sensitive data
  • Enable CloudTrail for API logging
  • Configure proper IAM roles and policies
  • Enable MFA for AWS root account
  • Regularly rotate JWT secrets

Performance Optimization

  1. Enable CloudFront caching for static assets
  2. Configure DynamoDB auto-scaling
  3. Use S3 Transfer Acceleration for file uploads
  4. Enable gzip compression on CloudFront
  5. Implement CDN for global content delivery
  6. Monitor and optimize database queries

Backup and Disaster Recovery

  1. Enable DynamoDB point-in-time recovery
  2. Configure S3 cross-region replication
  3. Regular database backups
  4. Test disaster recovery procedures

Maintenance

  1. Regular security updates
  2. Monitor AWS service limits
  3. Review and optimize costs
  4. Update dependencies regularly
  5. Monitor application performance