> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/makriman/inspir/llms.txt
> Use this file to discover all available pages before exploring further.

# Production Deployment

> Deploy inspir to production with Ubuntu, nginx, SSL, and PM2

## Overview

This guide walks through deploying inspir to a production Ubuntu server with:

* **nginx** as a reverse proxy and static file server
* **SSL/TLS** via Let's Encrypt (free certificate)
* **PM2** or **systemd** for process management
* **Domain name** configured with DNS

<Warning>
  Production deployment requires server administration knowledge. Ensure you understand Linux, nginx, and security best practices before proceeding.
</Warning>

## Prerequisites

* **Ubuntu 20.04+ server** with root/sudo access
* **Domain name** pointed to your server's IP address
* **Supabase project** with database schema configured
* **Anthropic API key**
* **Git** installed on the server

## Step 1: Server Setup

<Steps>
  <Step title="Update system packages">
    ```bash theme={null}
    sudo apt update
    sudo apt upgrade -y
    ```
  </Step>

  <Step title="Install Node.js 18+">
    ```bash theme={null}
    curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
    sudo apt-get install -y nodejs

    # Verify installation
    node --version  # Should be 18.x or higher
    npm --version
    ```
  </Step>

  <Step title="Install nginx">
    ```bash theme={null}
    sudo apt install nginx -y
    sudo systemctl enable nginx
    sudo systemctl start nginx
    ```
  </Step>

  <Step title="Install PM2 (recommended)">
    ```bash theme={null}
    sudo npm install -g pm2
    ```

    Alternatively, you can use systemd instead of PM2 (see below).
  </Step>
</Steps>

## Step 2: Clone and Configure the Application

<Steps>
  <Step title="Clone the repository">
    ```bash theme={null}
    cd /root
    git clone https://github.com/yourusername/inspir.git
    cd inspir
    ```
  </Step>

  <Step title="Configure backend environment">
    ```bash theme={null}
    cd backend
    cp .env.example .env
    nano .env  # or vim .env
    ```

    Update with production values:

    ```bash theme={null}
    # Server Configuration
    PORT=3000
    HOST=0.0.0.0
    FRONTEND_URL=https://yourdomain.com  # Your actual domain

    # Anthropic API
    ANTHROPIC_API_KEY=sk-ant-api03-...

    # Supabase Configuration
    SUPABASE_URL=https://xxxxxxxxxxx.supabase.co
    SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
    SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

    # JWT Secret - Generate a strong random string
    JWT_SECRET=$(openssl rand -base64 32)
    ```
  </Step>

  <Step title="Configure frontend environment">
    ```bash theme={null}
    cd ../frontend
    cp .env.example .env
    nano .env
    ```

    Update with production values:

    ```bash theme={null}
    # Supabase Configuration
    VITE_SUPABASE_URL=https://xxxxxxxxxxx.supabase.co
    VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

    # API Configuration - Use your actual domain
    VITE_API_URL=https://yourdomain.com/api
    ```
  </Step>

  <Step title="Install dependencies">
    ```bash theme={null}
    # Backend
    cd /root/inspir/backend
    npm install --production

    # Frontend
    cd /root/inspir/frontend
    npm install
    ```
  </Step>

  <Step title="Build the frontend">
    ```bash theme={null}
    cd /root/inspir/frontend
    npm run build
    ```

    This creates an optimized production build in `dist/`.
  </Step>
</Steps>

## Step 3: Configure nginx

<Steps>
  <Step title="Create nginx configuration">
    Create a new site configuration:

    ```bash theme={null}
    sudo nano /etc/nginx/sites-available/inspir.conf
    ```

    Paste the following (replace `yourdomain.com` with your actual domain):

    ```nginx theme={null}
    server {
        listen 80;
        server_name yourdomain.com www.yourdomain.com;

        # Serve the built frontend
        root /var/www/inspir;
        index index.html;

        # Reverse proxy API requests to the backend
        location /api/ {
            proxy_pass http://127.0.0.1:3000/api/;
            proxy_http_version 1.1;
            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_set_header Connection "";
            proxy_read_timeout 90;
            client_max_body_size 15m;
        }

        # Single-page app routing
        location / {
            try_files $uri $uri/ /index.html;
        }

        # Enable gzip compression
        gzip on;
        gzip_types text/plain text/css application/json application/javascript application/ld+json application/xml text/xml image/svg+xml;
    }
    ```
  </Step>

  <Step title="Copy frontend build to web directory">
    ```bash theme={null}
    sudo mkdir -p /var/www/inspir
    sudo cp -r /root/inspir/frontend/dist/* /var/www/inspir/
    sudo chmod -R 755 /var/www/inspir
    ```
  </Step>

  <Step title="Enable the site">
    ```bash theme={null}
    sudo ln -s /etc/nginx/sites-available/inspir.conf /etc/nginx/sites-enabled/
    sudo nginx -t  # Test configuration
    sudo systemctl reload nginx
    ```
  </Step>
