← back to Goodquestion

DEPLOYMENT.md

633 lines

# Deployment Guide

Complete guide for deploying the SWOT Analysis Platform to production.

## Deployment Options

### Option 1: Vercel (Recommended)

Vercel provides the best integration with Next.js and supports automatic deployments from GitHub.

#### Setup Steps

1. **Create Vercel Account**
   - Go to [vercel.com](https://vercel.com)
   - Sign up with GitHub

2. **Install Vercel CLI** (optional but recommended)
   ```bash
   npm i -g vercel
   ```

3. **Connect GitHub Repository**
   - Push your code to GitHub
   - In Vercel dashboard, click "New Project"
   - Import your repository

4. **Configure Environment Variables**
   In Project Settings → Environment Variables, add:
   ```
   ANTHROPIC_API_KEY=sk-ant-api03-xxx
   MCP_SERVER_URL=https://your-mcp-server.com
   MCP_API_KEY=your_mcp_key
   NEXT_PUBLIC_APP_URL=https://your-domain.vercel.app
   ```

5. **Deploy**
   ```bash
   # First deployment
   vercel

   # Production deployment
   vercel --prod
   ```

6. **Set Up Custom Domain**
   - In Project Settings → Domains
   - Add your custom domain
   - Follow DNS configuration instructions

#### Continuous Deployment

Vercel automatically deploys:
- **Production**: Every push to `main` branch
- **Preview**: Every pull request gets a unique preview URL

To customize:
```json
// vercel.json
{
  "git": {
    "deploymentEnabled": {
      "main": true,
      "feature/*": true
    }
  },
  "github": {
    "silent": false
  }
}
```

---

### Option 2: Self-Hosted (Docker)

For full control over hosting environment.

#### 1. Create Dockerfile

Already included in the project root:

```dockerfile
FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000
ENV HOSTNAME "0.0.0.0"

CMD ["node", "server.js"]
```

#### 2. Build and Run

```bash
# Build image
docker build -t swot-platform .

# Run container
docker run -d \
  -p 3000:3000 \
  --name swot-app \
  --env-file .env \
  swot-platform

# Check logs
docker logs -f swot-app
```

#### 3. Docker Compose (with MCP Server)

```yaml
# docker-compose.yml
version: '3.8'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - MCP_SERVER_URL=http://mcp-server:8000
      - MCP_API_KEY=${MCP_API_KEY}
    depends_on:
      - mcp-server

  mcp-server:
    build: ./mcp-server
    ports:
      - "8000:8000"
    volumes:
      - ./data:/app/data
    environment:
      - MCP_API_KEY=${MCP_API_KEY}
```

Deploy:
```bash
docker-compose up -d
```

---

### Option 3: AWS (EC2 + RDS)

For enterprise-grade deployment with database.

#### Prerequisites
- AWS account
- AWS CLI configured
- Domain name

#### Steps

1. **Create EC2 Instance**
   ```bash
   aws ec2 run-instances \
     --image-id ami-0c55b159cbfafe1f0 \
     --instance-type t3.medium \
     --key-name your-key-pair \
     --security-group-ids sg-xxxxx
   ```

2. **SSH into Instance**
   ```bash
   ssh -i your-key.pem ec2-user@your-instance-ip
   ```

3. **Install Dependencies**
   ```bash
   # Install Node.js
   curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash -
   sudo yum install -y nodejs

   # Install PM2
   sudo npm install -g pm2

   # Install Docker (optional)
   sudo yum install -y docker
   sudo service docker start
   ```

4. **Deploy Application**
   ```bash
   # Clone repository
   git clone https://github.com/your-repo/swot-platform.git
   cd swot-platform

   # Install dependencies
   npm ci

   # Build
   npm run build

   # Start with PM2
   pm2 start npm --name "swot-app" -- start
   pm2 save
   pm2 startup
   ```

5. **Configure Nginx Reverse Proxy**
   ```nginx
   # /etc/nginx/conf.d/swot.conf
   server {
       listen 80;
       server_name your-domain.com;

       location / {
           proxy_pass http://localhost:3000;
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection 'upgrade';
           proxy_set_header Host $host;
           proxy_cache_bypass $http_upgrade;
       }
   }
   ```

6. **Set Up SSL with Let's Encrypt**
   ```bash
   sudo certbot --nginx -d your-domain.com
   ```

---

## MCP Server Deployment

The MCP server needs to be deployed separately for production use.

### Option A: Replit (Quick & Easy)

1. **Create New Repl**
   - Go to [replit.com](https://replit.com)
   - Create new Python repl

2. **Add Code**
   ```python
   # main.py
   from fastmcp import FastMCP
   import chromadb
   import os

   mcp = FastMCP("SWOT Data Server")
   client = chromadb.Client()

   # Initialize collections
   collection = client.create_collection("business_data")

   @mcp.tool()
   def search(query: str, limit: int = 10):
       results = collection.query(
           query_texts=[query],
           n_results=limit
       )
       return results

   @mcp.tool()
   def fetch(document_id: str):
       doc = collection.get(ids=[document_id])
       return doc

   if __name__ == "__main__":
       port = int(os.getenv("PORT", 8000))
       mcp.run(host="0.0.0.0", port=port)
   ```

3. **Add Dependencies**
   ```txt
   # requirements.txt
   fastmcp
   chromadb
   uvicorn
   ```

4. **Run and Get URL**
   - Click "Run"
   - Copy the public URL (e.g., `https://your-repl.repl.co`)
   - Use this as `MCP_SERVER_URL`

### Option B: Railway

1. **Install Railway CLI**
   ```bash
   npm i -g @railway/cli
   ```

2. **Deploy MCP Server**
   ```bash
   cd mcp-server
   railway login
   railway init
   railway up
   ```

3. **Get Public URL**
   ```bash
   railway domain
   ```

### Option C: AWS Lambda (Serverless)

For production-grade, auto-scaling deployment:

```python
# lambda_handler.py
import json
from fastmcp import FastMCP

mcp = FastMCP("SWOT MCP")

def lambda_handler(event, context):
    # Parse API Gateway event
    path = event['path']
    method = event['httpMethod']
    body = json.loads(event.get('body', '{}'))

    # Route to MCP handlers
    if path == '/search' and method == 'POST':
        results = mcp.search(body['query'], body.get('limit', 10))
        return {
            'statusCode': 200,
            'body': json.dumps(results)
        }

    return {
        'statusCode': 404,
        'body': json.dumps({'error': 'Not found'})
    }
```

Deploy with SAM or Serverless Framework.

---

## Database Setup (Optional)

For storing analysis results and user data:

### PostgreSQL on AWS RDS

```bash
# Create RDS instance
aws rds create-db-instance \
  --db-instance-identifier swot-db \
  --db-instance-class db.t3.micro \
  --engine postgres \
  --master-username admin \
  --master-user-password yourpassword \
  --allocated-storage 20
```

### Prisma Schema

```prisma
// prisma/schema.prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model Analysis {
  id              String   @id @default(cuid())
  businessName    String
  businessType    String
  location        String
  swotData        Json
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt
}
```

---

## Environment Configuration

### Production Environment Variables

```env
# API Keys
ANTHROPIC_API_KEY=sk-ant-api03-xxx
MCP_API_KEY=prod_xxx

# URLs
MCP_SERVER_URL=https://mcp.your-domain.com
NEXT_PUBLIC_APP_URL=https://your-domain.com

# Database (if using)
DATABASE_URL=postgresql://user:pass@host:5432/dbname

# Analytics (optional)
NEXT_PUBLIC_VERCEL_ANALYTICS_ID=xxx
```

### Security Best Practices

1. **Never commit `.env` files**
   - Use `.env.example` for documentation
   - Set real values in deployment platform

2. **Rotate API keys regularly**
   - Set calendar reminder for quarterly rotation

3. **Use secrets management**
   ```bash
   # AWS Secrets Manager
   aws secretsmanager create-secret \
     --name swot/anthropic-key \
     --secret-string "sk-ant-xxx"
   ```

4. **Enable CORS properly**
   ```typescript
   // next.config.js
   module.exports = {
     async headers() {
       return [
         {
           source: '/api/:path*',
           headers: [
             { key: 'Access-Control-Allow-Origin', value: 'https://your-domain.com' },
           ],
         },
       ]
     },
   }
   ```

---

## Monitoring & Analytics

### Vercel Analytics

Add to `app/layout.tsx`:
```typescript
import { Analytics } from '@vercel/analytics/react'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  )
}
```

### Error Tracking (Sentry)

```bash
npm install @sentry/nextjs
```

```javascript
// sentry.client.config.js
import * as Sentry from '@sentry/nextjs'

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tracesSampleRate: 1.0,
})
```

---

## CI/CD Pipeline

### GitHub Actions

```yaml
# .github/workflows/deploy.yml
name: Deploy to Production

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm test

      - name: Build
        run: npm run build
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v20
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.ORG_ID }}
          vercel-project-id: ${{ secrets.PROJECT_ID }}
          vercel-args: '--prod'
```

---

## Post-Deployment Checklist

- [ ] Verify all environment variables are set
- [ ] Test API endpoints (`/api/analyze`, `/api/mcp/search`)
- [ ] Check SSL certificate is active
- [ ] Verify MCP server connectivity
- [ ] Test with real business analysis
- [ ] Set up monitoring alerts
- [ ] Configure backup strategy
- [ ] Document custom domain DNS settings
- [ ] Enable CDN for static assets
- [ ] Set up log aggregation

---

## Troubleshooting

### Build Failures

```bash
# Clear cache and rebuild
rm -rf .next node_modules
npm install
npm run build
```

### MCP Connection Issues

```bash
# Test MCP endpoint
curl -X POST https://your-mcp-server.com/search \
  -H "Content-Type: application/json" \
  -d '{"query": "test", "limit": 1}'
```

### Memory Issues on Build

```json
// package.json
{
  "scripts": {
    "build": "NODE_OPTIONS='--max-old-space-size=4096' next build"
  }
}
```

---

## Scaling Considerations

As your application grows:

1. **Add Redis for caching**
   ```typescript
   import Redis from 'ioredis'
   const redis = new Redis(process.env.REDIS_URL)

   // Cache analysis results
   await redis.setex(`analysis:${id}`, 3600, JSON.stringify(data))
   ```

2. **Implement rate limiting**
   ```typescript
   import { Ratelimit } from '@upstash/ratelimit'
   const ratelimit = new Ratelimit({
     redis,
     limiter: Ratelimit.slidingWindow(10, '1 h'),
   })
   ```

3. **Use CDN for assets**
   - Vercel automatically provides this
   - For self-hosted, use CloudFront or Cloudflare

4. **Queue long-running analyses**
   ```typescript
   import { Queue } from 'bullmq'
   const analysisQueue = new Queue('analysis')
   await analysisQueue.add('swot-analysis', { businessName, businessType, location })
   ```

---

For additional support, consult the main README.md or open an issue on GitHub.