Files
proxmox/docs/04-configuration/MIM4U_502_ERROR_RESOLUTION.md
defiQUG 4f97e27f69
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
MIM4U: nginx install/deploy/backup scripts, rate limit, CSP, docs; submodule pointer; txpool retry script
Made-with: Cursor
2026-02-26 22:35:24 -08:00

5.9 KiB
Raw Blame History

MIM4U 502 Error Resolution Guide

Last Updated: 2026-01-31
Document Version: 1.0
Status: Active Documentation


Date: 2026-01-18
Issue: https://mim4u.org/ returns HTTP 502 Bad Gateway
Status: ⚠️ RESOLUTION IN PROGRESS


Root Cause Analysis

Current Situation

  1. VMID 7810 (mim-web-1) @ 192.168.11.37:

    • Container is running
    • nginx is NOT installed
    • No web service on port 80
  2. VMID 7811 (mim-api-1) @ 192.168.11.36:

    • Container is running
    • No web service on port 80
    • Port 80 not accessible
  3. NPMplus Configuration:

    • ⚠️ Likely routing to old IP (192.168.11.36) OR
    • ⚠️ Routing to 192.168.11.37 but no service responding

502 Error Explanation

HTTP 502 Bad Gateway means:

  • NPMplus received the request
  • NPMplus tried to proxy to backend (192.168.11.36 or 192.168.11.37)
  • Backend service is not responding or not accessible

Solution Steps

Step 1: Install nginx on VMID 7810

The container needs nginx installed and running to serve the web application.

Option A — run the fix script (recommended): From a host that can SSH to the Proxmox node (r630-02):

./scripts/mim4u-install-nginx-and-fix-502.sh
# Or dry-run: ./scripts/mim4u-install-nginx-and-fix-502.sh --dry-run

The script installs nginx, writes the security-enabled config (including rate limits in /etc/nginx/conf.d/mim4u-rate-limit.conf and the default site), ensures /var/www/html exists, and reloads nginx.

Option B — manual steps:

# SSH to Proxmox host
ssh root@192.168.11.12

# Install nginx in container
pct exec 7810 -- bash -c 'export DEBIAN_FRONTEND=noninteractive && apt-get update && apt-get install -y nginx'

# Start nginx
pct exec 7810 -- systemctl enable nginx
pct exec 7810 -- systemctl start nginx

# Verify
curl -I http://192.168.11.37:80/

Step 2: Verify NPMplus Routing

Check what IP NPMplus is routing to:

  1. Access NPMplus Web UI:

    • URL: https://192.168.0.166:81 or https://192.168.11.166:81
    • Navigate to: Proxy Hosts → mim4u.org (and www.mim4u.org)
  2. Verify Configuration:

    • Forward Hostname/IP: Should be 192.168.11.37
    • Forward Port: Should be 80
    • Forward Scheme: Should be http
    • www.mim4u.org: Same backend so both apex and www work. Optional: create a Redirect host for www.mim4u.orghttps://mim4u.org in NPMplus to canonicalize to apex.
  3. Security (HSTS / SSL):

    • Enable SSL and Force SSL for mim4u.org (and www, secure, training) so HTTPS is used.
    • Enable HSTS in the proxy hosts SSL tab so browsers get Strict-Transport-Security. NPMplus adds the header when terminating SSL.

Step 3: Deploy MIM4U Web Application (When Ready)

Once nginx is running, deploy the actual MIM4U web application:

  • Application files go in: /opt/miracles-in-motion/dist (or configured path)
  • Nginx config: /etc/nginx/sites-available/miracles-in-motion
  • nginx should serve static files and proxy /api/* to VMID 7811

Quick Fix (Temporary)

If you need the site working immediately, you can:

  1. Install nginx on VMID 7810 (see Step 1 above)
  2. Configure basic nginx to serve a default page:
# Basic nginx config (temporary) — server_name includes www so www.mim4u.org works; security headers (HSTS when on HTTPS via NPMplus, CSP)
pct exec 7810 -- bash -c 'cat > /etc/nginx/sites-available/default << EOF
server {
    listen 80;
    server_name mim4u.org www.mim4u.org secure.mim4u.org training.mim4u.org _;
    root /var/www/html;
    index index.html;

    # Security headers (HSTS added by NPMplus when terminating SSL; CSP reduces XSS)
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Content-Security-Policy "default-src '\''self'\''; script-src '\''self'\'' '\''unsafe-inline'\'' '\''unsafe-eval'\''; style-src '\''self'\'' '\''unsafe-inline'\'' https://fonts.googleapis.com; font-src '\''self'\'' https://fonts.gstatic.com; img-src '\''self'\'' data: https:; connect-src '\''self'\'' https://mim4u.org; frame-ancestors '\''self'\'';" always;
    
    location / {
        try_files \$uri \$uri/ /index.html =404;
    }
    
    location /api/ {
        proxy_pass http://192.168.11.36:3001;
        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;
    }
}
EOF'

pct exec 7810 -- nginx -t && pct exec 7810 -- systemctl reload nginx

This will at least allow nginx to respond and stop the 502 error.


Complete Deployment

For full MIM4U deployment, see:

  • scripts/deploy-miracles-in-motion-pve2.sh - Full deployment script
  • docs/archive/completion/MIRACLES_IN_MOTION_DEPLOYMENT_COMPLETE.md - Deployment guide

Verification

After fixes:

# Test direct IP access
curl -I http://192.168.11.37:80/

# Test public domain (after NPMplus update)
curl -I https://mim4u.org/

Expected: HTTP 200 (not 502)


Optional: Rate limiting for /api/

To rate-limit /api/ at nginx, the limit_req_zone directive must live in the http block (e.g. in /etc/nginx/nginx.conf), not in the server block. Example:

# In http { ... } in nginx.conf
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=30r/m;

Then in your server block (or in the snippet above), inside location /api/ add:

limit_req zone=api_limit burst=5 nodelay;

Alternatively, use Cloudflare WAF rate limiting in front of mim4u.org (see CLOUDFLARE_SETUP).


Last Updated: 2026-01-18
Status: ⚠️ nginx installation needed on VMID 7810