Skip to main content
Development preview — this is not a live application; it is still being built.
ProxmoxVEx
↑ ↓ to navigate Enter to open

Deploying the ProxmoxVEx Demo Sandbox

The demo is a sandboxed instance of the production image that serves

The demo is a sandboxed instance of the production image that serves synthetic cluster/VM/metrics data and blocks every mutating API call. It backs the Launch Demo CTA on the marketing site (proxmoxvex-landing).

How it works

  • PROXMOXVEX_DEMO_MODE=true switches the app into demo mode at startup:
    • ProxmoxVEx/demo/seed.py provisions the demo user (flagged is_demo=1, auth_source='demo'), a synthetic demo cluster, alert rules, migration history, and mock PBS/vCenter/NetApp records.
    • ProxmoxVEx/demo/cluster_mock.py intercepts the cluster manager so host='demo' is answered from fixtures/demo/*.json — no real hypervisor is ever contacted.
    • ProxmoxVEx/demo/guard.py installs a before_request hook that rejects every mutating /api/* call with 403 {"error": "demo_forbidden"} except a small allow-list (login/logout, demo token exchange, health, SSE token, preferences).
  • Public entry points:
    • GET /api/demo/auto-login — one-click entry; issues a single-use signed token, creates a session for the demo user, redirects to /.
    • GET /api/demo/token + POST /api/demo/login — token exchange flow.
    • GET /api/health returns demo_mode, mode, reset_in_seconds and capacity when demo mode is active.
    • GET /api/config returns demo_mode, demo_read_only and demo_reset_in_seconds so the UI can render the banner and disable destructive actions.

Running locally

docker compose -f docker-compose.yml -f docker-compose.demo-override.yml up --build -d

The demo listens on the normal app port; point the landing page at it via PUBLIC_DEMO_ORIGIN.

Environment variables

Variable Default Purpose
PROXMOXVEX_DEMO_MODE false Enables the sandbox.
PROXMOXVEX_DEMO_TOKEN_SECRET demo-local-secret HMAC secret for demo launch tokens. Set a real random value in production.
PROXMOXVEX_DEMO_RESET_INTERVAL 900 Seconds between automatic resets (reset sidecar SIGTERMs the app container; Postgres volume is re-seeded on boot).
PROXMOXVEX_DEMO_ALLOWED_ORIGINS landing origins CORS allow-list so the landing page can query /api/health.

Isolation and security

  • The demo stack runs on a dedicated proxmoxvex-demo compose network with its own postgres-demo service and anonymous volume; no production volumes, TLS material, or config/ contents are mounted.
  • All mutating API routes are blocked server-side; the demo account’s read coverage comes from its role while the guard — not RBAC — enforces read-only behaviour.
  • Demo launch tokens are HMAC-signed, short-lived and single-use (ProxmoxVEx/demo/token.py).
  • The standard security headers (CSP, X-Frame-Options, Referrer-Policy, HSTS behind TLS) apply unchanged; CORS is limited to PROXMOXVEX_ALLOWED_ORIGINS.
  • DEMO_SEED_VERSION in ProxmoxVEx/demo/__init__.py tracks the synthetic dataset revision; bump it whenever fixtures/demo/ or the seed data changes so resets re-seed cleanly.

Production deployment

scripts/deploy-demo.sh and the pipeline build the image, set PROXMOXVEX_IMAGE_TAG, and bring the stack up behind the pmvexdemo.* tunnel. The demo-smoke job in .github/workflows/docker.yml runs scripts/demo-smoke.sh to verify /api/health reports demo_mode=true on every release.

Verification

  • Contract/unit tests: pytest tests/unit tests/contract -q (test_demo_token.py, test_demo_blocklist.py, test_demo_health.py, test_demo_guard.py).
  • E2E: cd proxmoxvex-landing && npx playwright test — the demo-sandbox/demo-reset specs require DEMO_ORIGIN pointing at a running sandbox.

Was this page helpful?

ProxmoxVEx Source-Available License
Checking status…

© 2025-2026 ProxmoxVEx contributors