initial commit
This commit is contained in:
503
docs/API.md
Normal file
503
docs/API.md
Normal file
@@ -0,0 +1,503 @@
|
||||
# SiliconPin API Documentation
|
||||
|
||||
This document describes the comprehensive API endpoints available in the SiliconPin platform.
|
||||
|
||||
## Base URL
|
||||
|
||||
- Development: `http://localhost:4023`
|
||||
- Production: `https://siliconpin.com`
|
||||
|
||||
## Authentication
|
||||
|
||||
This API uses JWT (JSON Web Tokens) for authentication. Tokens are stored in HTTP-only cookies for security.
|
||||
|
||||
### Authentication Flow
|
||||
|
||||
1. Register or login to receive access and refresh tokens
|
||||
2. Access token is valid for 15 minutes
|
||||
3. Refresh token is valid for 7 days
|
||||
4. When access token expires, use refresh endpoint to get new tokens
|
||||
5. All protected routes require valid access token in cookies
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Authentication Endpoints
|
||||
|
||||
#### POST /api/auth/register
|
||||
|
||||
Register a new user account.
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "John Doe",
|
||||
"email": "john@example.com",
|
||||
"password": "securePassword123"
|
||||
}
|
||||
```
|
||||
|
||||
**Validation:**
|
||||
|
||||
- `name`: Required, minimum 2 characters
|
||||
- `email`: Required, valid email format
|
||||
- `password`: Required, minimum 6 characters
|
||||
|
||||
**Response (201 Created):**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"user": {
|
||||
"id": "64f5a2b4c8d9e1f2a3b4c5d6",
|
||||
"name": "John Doe",
|
||||
"email": "john@example.com",
|
||||
"createdAt": "2024-01-15T10:30:00.000Z"
|
||||
}
|
||||
},
|
||||
"message": "User registered successfully"
|
||||
}
|
||||
```
|
||||
|
||||
**Error Responses:**
|
||||
|
||||
```json
|
||||
// 400 Bad Request - Validation Error
|
||||
{
|
||||
"success": false,
|
||||
"error": "Validation failed",
|
||||
"details": [
|
||||
{
|
||||
"field": "email",
|
||||
"message": "Invalid email format"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// 409 Conflict - User Already Exists
|
||||
{
|
||||
"success": false,
|
||||
"error": "User with this email already exists"
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/auth/login
|
||||
|
||||
Sign in an existing user.
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"email": "john@example.com",
|
||||
"password": "securePassword123"
|
||||
}
|
||||
```
|
||||
|
||||
**Response (200 OK):**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"user": {
|
||||
"id": "64f5a2b4c8d9e1f2a3b4c5d6",
|
||||
"name": "John Doe",
|
||||
"email": "john@example.com"
|
||||
}
|
||||
},
|
||||
"message": "Login successful"
|
||||
}
|
||||
```
|
||||
|
||||
**Sets Cookies:**
|
||||
|
||||
- `accessToken`: HTTP-only, expires in 15 minutes
|
||||
- `refreshToken`: HTTP-only, expires in 7 days
|
||||
|
||||
**Error Responses:**
|
||||
|
||||
```json
|
||||
// 401 Unauthorized - Invalid Credentials
|
||||
{
|
||||
"success": false,
|
||||
"error": "Invalid email or password"
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/auth/logout
|
||||
|
||||
Sign out the current user.
|
||||
|
||||
**Authorization:** Required (access token in cookies)
|
||||
|
||||
**Response (200 OK):**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Logout successful"
|
||||
}
|
||||
```
|
||||
|
||||
**Effect:** Clears authentication cookies
|
||||
|
||||
#### POST /api/auth/refresh
|
||||
|
||||
Refresh the access token using refresh token.
|
||||
|
||||
**Authorization:** Required (refresh token in cookies)
|
||||
|
||||
**Response (200 OK):**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Token refreshed successfully"
|
||||
}
|
||||
```
|
||||
|
||||
**Sets Cookies:**
|
||||
|
||||
- New `accessToken`: HTTP-only, expires in 15 minutes
|
||||
- New `refreshToken`: HTTP-only, expires in 7 days
|
||||
|
||||
**Error Responses:**
|
||||
|
||||
```json
|
||||
// 401 Unauthorized - Invalid Refresh Token
|
||||
{
|
||||
"success": false,
|
||||
"error": "Invalid or expired refresh token"
|
||||
}
|
||||
```
|
||||
|
||||
#### GET /api/auth/me
|
||||
|
||||
Get current user information.
|
||||
|
||||
**Authorization:** Required (access token in cookies)
|
||||
|
||||
**Response (200 OK):**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"user": {
|
||||
"id": "64f5a2b4c8d9e1f2a3b4c5d6",
|
||||
"name": "John Doe",
|
||||
"email": "john@example.com",
|
||||
"createdAt": "2024-01-15T10:30:00.000Z",
|
||||
"updatedAt": "2024-01-15T10:30:00.000Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Error Responses:**
|
||||
|
||||
```json
|
||||
// 401 Unauthorized - No Token or Invalid Token
|
||||
{
|
||||
"success": false,
|
||||
"error": "Authentication required"
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
All API endpoints follow a consistent error response format:
|
||||
|
||||
### Standard Error Response
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Error message",
|
||||
"details": [] // Optional array of detailed errors
|
||||
}
|
||||
```
|
||||
|
||||
### HTTP Status Codes
|
||||
|
||||
- `200` - Success
|
||||
- `201` - Created (successful registration)
|
||||
- `400` - Bad Request (validation errors)
|
||||
- `401` - Unauthorized (authentication required/failed)
|
||||
- `403` - Forbidden (access denied)
|
||||
- `404` - Not Found
|
||||
- `409` - Conflict (resource already exists)
|
||||
- `500` - Internal Server Error
|
||||
|
||||
### Validation Errors
|
||||
|
||||
When validation fails, the API returns detailed error information:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Validation failed",
|
||||
"details": [
|
||||
{
|
||||
"field": "email",
|
||||
"message": "Invalid email format"
|
||||
},
|
||||
{
|
||||
"field": "password",
|
||||
"message": "Password must be at least 6 characters"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
Currently, no rate limiting is implemented. For production deployment, consider adding rate limiting to prevent abuse:
|
||||
|
||||
- Login attempts: 5 per minute per IP
|
||||
- Registration: 3 per minute per IP
|
||||
- General API: 100 per minute per IP
|
||||
|
||||
## CORS Configuration
|
||||
|
||||
CORS is configured to allow requests from your frontend domain. In development, all origins are allowed.
|
||||
|
||||
## Security Headers
|
||||
|
||||
The API includes security headers:
|
||||
|
||||
- `Content-Security-Policy`
|
||||
- `X-Content-Type-Options: nosniff`
|
||||
- `X-Frame-Options: DENY`
|
||||
- `X-XSS-Protection: 1; mode=block`
|
||||
|
||||
## Frontend Integration
|
||||
|
||||
### Using with fetch API
|
||||
|
||||
```javascript
|
||||
// Login example
|
||||
const login = async (email, password) => {
|
||||
const response = await fetch('/api/auth/login', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ email, password }),
|
||||
credentials: 'include', // Important: include cookies
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
throw new Error(data.error)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// Protected API call example
|
||||
const getUserProfile = async () => {
|
||||
const response = await fetch('/api/auth/me', {
|
||||
method: 'GET',
|
||||
credentials: 'include', // Important: include cookies
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
if (response.status === 401) {
|
||||
// Token expired, try to refresh
|
||||
await refreshToken()
|
||||
// Retry the original request
|
||||
return getUserProfile()
|
||||
}
|
||||
throw new Error(data.error)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
```
|
||||
|
||||
### Using with Axios
|
||||
|
||||
```javascript
|
||||
import axios from 'axios'
|
||||
|
||||
// Configure axios to include cookies
|
||||
axios.defaults.withCredentials = true
|
||||
|
||||
// Request interceptor for automatic token refresh
|
||||
axios.interceptors.response.use(
|
||||
(response) => response,
|
||||
async (error) => {
|
||||
if (error.response?.status === 401) {
|
||||
try {
|
||||
await axios.post('/api/auth/refresh')
|
||||
// Retry the original request
|
||||
return axios.request(error.config)
|
||||
} catch (refreshError) {
|
||||
// Refresh failed, redirect to login
|
||||
window.location.href = '/auth'
|
||||
}
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Testing the API
|
||||
|
||||
### Using curl
|
||||
|
||||
```bash
|
||||
# Register a new user
|
||||
curl -X POST http://localhost:4023/api/auth/register \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"Test User","email":"test@example.com","password":"password123"}' \
|
||||
-c cookies.txt
|
||||
|
||||
# Login
|
||||
curl -X POST http://localhost:4023/api/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"test@example.com","password":"password123"}' \
|
||||
-c cookies.txt
|
||||
|
||||
# Get user profile (protected route)
|
||||
curl -X GET http://localhost:4023/api/auth/me \
|
||||
-b cookies.txt
|
||||
|
||||
# Logout
|
||||
curl -X POST http://localhost:4023/api/auth/logout \
|
||||
-b cookies.txt
|
||||
```
|
||||
|
||||
### Using Postman
|
||||
|
||||
1. Set up environment variables for base URL
|
||||
2. Use "Send and download cookies" option in requests
|
||||
3. Test the authentication flow step by step
|
||||
4. Save cookies between requests for protected routes
|
||||
|
||||
## Extending the API
|
||||
|
||||
### Adding New Protected Routes
|
||||
|
||||
```typescript
|
||||
// app/api/example/route.ts
|
||||
import { authMiddleware } from '@/lib/auth-middleware'
|
||||
|
||||
export async function GET(request: Request) {
|
||||
// Authenticate the request
|
||||
const user = await authMiddleware(request)
|
||||
|
||||
if (!user) {
|
||||
return Response.json({ success: false, error: 'Authentication required' }, { status: 401 })
|
||||
}
|
||||
|
||||
// Your protected logic here
|
||||
return Response.json({
|
||||
success: true,
|
||||
data: { message: 'Protected data', user: user.id },
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### Adding Request Validation
|
||||
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
const CreatePostSchema = z.object({
|
||||
title: z.string().min(1, 'Title is required'),
|
||||
content: z.string().min(10, 'Content must be at least 10 characters'),
|
||||
})
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const body = await request.json()
|
||||
const validatedData = CreatePostSchema.parse(body)
|
||||
|
||||
// Process validated data
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
error: 'Validation failed',
|
||||
details: error.errors.map((err) => ({
|
||||
field: err.path.join('.'),
|
||||
message: err.message,
|
||||
})),
|
||||
},
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
return Response.json({ success: false, error: 'Internal server error' }, { status: 500 })
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Additional API Endpoints
|
||||
|
||||
SiliconPin includes extensive API coverage beyond authentication:
|
||||
|
||||
### Topics API
|
||||
|
||||
- `GET /api/topics` - List all topics with search and filtering
|
||||
- `POST /api/topics` - Create new topic (protected)
|
||||
- `GET /api/topics/[slug]` - Get specific topic
|
||||
- `PUT /api/topic/[id]` - Update topic (protected, owner only)
|
||||
- `DELETE /api/topic/[id]` - Delete topic (protected, owner only)
|
||||
- `GET /api/topics/[slug]/related` - Get related topics
|
||||
- `POST /api/topics/[slug]/view` - Track topic views
|
||||
|
||||
### Admin API (Protected, Admin Only)
|
||||
|
||||
- `GET /api/admin/dashboard` - Admin dashboard statistics
|
||||
- `GET /api/admin/users` - User management
|
||||
- `GET /api/admin/billing` - Billing management
|
||||
- `GET /api/admin/reports` - Generate reports
|
||||
- `GET /api/admin/services` - Service management
|
||||
- `GET /api/admin/settings` - System settings
|
||||
|
||||
### Services API
|
||||
|
||||
- `POST /api/services/deploy-kubernetes` - Deploy K8s service
|
||||
- `POST /api/services/deploy-vpn` - Deploy VPN service
|
||||
- `POST /api/services/deploy-cloude` - Deploy cloud instance
|
||||
- `POST /api/services/hire-developer` - Developer hiring request
|
||||
- `GET /api/services/active` - Get active services
|
||||
|
||||
### Payment & Billing API
|
||||
|
||||
- `POST /api/balance/add` - Add balance to account
|
||||
- `POST /api/balance/deduct` - Deduct balance
|
||||
- `GET /api/user/balance` - Get user balance
|
||||
- `POST /api/payments/initiate` - Initiate payment
|
||||
- `GET /api/billing` - Get billing history
|
||||
- `GET /api/billing/stats` - Billing statistics
|
||||
- `GET /api/transactions` - Transaction history
|
||||
|
||||
### Tools API
|
||||
|
||||
- `POST /api/tools/openai-chat` - OpenAI chat integration
|
||||
|
||||
### Upload & File Management
|
||||
|
||||
- `POST /api/upload` - Upload files to MinIO
|
||||
- `POST /api/upload/confirm` - Confirm file upload
|
||||
- `POST /api/topic-content-image` - Upload topic images
|
||||
|
||||
### Utility API
|
||||
|
||||
- `GET /api/health` - Health check endpoint
|
||||
- `POST /api/contact` - Contact form submission
|
||||
- `POST /api/feedback` - Submit feedback
|
||||
- `GET /api/tags` - Get all available tags
|
||||
- `GET /api/startup-test` - System startup validation
|
||||
|
||||
This comprehensive API documentation covers the complete SiliconPin platform, providing authentication, content management, admin capabilities, web services, payment processing, and utility endpoints.
|
||||
593
docs/DEPLOYMENT.md
Normal file
593
docs/DEPLOYMENT.md
Normal file
@@ -0,0 +1,593 @@
|
||||
# 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.
|
||||
1124
docs/PATTERNS.md
Normal file
1124
docs/PATTERNS.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user