- Added .dockerignore to exclude unnecessary files from Docker builds - Enhanced .env.example with detailed configuration options and added MySQL settings - Created Gitea CI/CD workflow for automated production deployment with health checks - Added comprehensive Caddy server setup guide and configuration for reverse proxy - Created Caddyfile with secure defaults for SSL, compression, and security headers The changes focus on setting up a production-
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:3000
}
# API
handle /api* {
reverse_proxy localhost:3001
}
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:3000
}
handle /api* {
reverse_proxy localhost:3001
}
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:3000
curl http://localhost:3001/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:3000
curl http://localhost:3001/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:3000
encode gzip
}
# API
api.voxblog.yourdomain.com {
reverse_proxy localhost:3001
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:3000
}
# API with long timeout for AI streaming
handle /api* {
reverse_proxy localhost:3001 {
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. 🚀