Your machines, one tap away.
Rigdeck is a self-hosted control deck for the computers you own. From any browser, including your iPhone, you can:
- watch CPU, RAM and GPU,
- start and stop jobs and read their logs,
- take over the desktop.
Everything runs over your private Tailscale network, so nothing is exposed to the internet.
Status: early (v0.1). The macOS panel and the remote desktop path are tested end-to-end. The Linux agent setup is documented but has not yet been validated on real hardware. The interface labels are currently in Portuguese, so this guide shows each label with its English meaning, for example Adicionar (Add).
- Why Rigdeck
- Features
- How it works
- Quick start
- Using Rigdeck
- Setting up a VNC server
- Configured jobs
- Configuration
- API
- Security
- Troubleshooting
- Project layout
- Roadmap
- Contributing
- License
You have a GPU rig at home and a laptop on the go. You want to check whether training is still running, start a new run, or click something on the rig's screen. You want to do that from your phone or any other device, without opening ports on your router and without paying for a remote-desktop subscription.
| Device catalog | All your machines in one list, with live online/offline status. |
| Metrics | CPU, memory, disk, uptime, and NVIDIA GPU utilization, VRAM and temperature (via nvidia-smi). |
| Processes | The top 100 processes by CPU and memory. |
| Jobs | Start any command in a working folder, follow its log, and stop it. Add one-tap buttons for recurring jobs. |
| Remote desktop | See and control the screen from the browser (noVNC). Works with macOS Screen Sharing and Linux VNC servers. |
| Built for phones | Installs on the iPhone home screen. Touch gestures, an on-screen keyboard with Ctrl/Alt/⌘, zoom, pan and full screen. |
| Private by default | Services listen on localhost and are shared only inside your tailnet. Each machine has its own token, and stored tokens are encrypted. |
Every machine runs the same small app. Each copy plays one of two roles:
- The panel is the copy you open in the browser. It stores your device list and forwards your requests. Install it on the machine that is powered on most often.
- An agent is a copy on any other machine. It reports metrics, runs jobs and bridges that machine's screen. The panel is also an agent for itself.
Your browser only talks to the panel. The panel talks to each agent using that agent's own token.
Install Tailscale on every computer and on your phone, and sign in with the same account. The free plan is enough.
In the admin console, turn on MagicDNS and HTTPS certificates.
On the machine that will host the panel:
git clone https://github.com/<you>/rigdeck.git ~/rigdeck
cd ~/rigdeck
python3 -m venv .venv
.venv/bin/pip install -e .
cp .env.example .env
python3 -c "import secrets; print(secrets.token_urlsafe(32))"Paste the printed value into RIGDECK_TOKEN in .env. Then start the panel:
.venv/bin/python -m rigdeckOpen http://127.0.0.1:8765 and enter the token. The panel machine already appears in the list as Este computador (This computer).
To keep the panel running in the background, use the installer for your system:
- macOS:
./deploy/install-macos.shinstalls a LaunchAgent. The panel starts at login and restarts if it crashes. - Linux: use the systemd unit, the same way as for an agent (see step 4).
Important
On macOS:
- Keep the repository outside
~/Desktop,~/Documentsand~/Downloads;~/rigdeckworks. macOS blocks background services from reading those folders. - The Mac must stay awake to be reachable. Plug it in, turn off automatic sleep, and keep the lid open or connect an external display.
tailscale serve --bg 8765This prints the panel's private address, https://<machine>.<tailnet>.ts.net, which only devices in your tailnet can open.
Repeat the install with a new token, different from the panel's:
git clone https://github.com/<you>/rigdeck.git ~/rigdeck
cd ~/rigdeck && python3 -m venv .venv && .venv/bin/pip install -e .
cp .env.example .env # set a new RIGDECK_TOKENOn Linux, keep it running with systemd and share it:
mkdir -p ~/.config/systemd/user
cp deploy/rigdeck.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now rigdeck.service
sudo loginctl enable-linger "$USER" # keep running when you are logged out
sudo tailscale set --operator="$USER" # allow `tailscale serve` without sudo
tailscale serve --bg 8765In the panel, tap + Adicionar (Add) and fill in:
- a name,
- the agent's
https://….ts.netaddress, - the agent's token.
The device appears in the list with its status. Plain HTTP addresses are accepted only for localhost and private IPs.
On any device in your tailnet, open the panel's address. On iPhone, open it in Safari, then tap Share → Add to Home Screen to use it like an app.
The home screen lists every machine with its status, for example Online · CPU 24% · GPU 81%. Tap Abrir dispositivo (Open device) to see two tabs:
- Processos (Processes): metrics, GPUs, jobs and running processes.
- Interface: the remote desktop.
- Metrics: CPU, memory, disk and uptime, refreshed every 10 seconds. NVIDIA GPUs appear automatically.
- Executar programa (Run program): enter a name, a command such as
python train.py --epochs 20, and a working folder.- Commands run without a shell, so pipes (
|) and redirections (>) do not work. - Each run gets its own log. Use Log to read the output and Parar (Stop) to end it.
- Commands run without a shell, so pipes (
- Tarefas configuradas (Configured jobs): one-tap buttons defined in
config/jobs.json(see Configured jobs).
- Open a device, then the Interface tab.
- Enter the VNC password.
- On a Mac, enter your macOS username and password instead.
- Or enable a VNC password in Screen Sharing (see macOS) and use only that.
- Tap Conectar (Connect).
The machine must have a VNC server running (see Setting up a VNC server), and someone must be logged in to its desktop.
Some tips:
- Tap ⌨ Teclado (Keyboard) to type. Tapping the remote screen again closes the keyboard.
- Modifier keys apply to the next key only. For example, tap ⌘/Super and then type
cto copy on a Mac. - Expandir (Expand) uses the whole phone screen. For the best experience, add Rigdeck to the Home Screen first.
Rigdeck connects to a VNC server on localhost of each machine (default 127.0.0.1:5900). Keep that server off the network: Rigdeck is the only way in.
Turn on System Settings → General → Sharing → Screen Sharing. Then sign in from the Interface tab with your macOS account.
To use a separate password instead, click (i) next to Screen Sharing and enable VNC viewers may control screen with password.
This covers setups such as Pop!_OS 22.04 or Ubuntu with Xorg. Check your session type with echo $XDG_SESSION_TYPE. If it prints x11:
sudo apt install -y x11vnc
x11vnc -storepasswd
x11vnc -display :0 -auth guess -localhost -rfbport 5900 -usepw -forever -sharedIf your GNOME version ships grdctl with VNC support:
grdctl vnc set-auth-method password
grdctl vnc set-password
grdctl vnc enable
systemctl --user enable --now gnome-remote-desktop.serviceThese are not covered yet. Contributions are welcome.
If your VNC server listens somewhere else, set RIGDECK_VNC_HOST and RIGDECK_VNC_PORT.
For jobs you run often, copy config/jobs.example.json to config/jobs.json on the machine that runs them:
[
{
"id": "train-resnet",
"name": "Train ResNet",
"description": "20 epochs on the home dataset",
"command": ["python", "-u", "train.py", "--epochs", "20"],
"cwd": "/home/me/projects/resnet",
"enabled": true
}
]Each job appears as a button with Iniciar (Start) and Parar (Stop). Output goes to logs/<id>.log.
Settings are read from environment variables and from .env in the project folder. Environment variables win over .env. The legacy MACHINES_CONTROL_* names still work.
| Variable | Default | Purpose |
|---|---|---|
RIGDECK_TOKEN |
(required) | API token for this machine. On the panel, it also encrypts the stored device tokens: if you change it, add your devices again. |
RIGDECK_HOST |
127.0.0.1 |
Bind address. Keep localhost and share with tailscale serve. |
RIGDECK_PORT |
8765 |
HTTP port. |
RIGDECK_VNC_HOST |
127.0.0.1 |
Host of this machine's VNC server. |
RIGDECK_VNC_PORT |
5900 |
Port of this machine's VNC server. |
RIGDECK_DB |
data/devices.sqlite3 |
Device catalog file. |
Every endpoint requires Authorization: Bearer <token>. The panel exposes each agent endpoint under /api/devices/{id}/… and forwards it with that agent's token.
| On the agent | Through the panel | What it does |
|---|---|---|
| — | GET POST /api/devices · DELETE /api/devices/{id} |
Manage the device catalog |
GET /api/status |
GET /api/devices/{id}/status |
Host, CPU, memory, disk, GPU, uptime |
GET /api/processes |
GET /api/devices/{id}/processes |
Top processes |
GET /api/jobs |
GET /api/devices/{id}/jobs |
Configured jobs |
POST /api/jobs/{job}/start · /stop |
POST /api/devices/{id}/jobs/{job}/start · /stop |
Start or stop a configured job |
POST /api/launch |
POST /api/devices/{id}/launch |
Start {name, command, cwd} |
GET /api/managed |
GET /api/devices/{id}/managed |
Jobs started from Rigdeck |
GET /api/managed/{job}/logs |
GET /api/devices/{id}/managed/{job}/logs |
Last 24 KB of output |
POST /api/managed/{job}/stop |
POST /api/devices/{id}/managed/{job}/stop |
Send SIGTERM to the job's process group |
WS /api/desktop?token= |
WS /api/devices/{id}/desktop?token= |
VNC over WebSocket |
Anyone with a machine's token can run programs and control the desktop on that machine. Read SECURITY.md before you deploy. The essentials:
- Keep every service on localhost and inside your tailnet.
- Use a long, unique token for each machine.
- Never use
tailscale funnelor router port-forwarding for Rigdeck.
| Symptom | What to check |
|---|---|
| A device shows Offline | Open the agent's .ts.net address from the panel machine. Check systemctl --user status rigdeck (Linux) or logs/panel.log (macOS). Make sure the token matches. |
| Credencial local inválida (invalid stored credential) | The panel token changed. Remove the device and add it again. |
| The remote desktop disconnects right away | No VNC server is listening on 127.0.0.1:5900. Check with nc -z 127.0.0.1 5900. |
| Usuário e senha necessários (username and password required) | The Mac needs your account login. Fill in Usuário (username) as well. |
ModuleNotFoundError: rigdeck on macOS |
Files in synced folders can get the hidden flag, and Python then skips .pth files. Run .venv/bin/python -m rigdeck from the project folder, or run chflags nohidden .venv/lib/python3.*/site-packages/*.pth. |
rigdeck/
├── rigdeck/
│ ├── main.py # FastAPI app: API, agent proxy, VNC WebSocket bridge
│ ├── __main__.py # `python -m rigdeck` entry point (loads .env)
│ └── static/ # Web UI: index.html, app.js, style.css, manifest, vendored noVNC
├── config/
│ └── jobs.example.json # Template for one-tap jobs
├── deploy/
│ ├── install-macos.sh # macOS LaunchAgent installer
│ └── rigdeck.service # systemd user unit for Linux
├── docs/
│ ├── diagrams.py # Generates the diagrams below
│ └── images/ # README diagrams (SVG)
├── .env.example
├── SECURITY.md
└── LICENSE
- English interface and translations
- Automated tests
- Edit devices from the UI
- Keep job state across restarts
- Clipboard sync for the remote desktop
- Wayland support beyond GNOME (COSMIC, KDE)
- Wake-on-LAN for sleeping machines
Issues and pull requests are welcome. To change a diagram, edit docs/diagrams.py and run:
python3 docs/diagrams.py docs/imagesRigdeck is released under the MIT License. The vendored noVNC in rigdeck/static/novnc/ keeps its own license (MPL-2.0 for the core); see rigdeck/static/novnc/LICENSE.txt.