voxblog/CADDY_SETUP.md
Ender f160b26564
Some checks are pending
Deploy to Production / deploy (push) Waiting to run
feat: update service ports from 3000/3001 to 3300/3301
- Changed admin frontend port from 3000 to 3300 across all configuration files
- Changed API backend port from 3001 to 3301 across all configuration files
- Updated health check endpoints to use new ports in CI/CD workflow
- Modified documentation and deployment guides to reflect new port numbers
- Updated Caddy and Nginx reverse proxy configurations to use new ports
2025-10-26 00:25:40 +02:00

5.5 KiB

Caddy Setup for VoxBlog (Multi-App VPS)

Why Caddy is Great! 🎉

Automatic HTTPS - SSL certificates managed automatically
Simple config - Much easier than Nginx
Auto-renewal - Certificates renew automatically
Modern - HTTP/2, HTTP/3 support built-in

Quick Setup (3 Steps!)

1. Configure DNS

Add DNS record:

A Record: voxblog.yourdomain.com → your-vps-ip

2. Add to Your Caddyfile

On your VPS, edit your existing Caddyfile:

sudo nano /etc/caddy/Caddyfile

Add this configuration (from the Caddyfile in this repo):

admin.pusula.blog {
    # Frontend
    handle / {
        reverse_proxy localhost:3300
    }

    # API
    handle /api* {
        reverse_proxy localhost:3301
    }

    encode gzip

    header {
        X-Frame-Options "SAMEORIGIN"
        X-Content-Type-Options "nosniff"
        X-XSS-Protection "1; mode=block"
    }

    log {
        output file /var/log/caddy/voxblog-access.log
    }
}

Important: Replace voxblog.yourdomain.com with your actual domain!

3. Reload Caddy

# Test configuration
sudo caddy validate --config /etc/caddy/Caddyfile

# Reload Caddy
sudo systemctl reload caddy

# Check status
sudo systemctl status caddy

4. Update .env on VPS

cd /path/to/voxblog
nano .env

Add:

VITE_API_URL=https://voxblog.yourdomain.com/api

5. Deploy

./deploy.sh

That's It! 🎉

Caddy will automatically:

  • Get SSL certificate from Let's Encrypt
  • Redirect HTTP to HTTPS
  • Renew certificates automatically
  • Handle HTTP/2 and HTTP/3

Access Your App

  • Frontend: https://voxblog.yourdomain.com
  • API: https://voxblog.yourdomain.com/api

Your Existing Apps

Your Caddyfile probably looks like this:

# Existing app 1
app1.yourdomain.com {
    reverse_proxy localhost:4000
}

# Existing app 2
app2.yourdomain.com {
    reverse_proxy localhost:5000
}

# Add VoxBlog
voxblog.yourdomain.com {
    handle / {
        reverse_proxy localhost:3300
    }
    handle /api* {
        reverse_proxy localhost:3301
    }
    encode gzip
}

All apps coexist perfectly! 🚀

Troubleshooting

Check Caddy Status

sudo systemctl status caddy

View Caddy Logs

sudo journalctl -u caddy -f
sudo tail -f /var/log/caddy/voxblog-access.log

Test Configuration

sudo caddy validate --config /etc/caddy/Caddyfile

Reload After Changes

sudo systemctl reload caddy

Check if Ports are Accessible

# From VPS (should work)
curl http://localhost:3300
curl http://localhost:3301/api/health

# From internet (should work via domain)
curl https://voxblog.yourdomain.com
curl https://voxblog.yourdomain.com/api/health

502 Bad Gateway

# Check if containers are running
docker-compose ps

# Check if ports are accessible
curl http://localhost:3300
curl http://localhost:3301/api/health

# Check Caddy logs
sudo journalctl -u caddy -f

Certificate Issues

Caddy handles this automatically, but if you have issues:

# Check Caddy logs for certificate errors
sudo journalctl -u caddy | grep -i cert

# Make sure port 443 is open
sudo ufw status

# Restart Caddy
sudo systemctl restart caddy

Advanced: Separate Subdomains

If you prefer separate subdomains for frontend and API:

# Frontend
voxblog.yourdomain.com {
    reverse_proxy localhost:3300
    encode gzip
}

# API
api.voxblog.yourdomain.com {
    reverse_proxy localhost:3301
    encode gzip
}

Then update .env:

VITE_API_URL=https://api.voxblog.yourdomain.com

Caddy vs Nginx

Feature Caddy Nginx
SSL Setup Automatic Manual (certbot)
Config Simple Complex
HTTP/3 Built-in Requires module
Cert Renewal Automatic Cron job needed
Learning Curve Easy Steep

Caddy is perfect for your use case! 🎉

Complete Example Caddyfile

# Global options
{
    email your-email@example.com
}

# Existing apps
app1.yourdomain.com {
    reverse_proxy localhost:4000
}

app2.yourdomain.com {
    reverse_proxy localhost:5000
}

# VoxBlog
voxblog.yourdomain.com {
    # Frontend
    handle / {
        reverse_proxy localhost:3300
    }

    # API with long timeout for AI streaming
    handle /api* {
        reverse_proxy localhost:3301 {
            transport http {
                read_timeout 600s
                write_timeout 600s
            }
        }
    }

    encode gzip

    header {
        X-Frame-Options "SAMEORIGIN"
        X-Content-Type-Options "nosniff"
        X-XSS-Protection "1; mode=block"
        Referrer-Policy "strict-origin-when-cross-origin"
    }

    log {
        output file /var/log/caddy/voxblog-access.log {
            roll_size 100mb
            roll_keep 5
        }
    }
}

Quick Reference

# Validate config
sudo caddy validate --config /etc/caddy/Caddyfile

# Reload Caddy
sudo systemctl reload caddy

# Restart Caddy
sudo systemctl restart caddy

# Check status
sudo systemctl status caddy

# View logs
sudo journalctl -u caddy -f

# View access logs
sudo tail -f /var/log/caddy/voxblog-access.log

Benefits for Multi-App VPS

Simple - Just add a new block for each app
Automatic SSL - No manual certificate management
No port conflicts - All apps share 80/443
Secure - App ports not exposed to internet
Professional - Production-ready setup


Caddy makes this incredibly easy! Just add the config and reload. SSL is handled automatically. 🚀