# Deployment Guide

Complete setup for deploying the portfolio site with various web servers.

## Architecture Options

### Option A: Static Build (Recommended for Production)
```
Cloudflare → VPS (Apache/lighttpd/Caddy) → dist/ (static files)
```

### Option B: Vite Dev Server (Development)
```
Cloudflare → VPS (Caddy) → Vite Dev Server (port 5173)
```

## Quick Start: Static Build

The simplest and most efficient approach:

```bash
cd /opt/peters-portfolio-site
git pull
npm install
npm run build
# Now serve the dist/ folder with any web server
```

## Option 1: Apache2

### Install Apache

```bash
sudo apt update
sudo apt install apache2
sudo systemctl enable apache2
```

### Build and Deploy

```bash
cd /opt/peters-portfolio-site
npm install
npm run build

# Copy docs to dist for serving
cp -r public/docs dist/

# Deploy to Apache
sudo rm -rf /var/www/pwlmyers.org/*
sudo cp -r dist/* /var/www/pwlmyers.org/
sudo chown -R www-data:www-data /var/www/pwlmyers.org
```

### Apache Configuration

Create `/etc/apache2/sites-available/pwlmyers.org.conf`:

```apache
<VirtualHost *:80>
    ServerName pwlmyers.org
    ServerAlias www.pwlmyers.org
    DocumentRoot /var/www/pwlmyers.org
    
    # Enable rewrite for SPA routing
    <Directory /var/www/pwlmyers.org>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
        
        # Handle client-side routing
        RewriteEngine On
        RewriteBase /
        RewriteRule ^index\.html$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.html [L]
    </Directory>
    
    # Enable compression
    <IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
        AddOutputFilterByType DEFLATE application/javascript application/json
    </IfModule>
    
    # Cache static assets
    <IfModule mod_expires.c>
        ExpiresActive On
        ExpiresByType image/png "access plus 1 month"
        ExpiresByType image/jpeg "access plus 1 month"
        ExpiresByType text/css "access plus 1 week"
        ExpiresByType application/javascript "access plus 1 week"
    </IfModule>
    
    ErrorLog ${APACHE_LOG_DIR}/pwlmyers-error.log
    CustomLog ${APACHE_LOG_DIR}/pwlmyers-access.log combined
</VirtualHost>
```

Enable the site:
```bash
sudo a2ensite pwlmyers.org.conf
sudo a2enmod rewrite deflate expires headers
sudo systemctl restart apache2
```

### SSL with Certbot

```bash
sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d pwlmyers.org
```

## Option 2: lighttpd

### Install lighttpd

```bash
sudo apt update
sudo apt install lighttpd
sudo systemctl enable lighttpd
```

### Build and Deploy

```bash
cd /opt/peters-portfolio-site
npm install
npm run build
cp -r public/docs dist/

sudo mkdir -p /var/www/pwlmyers.org
sudo rm -rf /var/www/pwlmyers.org/*
sudo cp -r dist/* /var/www/pwlmyers.org/
sudo chown -R www-data:www-data /var/www/pwlmyers.org
```

### lighttpd Configuration

Edit `/etc/lighttpd/lighttpd.conf` or create `/etc/lighttpd/conf-available/99-pwlmyers.conf`:

```lighttpd
server.document-root = "/var/www/pwlmyers.org"
server.port = 80
server.bind = "0.0.0.0"
server.tag = "lighttpd"

# Server name
server.name = "pwlmyers.org"

# Index file
index-file.names = ( "index.html" )

# MIME types
mimetype.assign = (
    ".html" => "text/html",
    ".htm"  => "text/html",
    ".css"  => "text/css",
    ".js"   => "application/javascript",
    ".json" => "application/json",
    ".png"  => "image/png",
    ".jpg"  => "image/jpeg",
    ".jpeg" => "image/jpeg",
    ".gif"  => "image/gif",
    ".svg"  => "image/svg+xml",
    ".ico"  => "image/x-icon",
    ".pdf"  => "application/pdf",
    ".pptx" => "application/vnd.openxmlformats-officedocument.presentationml.presentation",
    ".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
)

# Enable mod_rewrite for SPA routing
server.modules += ( "mod_rewrite" )
url.rewrite-if-not-file = (
    "^/(.*)$" => "/index.html"
)

# Enable compression
server.modules += ( "mod_deflate" )
deflate.mimetypes = ( "text/html", "text/plain", "text/css", "application/javascript" )
deflate.allowed-encodings = ( "gzip", "deflate" )

# Security headers
server.modules += ( "mod_setenv" )
setenv.add-response-header += (
    "X-Frame-Options" => "SAMEORIGIN",
    "X-Content-Type-Options" => "nosniff",
    "X-XSS-Protection" => "1; mode=block",
    "Referrer-Policy" => "strict-origin-when-cross-origin"
)

# Logging
server.errorlog = "/var/log/lighttpd/error.log"
accesslog.filename = "/var/log/lighttpd/access.log"

# File upload limits (for large PPTX/PDF files)
server.max-request-size = 104857600  # 100MB
```

