SELF_HOSTED_MODE indicates deployment mode to the plan-mode edge function (used for UI messaging only). It does not disable plan limits. Unlimited operations are achieved by setting the tenant’s plan field in the database to enterprise with null limit columns — the app treats null as unlimited. Valid plan values are: free, pro, premium, enterprise.
# Run container with your runtime VITE_* configuration
dockerrun-d\
-p80:80\
--nameeryxon-flow\
--restartunless-stopped\
--env-file.env\
ghcr.io/sheetmetalconnect/eryxon-flow:latest
The shipped image reads your VITE_* variables at container start and writes them to /env.js, so you can point the same image at your own Supabase project without rebuilding it.
The repository ships with a ready-to-use docker-compose.yml. In the current v0.6 repo, this is the single self-hosted Docker entry point and it already reads .env through env_file.
Terminal window
dockercomposeup-d
To build your own image instead of using ghcr.io/sheetmetalconnect/eryxon-flow:latest, replace the image line in docker-compose.yml with a build block:
The repo no longer uses a separate docker-compose.prod.yml. For HTTPS in the current v0.6 line, stay on the shipped docker-compose.yml and enable the optional Caddy service that is already commented into that file:
Uncomment the caddy service and the volumes: block in docker-compose.yml
Change the eryxon-flow service from ports: ["80:80"] to expose: ["80"]
Edit the included Caddyfile
Start the stack with docker compose up -d
The shipped Caddyfile supports two real deployment modes:
a public hostname with automatic Let’s Encrypt certificates
a LAN-only rollout with Caddy tls internal, a .local host, and a trusted local root certificate for operator devices
Use the section that matches your environment and replace the example domain, LAN_HOST, or LAN_IP values before you bring the stack up.
Enable automated email invitations and admin signup notifications:
Terminal window
supabasesecretsset\
RESEND_API_KEY="re_your_api_key"\
APP_URL="https://your-domain.com"\
EMAIL_FROM="Eryxon <noreply@your-domain.com>"\
SIGNUP_NOTIFY_EMAIL="admin@your-domain.com"
SIGNUP_NOTIFY_EMAIL is the address that receives notifications when a new company signs up. Required for the notify-new-signup edge function to send emails.
The built-in 3D STEP viewer works out of the box using browser-based WASM parsing (occt-import-js). No server-side CAD service is required.
How it works: STEP/STP files uploaded to the parts-cad storage bucket are parsed client-side using WebAssembly. The viewer supports orbit controls, exploded view, wireframe mode, and measurement tools (distance, angle, radius).
CSP requirements: The STEP parser needs specific Content Security Policy directives. These are already configured in the shipped index.html and vercel.json, but if your reverse proxy (Nginx, Caddy, Cloudflare) adds its own CSP headers, make sure they include:
Emscripten embind (occt-import-js) uses new Function()
'wasm-unsafe-eval'
Explicit WASM compilation permission
https://cdn.jsdelivr.net
CDN host for the occt-import-js library
worker-src blob:
occt-import-js creates Web Workers from blob URLs
Note: The default Nginx and Caddy configs shipped with this repo do not set CSP headers (they rely on the <meta> tag in index.html), so you only need to worry about this if you add custom CSP rules at the proxy level.
Optional: Server-side CAD processing
For server-side geometry extraction and PMI (Product Manufacturing Information) data, configure an external CAD service:
If not configured, browser-based processing is used automatically. The viewer supports three backend modes: custom (Eryxon3D Docker), byob (Bring Your Own Backend), and frontend (browser-only, the default).
Note: Your self-hosted application works perfectly without the MCP server. It’s only for developers who want AI assistant integration via Claude Desktop.
Note: Storage bucket check may report FAIL (HTTP 400) even when buckets exist. This is expected because the buckets are private (public: false) and the verification script uses the Anon Key, which cannot list private buckets. Verify manually via SQL: