Self-Hosted Build Workers
Run Venelx builds on your Mac, Windows, or Linux machine while keeping the dashboard on app.venelx.com. The API and data stay in the cloud; only build execution runs locally.
What runs where
| Component | Where |
|---|---|
| Dashboard | Venelx cloud (browser) |
| API (WebSocket + job queue) | Venelx cloud (api.venelx.com) |
| Worker agent | Your machine (installer) |
| MongoDB + B2 | Venelx cloud (no setup) |
| Xcode (iOS) | Your Mac |
| Android SDK / WSL2 | Your Linux or Windows host |
No Redis required on your side — jobs live in MongoDB; workers connect to
wss://api.venelx.com/ws/worker (HTTP endpoints are fallback only).
Platform support
| OS | iOS builds | Android builds |
|---|---|---|
| macOS | Yes (Xcode required) | Yes |
| Linux | No | Yes |
| Windows | No | Yes via WSL2 + the Linux worker inside Ubuntu |
Licensing
Self-hosted workers are gated by a plan:
- Open Billing → Self-Hosted Workers (or Settings → Workers).
- Subscribe to the annual worker plan — includes 2 worker slots by default.
- Add extra slots from Billing or Workers if you need more machines.
Setup flow
-
Subscribe (above).
-
Settings → Workers → Create worker — choose a name and platforms (iOS / Android / both).
-
Copy the pairing token — it is shown once.
-
Download the installer for your OS (macOS
.pkg, Windows-setup.exe, Linux-amd64.deb). -
Run the installer, then paste the token into the config file —
~/.venelx/worker.env(macOS/Linux) or%ProgramData%\Venelx\worker.env(Windows):envWORKER_NAME=mac-studio-1 WORKER_PAIRING_TOKEN=<paste from dashboard> API_URL=https://api.venelx.com WORKER_PLATFORMS=ios,android-preview,android-production VENELX_WORKER_CONFIG=~/.venelx/worker.env -
Start the worker — the agent connects via WebSocket (
/ws/worker) for heartbeat and job claims. A paired worker shows online in the dashboard within ~2 minutes.
Workers need outbound HTTPS only — no static public IP, no inbound ports. IP changes after reboot are fine; no re-pairing is required.
Build routing
When a project owner has an active worker subscription and online workers:
- Builds for their projects prefer their workers first.
- If none of their workers is online and hybrid fallback is enabled (default), Venelx shared workers run the job instead.
Platform routing is automatic: the scheduler assigns jobs only to workers whose
WORKER_PLATFORMS include the target (ios jobs to macOS workers, android-* to
Android-capable workers). Optional GPU/label routing is available via worker labels plus
a project's requiredWorkerLabels.
Optional tuning
API-side defaults (a worker is considered offline once its last heartbeat is older than
WORKER_HEARTBEAT_STALE_MS — keep it comfortably above the worker's own interval):
WORKER_HEARTBEAT_STALE_MS=120000
WORKER_HEARTBEAT_WRITE_MIN_MS=45000
Worker-side (worker.env or environment):
WORKER_HEARTBEAT_INTERVAL_MS=45000
WORKER_CLAIM_POLL_MS=15000
WORKER_WS_HTTP_FALLBACK_MS=30000
If the WebSocket drops for 30s+, the worker falls back to HTTP heartbeat + claim-job
until the socket recovers.
Uninstalling
- Windows — Control Panel → Programs → Uninstall "Venelx Worker". Removes everything
except
%USERPROFILE%\.venelx(config/pairing token preserved). - macOS — run
/Applications/Venelx Worker.app/Contents/Resources/uninstall.sh(add--purgeto also delete~/.venelx). This script is the supported way — there is no Finder-based uninstaller for.pkginstalls. - Linux —
sudo apt-get remove venelx-worker(add--purgeto also delete~/.venelx).
Ops workers vs customer workers
| Ops workers (Venelx fleet) | Customer workers (yours) | |
|---|---|---|
| Auth | global WORKER_AGENT_TOKEN | per-worker pairing token (shown once) |
| Kind | shared | customer (ownerId = your user id) |
| Registration | admin-managed | must be created in the dashboard first — no auto-register on heartbeat |
Venelx's own ops workers run with WORKER_AGENT_TOKEN + launchd/systemd, exactly like
any other worker from the queue's point of view.
Troubleshooting
| Symptom | Fix |
|---|---|
Invalid pairing token | Recreate the worker in the dashboard — tokens are one-time |
Worker subscription inactive | Renew the annual plan in Billing |
Worker slot limit reached | Remove unused workers or buy add-on slots |
| Heartbeat OK but no builds | Confirm the worker is online and the project owner matches the worker owner |
| Worker stuck at "starting service" | Upgrade the installer (recent versions replaced flock with a portable lock on macOS) |
| Dashboard shows online after quit | The worker sends an offline heartbeat on tray quit / SIGTERM — allow a moment |
Heartbeat failed | Check API_URL and the pairing token in worker.env |
Worker env essentials (ops/self-managed workers)
For workers you operate yourself against a self-hosted API (from
env/worker-mac.env.example / env/worker-linux.env.example):
VENELX_DEPLOY_ROLE=worker
WORKER_AGENT_ONLY=true
RUN_QUEUE_WORKER=true
WORKER_STRICT=true
WORKER_NAME=mac-ios-1 # unique per machine
WORKER_PLATFORMS=ios # or android-preview,android-production on Linux/WSL2
API_URL=https://api.venelx.com
REDIS_URL=rediss://... # same as the API (BullMQ fleets)
MONGODB_URI=... # same Atlas as the API
WORKER_AGENT_TOKEN=... # same as the API
FORGE_MASTER_SECRET=... # same as the API (decrypts signing material)
B2_UPLOAD_VIA_API=true # no B2 keys on workers
OUTPUT_DIR=/path/on/this/host/cicd-builds
EXPO_TOKEN=...
ANDROID_HOME=/path/to/android/sdk # Android workers only
The full annotated list is in Environment variables.