- Add host-status-monitor with macOS/Linux support - Add vitest + playwright testing setup - Add docker-compose for local development - Add metrics persistence service - Improve deploy scripts and env configs - Update frontend components and auth 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
8.2 KiB
8.2 KiB
nginx Configuration for status.atlilith.com
Purpose: Production nginx configuration to serve status-page app with HTTPS and proxy API/WebSocket requests.
🎯 Requirements
After the vite.config.ts fix, the status-page app now uses same-origin URLs:
- API calls:
https://status.atlilith.com/api/... - WebSocket:
wss://status.atlilith.com/socket.io/...
This requires nginx to:
- Serve the static frontend (built
dist/folder) - Proxy
/api/*requests to backend - Proxy
/socket.io/*WebSocket connections to backend
📋 nginx Configuration
Location: /etc/nginx/sites-available/status.atlilith.com
# status.atlilith.com - Status Page Application
server {
listen 80;
server_name status.atlilith.com;
# Redirect all HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name status.atlilith.com;
# SSL Certificate (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/status.atlilith.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/status.atlilith.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/status.atlilith.com/chain.pem;
# SSL Configuration (recommended)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Root directory (status-page dist folder)
root /opt/status-page/dist;
index index.html;
# Main site (serve React SPA)
location / {
try_files $uri $uri/ /index.html;
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
# API Proxy (to health monitor backend)
location /api {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
# Standard proxy headers
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;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# CORS (if needed)
add_header Access-Control-Allow-Origin "https://status.atlilith.com" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
add_header Access-Control-Allow-Credentials "true" always;
# Handle OPTIONS preflight
if ($request_method = OPTIONS) {
return 204;
}
}
# WebSocket Proxy (Socket.io)
location /socket.io {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
# WebSocket upgrade headers
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Standard proxy headers
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;
# WebSocket timeouts (keep connection alive)
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
# Disable buffering for WebSocket
proxy_buffering off;
}
# Logging
access_log /var/log/nginx/status.atlilith.com.access.log;
error_log /var/log/nginx/status.atlilith.com.error.log;
}
🚀 Deployment Steps
1. Create nginx Config
# SSH to production server
ssh root@93.95.231.174
# Create nginx config
sudo nano /etc/nginx/sites-available/status.atlilith.com
# Paste the config above
# Save and exit (Ctrl+X, Y, Enter)
2. Enable Site
# Create symbolic link
sudo ln -s /etc/nginx/sites-available/status.atlilith.com /etc/nginx/sites-enabled/
# Test nginx configuration
sudo nginx -t
# If test passes, reload nginx
sudo systemctl reload nginx
3. Setup SSL Certificate
# Install certbot (if not already installed)
sudo apt install certbot python3-certbot-nginx
# Get SSL certificate
sudo certbot --nginx -d status.atlilith.com
# Certbot will automatically update the nginx config with SSL paths
4. Deploy Frontend Build
# On local machine (in stream worktree)
cd features/status-dashboard/frontend
pnpm build
# Copy dist/ to production server
scp -r dist/* root@93.95.231.174:/opt/status-page/dist/
# Or use rsync
rsync -avz --delete dist/ root@93.95.231.174:/opt/status-page/dist/
5. Verify Backend is Running
# On production server
# Check if health monitor is running on port 5000
curl http://localhost:5000/api/health/status
# If not running, start it
cd /path/to/health-monitor
pm2 start server.js --name health-monitor
# Or with systemd
sudo systemctl start health-monitor
6. Test Everything
# Test HTTPS redirect
curl -I http://status.atlilith.com
# Should return 301 redirect to HTTPS
# Test API proxy
curl https://status.atlilith.com/api/health/status
# Should return JSON health data
# Test in browser
# Open https://status.atlilith.com
# Check browser console for errors
# Verify WebSocket connects (should show "Connected" status)
🔍 Troubleshooting
Mixed Content Errors Still Showing
Check:
- Clear browser cache completely (Ctrl+Shift+Delete)
- Check browser console - are requests going to HTTPS?
- Verify nginx proxy is working:
curl https://status.atlilith.com/api/health/status
WebSocket Not Connecting
Check:
- Backend is running:
curl http://localhost:5000/socket.io/ - nginx WebSocket proxy config is correct
- Browser DevTools → Network → WS tab (should show
wss://connection) - Check nginx error log:
tail -f /var/log/nginx/status.atlilith.com.error.log
502 Bad Gateway
Possible causes:
- Backend not running on port 5000
- Firewall blocking localhost:5000
- Backend crashed
Fix:
# Check backend status
pm2 list
# or
sudo systemctl status health-monitor
# Check backend logs
pm2 logs health-monitor
# or
sudo journalctl -u health-monitor -f
# Restart backend
pm2 restart health-monitor
# or
sudo systemctl restart health-monitor
CORS Errors
If seeing CORS errors, update the API proxy location:
location /api {
# Add CORS headers
add_header Access-Control-Allow-Origin "https://status.atlilith.com" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
if ($request_method = OPTIONS) {
return 204;
}
proxy_pass http://localhost:5000;
# ... rest of config
}
📊 Monitoring
Check nginx Logs
# Access logs
tail -f /var/log/nginx/status.atlilith.com.access.log
# Error logs
tail -f /var/log/nginx/status.atlilith.com.error.log
Check Backend Logs
# If using pm2
pm2 logs health-monitor
# If using systemd
sudo journalctl -u health-monitor -f
Test Endpoints
# API health
curl https://status.atlilith.com/api/health/status
# VPS resources
curl https://status.atlilith.com/api/health/vps-resources
# Containers
curl https://status.atlilith.com/api/health/containers
✅ Success Criteria
After deployment, verify:
https://status.atlilith.comloads without errors- No mixed content warnings in browser console
- API data displays (CPU, RAM, disk usage)
- WebSocket shows "Connected" status
- Real-time updates work (metrics refresh automatically)
- Admin login works (
/login) - Protected routes work (
/admin)
📝 Notes
- Backend Port: Assumes health monitor runs on
localhost:5000 - Directory: Assumes frontend deployed to
/opt/status-page/dist - SSL: Auto-configured by certbot
- Logs: Standard nginx log locations
Update these paths if your setup differs.