Deploy any Git repository to the Flux Decentralized Cloud in minutes. Orbit is a full-stack React + Node.js app that handles everything from authentication and app registration to live monitoring, redeploys, and billing — all without a centralised server.
🏢 Owned by: InFlux Technologies ⚡ Powered by: Flux
- 🔑 SSP Wallet — sign-in via the SSP browser extension
- 🦊 ZelCore — QR-based wallet signing flow
- 📧 Firebase Email/Google — traditional login with SSO-derived Flux keypair
- 🔐 Deterministic zelid — each Firebase user always maps to the same Flux address
- 🔒 Session persistence — auth state survives page reloads
- 🚀 6-step guided wizard — Repo → Plan → Config → Review → Payment → Status
- 🧠 Repo intelligence — auto-detects framework, port, build/run commands from GitHub
- 📦 Plan selection — Free, Developer, Pro, Custom with live price calculation
- 🌍 Geo-targeting — choose continent or specific country for node placement
- 💳 Stripe Checkout — fiat payments via Flux payment bridge
- 🔄 ZelCore / SSP Wallet — native crypto FLUX payments
- ✅ Live test install — streaming NDJSON build log during registration
- 🔏 On-chain signing — spec verified + signed before submission to the blockchain
- 📊 Real-time status — per-node running/partial/stopped badges, auto-polls every 30s
- 🖼️ Site preview — live screenshot of deployed app via BFF proxy
- 📋 Settings editor — edit description, domain, env vars, git branch, polling interval, secrets
- 🔁 Redeploy — trigger a git pull + rebuild on any node via HMAC-signed webhook
- ⚡ Hard Redeploy — force a clean build from scratch
- 🛑 Node actions — restart / start / stop / remove per Flux node
- 📜 Live logs — streaming app & system build logs (NDJSON)
- 🌐 Orbit status — last commit, build status, deployed-at per node
- 💰 Subscription overview — per-app plan, expiry countdown in days, renew shortcut
⚠️ Expiry alerts — banner when any app expires within 14 days- 🎫 Support tickets — submit tickets via relay with issue-type classification
- 🎨 Fully responsive — mobile sidebar drawer, responsive grids throughout
- 🔔 Toast notifications — success/error feedback for every action
- 💀 Skeleton loaders — shimmer placeholders on every async card
- 🛡️ Error boundary — graceful fallback UI for unhandled errors
- ⚡ Vite + React — HMR in development, optimised code-split bundles in production
- 🔀 BFF proxy — Express server handles Flux API proxying, screenshot capture, webhook signing
-
Node.js 18+ and npm
-
A Flux account (SSP Wallet, ZelCore, or Firebase email)
-
Firebase project with Email/Password and Google auth enabled (optional — a shared project is used by default)
-
Chromium — required for the app preview screenshot feature (not bundled via npm)
# Ubuntu / Debian sudo apt install chromium # Snap (any Linux) sudo snap install chromium
The server expects Chromium at
/snap/bin/chromiumby default. Override with theCHROMIUM_PATHenv variable if your binary is elsewhere (e.g./usr/bin/chromium).
# Clone the repository
git clone <repository-url>
cd orbit-ui
# Install dependencies
npm install
# Create your environment file
cp .env.example .env
# Edit .env with your values (see Environment Setup below)
nano .env
# Start dev server (Vite on :5173 + Express BFF on :3001)
npm run devOpen http://localhost:5173 in your browser.
# Build optimised bundle
npm run build
# Preview production build locally
npm run preview
# Run in production (serves /dist + API on one port)
PORT=4000 node server.jsCopy .env.example to .env and fill in the values:
# App
VITE_APP_URL=http://localhost:5173
# Feature Flags (runtime via GET /api/config — set as container env in production)
VITE_ENABLE_ANALYTICS=false
VITE_GA_MEASUREMENT_ID=G-XXXXXXXXXX
# Payment Bridge (Stripe checkout + Flux price calculation, via the hosted bridge)
VITE_PAYMENT_BRIDGE_URL=https://fiatpaymentsbridge.runonflux.io
# Firebase (optional — defaults to the shared FluxOS project)
VITE_FIREBASE_API_KEY=
VITE_FIREBASE_AUTH_DOMAIN=
VITE_FIREBASE_PROJECT_ID=
VITE_FIREBASE_STORAGE_BUCKET=
VITE_FIREBASE_MESSAGING_SENDER_ID=
VITE_FIREBASE_APP_ID=VITE_APP_URL=https://orbit.runonflux.com
VITE_ENABLE_ANALYTICS=true
VITE_GA_MEASUREMENT_ID=G-XXXXXXXXXX
PORT=4000
NODE_ENV=productionGoogle Analytics is optional. When enabled, the server exposes both variables through GET /api/config; the client loads GA4 only after the user accepts the analytics consent banner. No frontend rebuild is required when changing these in a Docker/Flux container — restart the app process so server.js picks up new env values.
VITE_GA_MEASUREMENT_IDis for Google Analytics 4.VITE_FIREBASE_MEASUREMENT_ID(Firebase config) is separate and does not enable GA tracking on its own.
- Go to Firebase Console
- Create a new project and add a Web App
- Navigate to Authentication → Sign-in method
- Enable Email/Password and Google
- Add authorised domains:
localhost,your-domain.com
Paste your Firebase config values into .env:
VITE_FIREBASE_API_KEY=AIza...
VITE_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your-project-id
VITE_FIREBASE_STORAGE_BUCKET=your-project.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=123456789
VITE_FIREBASE_APP_ID=1:123456789:web:abcdefFirebase users sign Flux transactions without owning a wallet app: the BFF
forwards the user's Firebase ID token to service.fluxcore.ai, which signs the
login phrase and app specs on their behalf. This requires the official FluxOS
fluxcore-prod Firebase project (the default in config/defaults.js), so no
signing secret or extra configuration is needed.
orbit-ui/
├── server.js # Express BFF — API proxy, auth, screenshot, webhooks
├── src/
│ ├── pages/
│ │ ├── Home.jsx # Landing page
│ │ └── dashboard/
│ │ ├── DashboardLayout.jsx
│ │ ├── Overview.jsx
│ │ ├── Deployments.jsx
│ │ ├── AppDetail.jsx # Per-app management page
│ │ ├── DeployWizard.jsx
│ │ ├── Billing.jsx
│ │ └── Support.jsx
│ ├── components/
│ │ ├── management/ # App detail cards (info, settings, instances, logs)
│ │ ├── wizard/ # Deployment wizard steps
│ │ ├── dashboard/ # AppCard, StatusBadge
│ │ ├── common/ # ErrorBoundary, Modal, Button, Input
│ │ └── landing/ # Home page sections
│ ├── services/
│ │ ├── appsService.js # App list + status fetching
│ │ ├── deployService.js # Plans, spec building, registration
│ │ ├── managementService.js # Node actions, orbit status, redeploy
│ │ ├── authService.js # Login flows (SSP, ZelCore, Firebase)
│ │ └── axiosInstance.js # Axios + Flux API proxy helpers
│ ├── hooks/
│ │ └── useApps.js # React Query hooks for app data
│ └── context/
│ └── AuthContext.jsx # Global auth state
└── public/
└── orbit-icon.svg
Orbit uses a Backend-for-Frontend (BFF) pattern. The Express server (server.js) proxies all Flux API calls so the browser never touches the network directly.
Browser → Vite dev proxy (dev) → BFF :3001
↓
https://api.runonflux.io
https://<node>.node.api.runonflux.io
https://service.fluxcore.ai
https://fiatpaymentsbridge.runonflux.io
| Method | Path | Purpose |
|---|---|---|
GET |
/api/flux/* |
Proxy to api.runonflux.io |
POST |
/api/flux/apps/registerapplication |
Register app on Flux |
GET |
/api/screenshot?url= |
Capture site screenshot via headless Chromium |
POST |
/api/orbit-deploy |
HMAC-signed redeploy webhook trigger |
Orbit supports three payment methods for app deployments:
- Price calculated via
POST /apps/calculatefiatandfluxpriceon the payment bridge - Checkout session created at
POST <bridge>/api/v1/stripe/checkout/create - User redirected to Stripe Hosted Checkout
- On success,
?session_id=redirected to/successcheckout
- FLUX amount fetched from payment bridge
- Payment address fetched from
GET /apps/deploymentinformation zel:?action=pay&...deep-link opens ZelCore wallet
- Same price/address lookup as ZelCore
window.ssp.request('pay', {...})invokes the browser extension
Orbit nodes run a local webhook server. Redeploy triggers are sent as synthetic GitHub-style push events:
POST http://<node-ip>:<mgmt-port>/webhook
X-Hub-Signature-256: sha256=<hmac-sha256>
The BFF signs the payload with the app's WEBHOOK_SECRET env var so each node validates authenticity before pulling and rebuilding.
- Redeploy —
git pull+ rebuild (same image) - Hard Redeploy —
forced: true— clean wipe + full rebuild from scratch
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, Tailwind CSS, Framer Motion |
| State / Data | TanStack Query, React Context |
| Backend | Node.js, Express |
| Auth | Firebase Auth (signing delegated to service.fluxcore.ai) |
| Payments | Stripe (hosted Checkout via the Flux fiat bridge) |
| Icons | Lucide React |
| Notifications | react-hot-toast |
# Start both servers (Vite :5173 + Express :3001)
npm run dev
# Run only the BFF server
npm run server
# Run only the Vite client
npm run client
# Lint
npm run lint
# Production build
npm run buildSet a zelid starting with dev_ to skip live Flux API calls and work with mock data:
# In AuthContext, dev mock mode activates automatically for zelid = 'dev_*'
# App list queries are disabled, letting you build UI against static fixturesOrbit is itself deployable on Flux. The app container runs NODE_ENV=production node server.js which serves the built /dist and the BFF API on a single port.
# Build
npm run build
# Run (production)
PORT=4000 NODE_ENV=production node server.jsFlux spec environment variables to set:
| Variable | Description |
|---|---|
PORT |
Server port (default 3001, set to 4000 or any free port) |
NODE_ENV |
production |
VITE_PAYMENT_BRIDGE_URL |
Flux fiat payment bridge URL |
VITE_ENABLE_ANALYTICS |
true or 1 to enable GA4 (requires measurement ID) |
VITE_GA_MEASUREMENT_ID |
Google Analytics 4 measurement ID (e.g. G-XXXXXXXXXX) |
MIT © InFlux Technologies