594 lines
12 KiB
Markdown
594 lines
12 KiB
Markdown
# Deployment Guide
|
|
|
|
This guide covers various deployment options for the SiliconPin application.
|
|
|
|
## Table of Contents
|
|
|
|
- [Prerequisites](#prerequisites)
|
|
- [Environment Configuration](#environment-configuration)
|
|
- [Docker Deployment](#docker-deployment)
|
|
- [Platform Deployments](#platform-deployments)
|
|
- [Vercel](#vercel)
|
|
- [Railway](#railway)
|
|
- [DigitalOcean App Platform](#digitalocean-app-platform)
|
|
- [AWS ECS](#aws-ecs)
|
|
- [Database Setup](#database-setup)
|
|
- [SSL/HTTPS Configuration](#sslhttps-configuration)
|
|
- [Monitoring and Logging](#monitoring-and-logging)
|
|
- [Troubleshooting](#troubleshooting)
|
|
|
|
## Prerequisites
|
|
|
|
Before deploying, ensure you have:
|
|
|
|
- Node.js 18+ installed locally (for building)
|
|
- Docker and Docker Compose (for containerized deployment)
|
|
- Access to MongoDB database (local, Atlas, or cloud provider)
|
|
- Access to Redis instance (local, cloud, or managed service)
|
|
- Domain name (for production deployment)
|
|
- SSL certificates (for HTTPS)
|
|
|
|
## Environment Configuration
|
|
|
|
### Required Environment Variables
|
|
|
|
Create a `.env.production.local` file with the following variables:
|
|
|
|
```env
|
|
# Database (REQUIRED)
|
|
MONGODB_URI=mongodb://username:password@host:port/database
|
|
|
|
# Redis (REQUIRED)
|
|
REDIS_URL=redis://username:password@host:port
|
|
|
|
# Authentication Secrets (REQUIRED - Generate secure random strings)
|
|
SESSION_SECRET=your-secure-32-character-session-secret
|
|
JWT_SECRET=your-secure-jwt-secret
|
|
JWT_REFRESH_SECRET=your-secure-jwt-refresh-secret
|
|
|
|
# Application
|
|
NODE_ENV=production
|
|
NEXT_PUBLIC_SITE_URL=https://siliconpin.com
|
|
```
|
|
|
|
### Optional Environment Variables
|
|
|
|
```env
|
|
# Analytics
|
|
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX
|
|
NEXT_PUBLIC_PLAUSIBLE_DOMAIN=siliconpin.com
|
|
|
|
# Email
|
|
SMTP_HOST=smtp.gmail.com
|
|
SMTP_PORT=587
|
|
SMTP_USER=your-email@gmail.com
|
|
SMTP_PASS=your-app-password
|
|
|
|
# File Storage
|
|
MINIO_ENDPOINT=your-minio-endpoint
|
|
MINIO_ACCESS_KEY=your-access-key
|
|
MINIO_SECRET_KEY=your-secret-key
|
|
MINIO_BUCKET=your-bucket-name
|
|
|
|
# Monitoring
|
|
SENTRY_DSN=your-sentry-dsn
|
|
```
|
|
|
|
### Generating Secrets
|
|
|
|
Generate secure secrets using:
|
|
|
|
```bash
|
|
# Generate a 32-character secret
|
|
openssl rand -base64 32
|
|
|
|
# Or use Node.js
|
|
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
|
|
```
|
|
|
|
## Docker Deployment
|
|
|
|
### Local Development with Docker
|
|
|
|
1. **Start services only (recommended for development):**
|
|
|
|
```bash
|
|
docker-compose -f docker-compose.dev.yml up -d
|
|
yarn dev
|
|
```
|
|
|
|
2. **Full containerized development:**
|
|
```bash
|
|
docker-compose -f docker-compose.dev.yml up -d
|
|
```
|
|
|
|
### Production Deployment with Docker
|
|
|
|
1. **Build and start all services:**
|
|
|
|
```bash
|
|
docker-compose up -d
|
|
```
|
|
|
|
2. **Build and start with production profile:**
|
|
|
|
```bash
|
|
docker-compose --profile production up -d
|
|
```
|
|
|
|
3. **Scale the application:**
|
|
```bash
|
|
docker-compose up -d --scale app=3
|
|
```
|
|
|
|
### Docker Commands
|
|
|
|
```bash
|
|
# Build the application image
|
|
docker build -t siliconpin .
|
|
|
|
# Run the application container
|
|
docker run -p 3006:3006 --env-file .env.production.local siliconpin
|
|
|
|
# View logs
|
|
docker-compose logs -f app
|
|
|
|
# Execute commands in running container
|
|
docker-compose exec app yarn db:seed
|
|
|
|
# Update and restart services
|
|
docker-compose pull && docker-compose up -d
|
|
```
|
|
|
|
## Platform Deployments
|
|
|
|
### Vercel
|
|
|
|
Vercel is the recommended platform for Next.js applications.
|
|
|
|
1. **Connect your repository to Vercel:**
|
|
- Visit [vercel.com](https://vercel.com) and import your repository
|
|
- Vercel will automatically detect Next.js configuration
|
|
|
|
2. **Configure environment variables:**
|
|
- Go to Project Settings → Environment Variables
|
|
- Add all required environment variables
|
|
- Set `NODE_ENV=production`
|
|
|
|
3. **Configure build settings:**
|
|
|
|
```bash
|
|
# Build Command (default is correct)
|
|
yarn build
|
|
|
|
# Output Directory (default is correct)
|
|
.next
|
|
|
|
# Install Command
|
|
yarn install
|
|
```
|
|
|
|
4. **Domain configuration:**
|
|
- Add your custom domain in Project Settings → Domains
|
|
- Configure DNS to point to Vercel
|
|
|
|
### Railway
|
|
|
|
Railway provides easy deployment with built-in database services.
|
|
|
|
1. **Install Railway CLI:**
|
|
|
|
```bash
|
|
npm install -g @railway/cli
|
|
railway login
|
|
```
|
|
|
|
2. **Initialize and deploy:**
|
|
|
|
```bash
|
|
railway init
|
|
railway add # Add MongoDB and Redis plugins
|
|
railway up
|
|
```
|
|
|
|
3. **Configure environment variables:**
|
|
|
|
```bash
|
|
# Set environment variables
|
|
railway variables set SESSION_SECRET=your-secret
|
|
railway variables set JWT_SECRET=your-jwt-secret
|
|
|
|
# Railway automatically provides DATABASE_URL and REDIS_URL
|
|
```
|
|
|
|
4. **Custom domain:**
|
|
```bash
|
|
railway domain # Follow prompts to add custom domain
|
|
```
|
|
|
|
### DigitalOcean App Platform
|
|
|
|
1. **Create App Spec (app.yaml):**
|
|
|
|
```yaml
|
|
name: siliconpin
|
|
services:
|
|
- name: web
|
|
source_dir: /
|
|
github:
|
|
repo: your-username/your-repo
|
|
branch: main
|
|
run_command: yarn start
|
|
build_command: yarn build
|
|
environment_slug: node-js
|
|
instance_count: 1
|
|
instance_size_slug: basic-xxs
|
|
routes:
|
|
- path: /
|
|
envs:
|
|
- key: NODE_ENV
|
|
value: production
|
|
- key: MONGODB_URI
|
|
value: ${db.DATABASE_URL}
|
|
- key: REDIS_URL
|
|
value: ${redis.DATABASE_URL}
|
|
|
|
databases:
|
|
- name: db
|
|
engine: MONGODB
|
|
- name: redis
|
|
engine: REDIS
|
|
```
|
|
|
|
2. **Deploy using CLI:**
|
|
```bash
|
|
doctl apps create --spec app.yaml
|
|
```
|
|
|
|
### AWS ECS
|
|
|
|
1. **Create ECR repository:**
|
|
|
|
```bash
|
|
aws ecr create-repository --repository-name siliconpin
|
|
```
|
|
|
|
2. **Build and push Docker image:**
|
|
|
|
```bash
|
|
# Get login token
|
|
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com
|
|
|
|
# Build and tag image
|
|
docker build -t siliconpin .
|
|
docker tag siliconpin:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/siliconpin:latest
|
|
|
|
# Push image
|
|
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/siliconpin:latest
|
|
```
|
|
|
|
3. **Create ECS task definition and service:**
|
|
- Use AWS Console or CLI to create ECS cluster
|
|
- Configure task definition with environment variables
|
|
- Set up Application Load Balancer
|
|
- Configure auto-scaling
|
|
|
|
## Database Setup
|
|
|
|
### MongoDB Atlas (Recommended)
|
|
|
|
1. **Create MongoDB Atlas cluster:**
|
|
- Visit [mongodb.com/cloud/atlas](https://mongodb.com/cloud/atlas)
|
|
- Create a new cluster
|
|
- Configure network access and database user
|
|
|
|
2. **Get connection string:**
|
|
|
|
```
|
|
mongodb+srv://username:password@cluster0.mongodb.net/database?retryWrites=true&w=majority
|
|
```
|
|
|
|
3. **Seed initial data:**
|
|
```bash
|
|
yarn db:seed
|
|
```
|
|
|
|
### Self-hosted MongoDB
|
|
|
|
1. **Install MongoDB:**
|
|
|
|
```bash
|
|
# Ubuntu/Debian
|
|
sudo apt-get install mongodb
|
|
|
|
# macOS
|
|
brew install mongodb-community
|
|
|
|
# Docker
|
|
docker run -d -p 27017:27017 --name mongodb mongo:7
|
|
```
|
|
|
|
2. **Create database and user:**
|
|
```javascript
|
|
use siliconpin
|
|
db.createUser({
|
|
user: "app",
|
|
pwd: "secure-password",
|
|
roles: ["readWrite"]
|
|
})
|
|
```
|
|
|
|
### Redis Setup
|
|
|
|
#### Redis Cloud (Recommended)
|
|
|
|
1. **Create Redis Cloud account:**
|
|
- Visit [redis.com/redis-enterprise-cloud](https://redis.com/redis-enterprise-cloud)
|
|
- Create a new database
|
|
- Get connection details
|
|
|
|
#### Self-hosted Redis
|
|
|
|
```bash
|
|
# Install Redis
|
|
sudo apt-get install redis-server
|
|
|
|
# Or with Docker
|
|
docker run -d -p 6379:6379 --name redis redis:7-alpine
|
|
|
|
# Configure Redis (optional)
|
|
# Edit /etc/redis/redis.conf
|
|
# Set password: requirepass your-password
|
|
```
|
|
|
|
## SSL/HTTPS Configuration
|
|
|
|
### Automatic SSL (Recommended)
|
|
|
|
Most platforms provide automatic SSL:
|
|
|
|
- **Vercel**: Automatic SSL for all domains
|
|
- **Railway**: Automatic SSL certificates
|
|
- **DigitalOcean**: Managed certificates available
|
|
|
|
### Custom SSL with Nginx
|
|
|
|
1. **Obtain SSL certificates:**
|
|
|
|
```bash
|
|
# Using Let's Encrypt
|
|
sudo certbot --nginx -d siliconpin.com
|
|
```
|
|
|
|
2. **Configure Nginx:**
|
|
|
|
```nginx
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name siliconpin.com;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/siliconpin.com/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/siliconpin.com/privkey.pem;
|
|
|
|
location / {
|
|
proxy_pass http://localhost:4023;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection 'upgrade';
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_cache_bypass $http_upgrade;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Monitoring and Logging
|
|
|
|
### Health Checks
|
|
|
|
The application provides health check endpoints:
|
|
|
|
- **Health Check**: `GET /api/health`
|
|
- **Readiness Check**: `HEAD /api/health`
|
|
|
|
Example health check response:
|
|
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"timestamp": "2024-01-15T10:30:00.000Z",
|
|
"uptime": 3600,
|
|
"environment": "production",
|
|
"version": "1.0.0",
|
|
"checks": {
|
|
"database": { "status": "healthy" },
|
|
"redis": { "status": "healthy" }
|
|
},
|
|
"responseTime": 45
|
|
}
|
|
```
|
|
|
|
### Logging
|
|
|
|
Configure application logging:
|
|
|
|
```javascript
|
|
// lib/logger.ts
|
|
import winston from 'winston'
|
|
|
|
const logger = winston.createLogger({
|
|
level: process.env.LOG_LEVEL || 'info',
|
|
format: winston.format.combine(
|
|
winston.format.timestamp(),
|
|
winston.format.errors({ stack: true }),
|
|
winston.format.json()
|
|
),
|
|
transports: [
|
|
new winston.transports.File({ filename: 'error.log', level: 'error' }),
|
|
new winston.transports.File({ filename: 'combined.log' }),
|
|
],
|
|
})
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
logger.add(
|
|
new winston.transports.Console({
|
|
format: winston.format.simple(),
|
|
})
|
|
)
|
|
}
|
|
```
|
|
|
|
### Error Tracking
|
|
|
|
Set up Sentry for error tracking:
|
|
|
|
1. **Install Sentry:**
|
|
|
|
```bash
|
|
yarn add @sentry/nextjs
|
|
```
|
|
|
|
2. **Configure Sentry:**
|
|
|
|
```javascript
|
|
// sentry.client.config.js
|
|
import * as Sentry from '@sentry/nextjs'
|
|
|
|
Sentry.init({
|
|
dsn: process.env.SENTRY_DSN,
|
|
environment: process.env.NODE_ENV,
|
|
})
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **Environment Variables Not Loading:**
|
|
|
|
```bash
|
|
# Check if .env files are in correct location
|
|
ls -la .env*
|
|
|
|
# Verify environment variables are set
|
|
echo $MONGODB_URI
|
|
```
|
|
|
|
2. **Database Connection Issues:**
|
|
|
|
```bash
|
|
# Test MongoDB connection
|
|
mongosh "mongodb://your-connection-string"
|
|
|
|
# Check MongoDB Atlas network access
|
|
# Ensure your IP is whitelisted
|
|
```
|
|
|
|
3. **Redis Connection Issues:**
|
|
|
|
```bash
|
|
# Test Redis connection
|
|
redis-cli -u redis://your-redis-url ping
|
|
|
|
# Check Redis configuration
|
|
redis-cli config get requirepass
|
|
```
|
|
|
|
4. **Build Failures:**
|
|
|
|
```bash
|
|
# Clear Next.js cache
|
|
rm -rf .next
|
|
|
|
# Clear node_modules and reinstall
|
|
rm -rf node_modules
|
|
yarn install
|
|
|
|
# Check build logs
|
|
yarn build --debug
|
|
```
|
|
|
|
5. **Container Issues:**
|
|
|
|
```bash
|
|
# Check container logs
|
|
docker-compose logs app
|
|
|
|
# Rebuild containers
|
|
docker-compose build --no-cache
|
|
|
|
# Check container resource usage
|
|
docker stats
|
|
```
|
|
|
|
### Performance Issues
|
|
|
|
1. **Slow Database Queries:**
|
|
- Check MongoDB indexes
|
|
- Enable MongoDB profiling
|
|
- Use MongoDB Compass for query analysis
|
|
|
|
2. **High Memory Usage:**
|
|
- Monitor with `docker stats`
|
|
- Check for memory leaks in logs
|
|
- Consider increasing container memory limits
|
|
|
|
3. **Slow Response Times:**
|
|
- Enable Redis caching
|
|
- Optimize images and assets
|
|
- Use CDN for static assets
|
|
|
|
### Security Checklist
|
|
|
|
- [ ] All secrets are generated securely and unique
|
|
- [ ] Database connections use authentication
|
|
- [ ] Redis is password-protected
|
|
- [ ] HTTPS is enabled with valid certificates
|
|
- [ ] Security headers are configured
|
|
- [ ] CORS is properly configured
|
|
- [ ] Rate limiting is implemented
|
|
- [ ] Input validation is in place
|
|
- [ ] Dependencies are up to date
|
|
|
|
### Maintenance
|
|
|
|
#### Regular Tasks
|
|
|
|
1. **Update Dependencies:**
|
|
|
|
```bash
|
|
yarn upgrade
|
|
yarn audit
|
|
```
|
|
|
|
2. **Database Maintenance:**
|
|
|
|
```bash
|
|
# MongoDB
|
|
mongosh --eval "db.runCommand({compact: 'users'})"
|
|
|
|
# Redis
|
|
redis-cli BGREWRITEAOF
|
|
```
|
|
|
|
3. **Log Rotation:**
|
|
|
|
```bash
|
|
# Configure logrotate
|
|
sudo nano /etc/logrotate.d/siliconpin
|
|
```
|
|
|
|
4. **Backup:**
|
|
|
|
```bash
|
|
# MongoDB backup
|
|
mongodump --uri="mongodb://connection-string" --out=/backup/
|
|
|
|
# Redis backup
|
|
redis-cli --rdb /backup/dump.rdb
|
|
```
|
|
|
|
This deployment guide covers the most common deployment scenarios. Choose the method that best fits your infrastructure requirements and expertise level.
|