Skip to content

Nginx Reverse Proxy & Vhosts

The Nginx reverse proxy container (vps-proxy) acts as the single unified ingress point on ports 80 (HTTP) and 443 (HTTPS) for all domains and subdomains managed on the Hostinger VPS.


🏛️ Ingress Architecture

Nginx terminates TLS with Cloudflare 15-year certificates, validates client certificates for IoT telemetry (mTLS), enforces IP whitelisting for administration paths, and forwards requests across the Docker bridge network (vps-network).

/opt/vps-stack/proxy/
├── nginx.conf # Master Nginx configuration
├── allowed_ips.conf # Dynamic IP whitelist rules
├── kong.yml # Declarative Kong routing definitions
├── conf.d/ # Virtual host definitions (*.conf)
│ ├── apps.conf # Webpage, Microservices, Flutter Web vhosts
│ ├── converters.conf # Converter FastAPI backends (cloud.planovi.app)
│ ├── docs.conf # Documentation portal reverse proxy to Cloudflare Pages
│ └── supabase.conf # Kong, Auth, Studio, and Telemetry vhosts
└── html/ # Custom branded error pages
├── 404.html # 404 Not Found template
├── 50x.html # 500 / 502 / 503 / 504 Error template
└── default.html # Default root fallback landing page

🌐 Virtual Host Configuration Catalog

1. Supabase Services (supabase.conf)

  • api.planovi.app & dev-api.planovi.app:
    • Standard REST/GraphQL/Auth API routed to Kong (supabase-kong:8000).
    • /deploy-webhook location proxied to the CI/CD service (vps-deployer:9000).
  • supabase-studio.planovi.app & dev-supabase-studio.planovi.app:
    • Protected with include /etc/nginx/allowed_ips.conf;.
    • Proxied to supabase-studio:3000.
  • telemetry.planovi.app & dev-telemetry.planovi.app:
    • Configured with ssl_verify_client on; and ssl_client_certificate /etc/ssl/cloudflare/planovi-device-ca.pem;.
    • Forwards authenticated payloads directly to supabase-edge-runtime:9000.

2. Client Web Applications (apps.conf)

  • planovi.app & www.planovi.app: Static HTML/JS marketing website served from /opt/vps-apps/webpage/prod.
  • dev.planovi.app: Staging marketing website served from /opt/vps-apps/webpage/dev.
  • dealflow.planovi.app & scheduler.planovi.app: Reverse proxied to php-app:80 (FastCGI PHP 8.3 FPM).
  • panel.planovi.app & dev-panel.planovi.app: Flutter Web single page applications proxied to flutter-web:80 with SPA HTML5 fallback (try_files $uri $uri/ /index.html;).

3. Converter Backends (converters.conf)

  • cloud.planovi.app: Proxied to Python FastAPI container converters-api-prod:8000.
  • dev-cloud.planovi.app: Proxied to Python FastAPI container converters-api-dev:8000.

4. Docs Portal (docs.conf)

  • docs.planovi.app & dev-docs.planovi.app:
    • Protected by dynamic IP whitelist (allowed_ips.conf).
    • Reverse proxies to Cloudflare Pages static edge deployments (dev-docs-arq.pages.dev).
    • Uses dynamic DNS resolvers (resolver 1.1.1.1 8.8.8.8 valid=300s;) to avoid startup halts if DNS propagates asynchronously.

🎨 Branded Error Pages (html/)

When backends encounter upstream failures (e.g. during a service rebuild), Nginx intercepts error codes:

error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;

These responsive HTML files offer user-friendly messaging styled with Planovi dark mode theme, contact links, and automatic retry diagnostics.


⚡ Zero-Downtime Reload

Whenever vhosts or whitelist rules are adjusted:

Terminal window
# Test Nginx configuration syntax
docker exec vps-proxy nginx -t
# Hot-reload configuration without dropping active TCP connections
docker exec vps-proxy nginx -s reload