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

496 lines
11 KiB
Markdown

# Deployment Guide
Complete deployment guide for the LFG9 Forums application.
## AWS Infrastructure Setup
### 1. DynamoDB Tables
Create the following DynamoDB tables:
#### Users Table
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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:
```bash
aws s3 mb s3://lfg9-forums-uploads --region us-east-1
```
Configure bucket policy for proper access:
```json
{
"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:
```json
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
"AllowedOrigins": ["https://yourdomain.com"],
"ExposeHeaders": ["ETag"]
}
]
```
### 3. IAM Role and Policies
Create IAM role for the application:
```json
{
"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**:
```dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist ./dist
EXPOSE 3000
CMD ["npm", "start"]
```
2. **Build and push to ECR**:
```bash
# 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
```
3. **Create ECS Task Definition**:
```json
{
"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**:
```bash
npm install -g serverless
npm install --save-dev serverless-offline
```
2. **Create serverless.yml**:
```yaml
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**:
```bash
cd frontend
npm run build
```
2. **Create S3 bucket for hosting**:
```bash
aws s3 mb s3://lfg9-forums-frontend --region us-east-1
```
3. **Configure bucket for static website hosting**:
```bash
aws s3 website s3://lfg9-forums-frontend --index-document index.html --error-document index.html
```
4. **Upload build files**:
```bash
aws s3 sync dist/ s3://lfg9-forums-frontend --delete
```
5. **Create CloudFront distribution**:
```json
{
"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**:
```toml
[build]
command = "npm run build"
publish = "dist"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[build.environment]
VITE_API_URL = "https://api.yourdomain.com"
```
2. **Deploy via Netlify CLI**:
```bash
npm install -g netlify-cli
netlify login
netlify deploy --prod --dir=dist
```
## Environment Configuration
### Production Environment Variables
#### Backend (.env)
```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)
```env
VITE_API_URL=https://api.yourdomain.com
VITE_WS_URL=wss://api.yourdomain.com
```
## SSL/TLS Configuration
### AWS Certificate Manager
1. **Request SSL certificate**:
```bash
aws acm request-certificate \
--domain-name yourdomain.com \
--subject-alternative-names "*.yourdomain.com" \
--validation-method DNS
```
2. **Validate certificate** through DNS validation
3. **Update CloudFront and ALB** to use the certificate
## Monitoring and Logging
### CloudWatch Setup
1. **Create log groups**:
```bash
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
```
2. **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**