Enable and restart:
```bash
sudo lighty-enable-mod pwlmyers
sudo systemctl restart lighttpd
```

### SSL with Certbot

```bash
sudo apt install certbot
sudo certbot certonly --standalone -d pwlmyers.org
```

Then configure lighttpd for SSL (see certbot output for paths).

## Option 3: Caddy (Static Files)

### Build

```bash
cd /opt/peters-portfolio-site
npm install
npm run build
cp -r public/docs dist/
```

### Caddyfile

```caddy
pwlmyers.org {
    root * /opt/peters-portfolio-site/dist
    file_server
    try_files {path} {path}/ /index.html
    
    # Handle docs directory
    handle /docs/* {
        uri strip_prefix /docs
        root * /opt/peters-portfolio-site/dist/docs
        file_server
    }
    
    log {
        output file /var/log/caddy/access.log
    }
}
```

## Option 4: Nginx

### Install Nginx

```bash
sudo apt install nginx
sudo systemctl enable nginx
```

### Build

```bash
cd /opt/peters-portfolio-site
npm install
npm run build
cp -r public/docs dist/
```

### Nginx Configuration

Create `/etc/nginx/sites-available/pwlmyers.org`:

```nginx
server {
    listen 80;
    server_name pwlmyers.org www.pwlmyers.org;
    root /var/www/pwlmyers.org;
    index index.html;
    
    # Gzip compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml;
    
    # Cache static assets
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf)$ {
        expires 1M;
        add_header Cache-Control "public, immutable";
    }
    
    # Serve docs correctly
    location /docs/ {
        alias /var/www/pwlmyers.org/docs/;
        autoindex off;
    }
    
    # SPA routing - serve index.html for all non-file routes
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    
    # File upload size (for docs)
    client_max_body_size 100M;
}
```

Enable:
```bash
sudo ln -s /etc/nginx/sites-available/pwlmyers.org /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default  # Remove default
sudo nginx -t
sudo systemctl restart nginx
```

## Updating Static Build

Create a deploy script `/opt/peters-portfolio-site/deploy.sh`:

```bash
#!/bin/bash
set -e

cd /opt/peters-portfolio-site

echo "Pulling latest changes..."
git pull

echo "Installing dependencies..."
npm install

echo "Building..."
npm run build

echo "Copying docs..."
cp -r public/docs dist/

echo "Deploying to web server..."
# For Apache:
sudo rm -rf /var/www/pwlmyers.org/*
sudo cp -r dist/* /var/www/pwlmyers.org/
sudo chown -R www-data:www-data /var/www/pwlmyers.org

# For lighttpd:
# sudo rm -rf /var/www/pwlmyers.org/*
# sudo cp -r dist/* /var/www/pwlmyers.org/
# sudo chown -R www-data:www-data /var/www/pwlmyers.org
# sudo systemctl restart lighttpd

echo "Done!"
```

Make executable:
```bash
chmod +x /opt/peters-portfolio-site/deploy.sh
```

## Comparison

| Server | RAM Usage | Ease of Config | SSL | Best For |
|--------|-----------|----------------|-----|----------|
| Apache | High | Medium | Certbot | Complex setups |
| Nginx | Low | Medium | Certbot | High traffic |
| lighttpd | Very Low | Easy | Manual | Resource constrained |
| Caddy | Low | Very Easy | Auto | Simplicity |

## Troubleshooting

### 404 on refresh (SPA routing)

Ensure rewrite rules are configured to serve `index.html` for non-file paths.

### Docs not downloading

Check MIME types are configured for `.pptx`, `.docx`, `.pdf`.

### Permission denied

```bash
sudo chown -R www-data:www-data /var/www/pwlmyers.org
sudo chmod -R 755 /var/www/pwlmyers.org
```

### Check logs

```bash
# Apache
sudo tail -f /var/log/apache2/pwlmyers-error.log

# lighttpd
sudo tail -f /var/log/lighttpd/error.log

# Nginx
sudo tail -f /var/log/nginx/error.log
```

## Prerequisites

All options require:
- Domain pointing to VPS (A record)
- Ports 80/443 open in Oracle Cloud security list
- Node.js 20.19+ for building

See [README.md](README.md) for development setup.