</Steps>

## Step 4: Set Up SSL with Let's Encrypt

<Steps>
  <Step title="Install Certbot">
    ```bash theme={null}
    sudo apt install certbot python3-certbot-nginx -y
    ```
  </Step>

  <Step title="Obtain SSL certificate">
    ```bash theme={null}
    sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
    ```

    Follow the prompts to:

    * Enter your email address
    * Agree to terms of service
    * Choose to redirect HTTP to HTTPS (recommended)
  </Step>

  <Step title="Verify auto-renewal">
    Certbot automatically sets up certificate renewal. Test it:

    ```bash theme={null}
    sudo certbot renew --dry-run
    ```
  </Step>
</Steps>

## Step 5: Start the Backend

### Option A: Using PM2 (Recommended)

<Steps>
  <Step title="Start the backend with PM2">
    ```bash theme={null}
    cd /root/inspir/backend
    pm2 start server.js --name inspir-backend
    pm2 save
    ```
  </Step>

  <Step title="Configure PM2 to start on boot">
    ```bash theme={null}
    pm2 startup
    # Follow the command it outputs
    pm2 save
    ```
  </Step>

  <Step title="Verify it's running">
    ```bash theme={null}
    pm2 status
    pm2 logs inspir-backend
    ```
  </Step>
</Steps>

### Option B: Using systemd

<Steps>
  <Step title="Create systemd service file">
    ```bash theme={null}
    sudo nano /etc/systemd/system/inspirquiz.service
    ```

    Paste the following:

    ```ini theme={null}
    [Unit]
    Description=InspirQuiz Backend Service
    After=network.target

    [Service]
    Type=simple
    WorkingDirectory=/root/inspir/backend
    Environment=NODE_ENV=production
    Environment=PORT=3000
    Environment=HOST=0.0.0.0
    EnvironmentFile=-/root/inspir/backend/.env
    ExecStart=/usr/bin/node /root/inspir/backend/server.js
    Restart=on-failure
    RestartSec=5
    User=root
    Group=root

    [Install]
    WantedBy=multi-user.target
    ```
  </Step>

  <Step title="Enable and start the service">
    ```bash theme={null}
    sudo systemctl daemon-reload
    sudo systemctl enable inspirquiz
    sudo systemctl start inspirquiz
    ```
  </Step>

  <Step title="Check service status">
    ```bash theme={null}
    sudo systemctl status inspirquiz
    sudo journalctl -u inspirquiz -f  # View logs
    ```
  </Step>
</Steps>

## Step 6: Verify Deployment

