swarmy
v0.5.1
Published
Distributed container management with browser-based VNC and terminal access
Readme
Swarmy
Distributed container management with browser-based VNC and terminal access.
Provision ephemeral Docker containers across multiple workers and interact with them through a web dashboard — full desktop GUI via VNC and interactive terminals, all in the browser.
Architecture
┌─────────────────────────────────────────────────────┐
│ Browser Client │
│ React + xterm.js + noVNC │
└──────────┬───────────────────────────┬──────────────┘
│ WebSocket (UI/session/VNC)│ REST API
▼ ▼
┌─────────────────────────────────────────────────────┐
│ Manager │
│ Express.js · SQLite · WebSocket Hub │
└──────────┬──────────────────────────────────────────┘
│ WebSocket (/ws/worker)
┌─────┴─────┐
▼ ▼
┌──────────┐ ┌──────────┐
│ Worker │ │ Worker │ ...
│ Docker │ │ Docker │
│ node-pty │ │ node-pty │
└──────────┘ └──────────┘- Manager — Central server with React dashboard. Maintains state in SQLite, brokers WebSocket communication between workers and browser clients.
- Worker — Agent running on each machine. Manages Docker containers, PTY terminals, and VNC proxy connections.
- swarmy-base — Docker image (Ubuntu 24.04) with TigerVNC, Fluxbox, noVNC, Chrome, and s6-overlay for process supervision.
What you can do
- Drive a real Chrome from your agent — submit natural-language tasks via REST+SSE, MCP, or CLI; the in-container Chrome runs the task and streams events back.
- Snapshot and reuse Chrome profiles — log in once via VNC, snapshot the profile, then every future agent run skips the login (including MFA/SSO) until cookies actually expire.
- Jump in via VNC when the agent gets stuck — live human takeover from the browser-based dashboard.
- Test against your local app —
swarmy-iris-cli test --expose 3000 --expose 8000 --then "..."tunnels your local services into the container so the agent's Chrome can hitlocalhost:3000natively, no CORS surgery. Up to 8 ports per session. See help → "Test against your local app". - Capture screenshots, keyframes, and MP4 video — opt-in flags on the agent endpoint; artifacts kept 7 days.
Quick Start
Prerequisites
- Node.js (v24+ recommended)
- Docker
- npm
Using npx (recommended)
Manager:
npx --yes swarmy@latest manager startSign in with Google, then add workers from the Settings page. Each worker gets a unique token.
Worker (on each machine):
npx --yes swarmy@latest worker start --url http://<manager-ip>:5174 --token <worker-token>Other commands:
npx --yes swarmy@latest manager status # Show PID
npx --yes swarmy@latest manager stop # Stop manager
npx --yes swarmy@latest manager restart # Restart manager
npx --yes swarmy@latest worker status # Show worker PID
npx --yes swarmy@latest worker stop # Stop workerFrom source (development)
Manager:
cd manager
npm install
npm run devThe manager starts on port 5174. Sign in with Google to access the dashboard.
Worker (on each machine):
cd worker
npm install
SWARM_URL=http://<manager-host>:5174 SWARM_TOKEN=<worker-token> npm run devDocker Image
scripts/build.sh # Build swarmy-base image (linux/amd64)
scripts/run.sh # Run a standalone container
PORT=8080 RESOLUTION=1280x720 scripts/run.sh my-browser # Custom settingsProduction Deployment
Manager prerequisites:
- Node.js 22+
ffmpegon PATH — required for/api/agent/runcapture MP4 encoding. Install viaapt install ffmpeg(Linux) orbrew install ffmpeg(macOS). The manager refuses to start without it.
Manager:
npx --yes swarmy@latest manager start \
--firebase-service-account '{"type":"service_account",...}' \
--firebase-api-key "YOUR_API_KEY" \
--firebase-auth-domain "YOUR_PROJECT.firebaseapp.com" \
--firebase-project-id "YOUR_PROJECT_ID"Or use a .env file in the working directory (see Environment Variables below).
Worker:
npx --yes swarmy@latest worker start --url http://<manager-ip>:5174 --token <worker-token>Environment Variables
| Variable | Component | Description |
| ------------------------------ | --------- | -------------------------------------- |
| PORT | Manager | HTTP port (default: 5174) |
| FIREBASE_SERVICE_ACCOUNT_JSON| Manager | Firebase service account (raw JSON) |
| VITE_FIREBASE_API_KEY | Manager | Firebase API key (build-time) |
| VITE_FIREBASE_AUTH_DOMAIN | Manager | Firebase auth domain (build-time) |
| VITE_FIREBASE_PROJECT_ID | Manager | Firebase project ID (build-time) |
| SWARM_URL | Worker | Manager URL to connect to |
| SWARM_TOKEN | Worker | Worker auth token for registration |
| SWARM_WORKER_ID | Worker | Worker identifier (default: hostname) |
| SWARM_MAX_CONTAINERS | Worker | Max containers per worker (default: 10)|
| RESOLUTION | Docker | Screen resolution (default: 1920x1080) |
API
All REST endpoints require Authorization: Bearer <firebase-id-token> header.
| Method | Endpoint | Description |
| -------- | ------------------------- | ----------------------------------- |
| GET | /api/workers | List all workers |
| GET | /api/workers/:id | Get worker with containers |
| DELETE | /api/workers/:id | Remove worker (stops containers) |
| POST | /api/containers | Create container on a worker |
| DELETE | /api/containers/:id | Stop and remove container |
| POST | /api/terminals | Spawn terminal in container |
| DELETE | /api/terminals/:id | Kill terminal |
| POST | /api/terminals/:id/input | Send input to terminal |
| PATCH | /api/terminals/:id | Toggle interactive mode |
| POST | /api/containers/:id/thumbnail | Upload VNC thumbnail (base64 JPEG) |
| GET | /api/containers/:id/thumbnail | Get VNC thumbnail (supports ?token=) |
| POST | /api/agent/run | Run a browsing task end-to-end (SSE stream). Supports opt-in keyframe / final-screenshot / final-video capture. See docs/agent-sse-endpoint.md. |
| GET | /api/captures/:runId/:filename | Fetch a capture artifact (PNG keyframe, final.png, final.mp4). Supports ?token= for <img>/<video> tags. |
| GET | /api/status | Server status |
Tech Stack
Manager: Express.js, React 19, Tailwind CSS 4, xterm.js, noVNC, better-sqlite3, Vite
Worker: Dockerode, node-pty, ws
Container: Ubuntu 24.04, TigerVNC, Fluxbox, noVNC, Google Chrome, s6-overlay v3
