swarmy
v0.3.16
Published
Distributed container management with browser-based VNC and terminal access
Maintainers
Readme
Swarmy
Distributed container management with browser-based VNC and terminal access.
Provision ephemeral Docker containers across multiple nodes and interact with them through a web dashboard — full desktop GUI via VNC and interactive terminal sessions, 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 — Node agent on each machine. Manages Docker containers, PTY sessions, and VNC proxy connections.
- swarmy-base — Docker image (Ubuntu 24.04) with TigerVNC, Fluxbox, noVNC, Chrome, and s6-overlay for process supervision.
Quick Start
Prerequisites
- Node.js (v24+ recommended)
- Docker
- npm
Using npx (recommended)
Manager:
npx --yes swarmy@latest manager startSign in with Google, then add nodes from the Settings page. Each node gets a unique token.
Worker (on each node):
npx --yes swarmy@latest worker start --url http://<manager-ip>:5174 --token <node-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 node):
cd worker
npm install
SWARM_URL=http://<manager-host>:5174 SWARM_TOKEN=<node-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:
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 <node-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 | Node auth token for registration |
| SWARM_NODE_ID | Worker | Node identifier (default: hostname) |
| SWARM_MAX_CONTAINERS | Worker | Max containers per node (default: 10) |
| RESOLUTION | Docker | Screen resolution (default: 1920x1080) |
API
All REST endpoints require Authorization: Bearer <firebase-id-token> header.
| Method | Endpoint | Description |
| -------- | ------------------------- | ----------------------------------- |
| GET | /api/nodes | List all nodes |
| GET | /api/nodes/:id | Get node with containers |
| DELETE | /api/nodes/:id | Remove node (stops containers) |
| POST | /api/containers | Create container on a node |
| DELETE | /api/containers/:id | Stop and remove container |
| POST | /api/sessions | Spawn terminal session in container |
| DELETE | /api/sessions/:id | Kill session |
| POST | /api/sessions/:id/input | Send input to session |
| PATCH | /api/sessions/:id | Toggle interactive mode |
| POST | /api/containers/:id/thumbnail | Upload VNC thumbnail (base64 JPEG) |
| GET | /api/containers/:id/thumbnail | Get VNC thumbnail (supports ?token=) |
| 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