<Steps>
  <Step title="Test the website">
    Open [https://yourdomain.com](https://yourdomain.com) in your browser.

    * ✅ HTTPS should be enabled (green padlock)
    * ✅ Homepage should load
    * ✅ Sign up/login should work
  </Step>

  <Step title="Test the API">
    ```bash theme={null}
    curl https://yourdomain.com/api/health
    ```

    Should return a health check response.
  </Step>

  <Step title="Monitor logs">
    **PM2:**

    ```bash theme={null}
    pm2 logs inspir-backend
    ```

    **systemd:**

    ```bash theme={null}
    sudo journalctl -u inspirquiz -f
    ```
  </Step>
</Steps>

## Deployment Script

Create a script to automate future deployments:

```bash theme={null}
sudo nano /root/deploy.sh
```

Paste the following:

```bash theme={null}
#!/bin/bash

echo "🚀 Starting inspir deployment..."

# Navigate to project directory
cd /root/inspir || exit 1

# Pull latest code
echo "📥 Pulling latest code..."
git pull origin main

# Install backend dependencies
echo "📦 Installing backend dependencies..."
cd /root/inspir/backend
npm install --production

# Build the frontend
echo "📦 Building frontend..."
cd /root/inspir/frontend
npm install
npm run build

if [ $? -ne 0 ]; then
    echo "❌ Frontend build failed!"
    exit 1
fi

# Copy build to web directory
echo "📂 Copying build to web directory..."
sudo rm -rf /var/www/inspir/*
sudo cp -r dist/* /var/www/inspir/
sudo chmod -R 755 /var/www/inspir/

# Reload nginx
echo "🔄 Reloading nginx..."
sudo systemctl reload nginx

# Restart backend with PM2
echo "🔄 Restarting backend..."
cd /root/inspir/backend
pm2 restart inspir-backend || pm2 start server.js --name inspir-backend
pm2 save

echo "✅ Deployment complete!"
echo "🌐 Live at: https://yourdomain.com"
```

Make it executable:

```bash theme={null}
chmod +x /root/deploy.sh
```

Run future deployments with:

```bash theme={null}
/root/deploy.sh
```

## Security Best Practices

<Warning>
  Production security is critical. Follow these best practices:
</Warning>

### Firewall Configuration

```bash theme={null}
# Install ufw (Uncomplicated Firewall)
sudo apt install ufw

# Allow SSH, HTTP, HTTPS
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Enable firewall
sudo ufw enable
sudo ufw status
```

### Secure Environment Variables

```bash theme={null}
# Restrict .env file permissions
chmod 600 /root/inspir/backend/.env
chmod 600 /root/inspir/frontend/.env
```

### Keep Dependencies Updated

```bash theme={null}
# Check for vulnerabilities
cd /root/inspir/backend
npm audit
npm audit fix

cd /root/inspir/frontend
npm audit
npm audit fix
```

### Enable fail2ban (Optional)

Protect against brute-force attacks:

```bash theme={null}
sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
```

## Monitoring and Logs

### View Application Logs

**PM2:**

```bash theme={null}
pm2 logs inspir-backend
pm2 monit  # Live monitoring
```

**systemd:**

```bash theme={null}
sudo journalctl -u inspirquiz -f
sudo journalctl -u inspirquiz --since "1 hour ago"
```

### View nginx Logs

```bash theme={null}
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
```

### Monitor Server Resources

```bash theme={null}
htop  # Install: sudo apt install htop
df -h  # Disk usage
free -h  # Memory usage
```

## Troubleshooting

### 502 Bad Gateway

**Cause:** Backend is not running or unreachable.

**Fix:**

```bash theme={null}
# Check if backend is running
pm2 status  # or sudo systemctl status inspirquiz

# Restart backend
pm2 restart inspir-backend  # or sudo systemctl restart inspirquiz

# Check logs for errors
pm2 logs inspir-backend
```

### SSL Certificate Issues

**Renew certificate manually:**

```bash theme={null}
sudo certbot renew
sudo systemctl reload nginx
```

### Frontend Not Updating

**Clear build and redeploy:**

```bash theme={null}
cd /root/inspir/frontend
rm -rf dist node_modules
npm install
npm run build
sudo cp -r dist/* /var/www/inspir/
```

### Database Connection Errors

**Check Supabase project status:**

* Go to [Supabase Dashboard](https://supabase.com/dashboard)
* Verify project is not paused
* Check connection pooler settings

**Test connection from server:**

```bash theme={null}
curl -I https://xxxxxxxxxxx.supabase.co
```

## Backup Strategy

<Note>
  Regularly backup your environment variables and application data.
</Note>

### Backup Environment Variables

```bash theme={null}
cp /root/inspir/backend/.env /root/inspir/backend/.env.backup
cp /root/inspir/frontend/.env /root/inspir/frontend/.env.backup
```

### Backup Database

Supabase provides automatic backups. For manual backups:

1. Go to [Supabase Dashboard](https://supabase.com/dashboard)
2. Navigate to **Database** → **Backups**
3. Download manual backup or use `pg_dump` via connection string

## Next Steps

Your production deployment is complete! Consider:

* Setting up monitoring (e.g., UptimeRobot, Datadog)
* Configuring automated backups
* Setting up CI/CD for automated deployments
* Adding a CDN (e.g., Cloudflare) for better performance

[Database Setup →](/deployment/database-setup)
