Connect a machine
Connect the GPU machines you already have, at any provider, and run training and evaluation experiments on them from the platform: pick a machine and a number of GPUs, give your repository and command, and follow the live log.
What a machine needs
- SSH that the platform can log in to with its key.
- NVIDIA driver (
nvidia-smi) for the platform to find the GPUs. - bash, and git for experiments that check out a repository.
- Whatever your own code needs (Python, CUDA libraries, ...).
Nothing is installed on the machine, and Docker is not needed, so this works with VMs and bare metal (AWS, GCP, Azure, Lambda, CoreWeave, your own servers) and with rented containers (RunPod, Vast.ai) alike. The platform only connects out to the machine; the machine never needs to reach the platform.
Evals (not experiments) install
uvand Inspect into the machine's~/.simulusionon first use (unless you give a Python that already has Inspect), and tasks with container sandboxes need Docker usable by that user. See evals.md.
Or: run the platform on the GPU server itself
No server of your own for the platform? Put it on the GPU server and open it in your browser through an SSH tunnel. From this repository, on your computer (Python 3 and ssh are all it needs):
python tools/gpu_server.py deploy root@203.0.113.7 -p 22045
# the same, pasted from your provider:
python tools/gpu_server.py deploy "ssh root@203.0.113.7 -p 22045 -i ~/.ssh/id_ed25519"It packs the platform with its web app, copies it over your own SSH
connection, installs it on the server (deploy/gpu-server/install.sh: uv
and Python packages in your home directory; no Docker, no root), starts it,
then opens the tunnel and your browser at http://localhost:8000.
- The platform listens on the server's 127.0.0.1 only: nothing is open to the internet, and only people who can SSH to the server reach it.
- The server is already a machine on the Machines page ("This server"): experiments run on its GPUs directly, without SSH. You can still add other machines.
- Closing the tunnel (Ctrl+C) leaves the platform and its experiments running.
Reconnect later with
python tools/gpu_server.py tunnel root@203.0.113.7 -p 22045, or by hand:ssh -N -L 8000:localhost:8000 root@203.0.113.7 -p 22045, then open http://localhost:8000. - Deploying again updates it in place and keeps its data.
On the server, ~/.simulusion-platform/ holds its database, recordings,
SSH key and log; control it with
~/.simulusion-platform/platform start|stop|restart|status|logs. Where cron
exists it starts again after a reboot; on RunPod and Vast.ai, start it again
after restarting the pod. Options: --port (on the server), --local-port (on
your computer, if 8000 is taken), --no-browser, --no-tunnel.
Without the tool: copy the repository (with web/out built) to the server and
run bash deploy/gpu-server/install.sh there; it prints the tunnel command.
Connect a machine
On the Machines page (team admins):
- Give the machine the platform's SSH key. The page shows the
platform's public key. Add it in your provider's SSH key settings before
you create the machine, or, on a machine that already runs, add it to
~/.ssh/authorized_keys(the page has the command to copy). - Paste the SSH command your provider shows, e.g.
ssh root@203.0.113.7 -p 22045. Key files (-i ...) and port forwards in it are ignored. The platform connects, finds the GPUs and adds the machine; if it cannot get in, it says why and what to do.
Each machine card shows its GPUs (model, memory in use, utilisation, and whether an experiment holds it), CPUs, memory, free disk, OS, CUDA, driver, Python and git. It refreshes every minute; Check again refreshes now.
Machines the internet cannot reach
A laptop GPU, WSL, an office server behind NAT or a firewall: the platform cannot SSH to it, so it connects to the platform instead. On Machines, choose It can't be reached from the internet, name it, and run the command you get on the machine, as the user experiments should run as:
curl -fsSL https://app.example.com/v0/machines/connect.sh | SIMULUSION_CODE=<code> bashIt makes a key for the tunnel, registers it with the platform (the code works
once, within a day), adds the platform's key to ~/.ssh/authorized_keys,
and keeps ssh -R open from the machine to the platform's tunnel endpoint,
reconnecting when the network drops. The machine turns Ready within a
minute, and from then on it is like any other machine.
- The machine needs an SSH server (
sudo apt install -y openssh-server && sudo service ssh starton Ubuntu or WSL). - Nothing on the machine is opened to the internet. The endpoint allows each machine's key only its own tunnel, on the platform's loopback: no shell, no commands, no other forwarding.
- In
~/.simulusion/tunnel/on the machine:stop.sh,start.sh(after a reboot) andlog. Connect command on the machine's card makes a new code (to connect it again). - The platform needs its tunnel endpoint on (
PLATFORM_TUNNEL_PORT; it is off by default), that port open in its firewall, andPLATFORM_PUBLIC_URLset if machines reach it at another address than your browser does.
Provider notes
| Provider | What to paste |
|---|---|
| RunPod | The SSH over exposed TCP command (public IP and port) from the pod's Connect tab. The proxied ssh.runpod.io connection does not support what the platform needs. Add the key under Settings → SSH public keys before starting the pod. |
| Vast.ai | The SSH command from the instance's connect window (direct or proxy). Add the key under Account → SSH keys. |
| Lambda, AWS, GCP, Azure | ssh ubuntu@<public IP> (the image's user). Allow port 22 from the platform's address in the firewall or security group. |
| Your own servers | ssh <user>@<host>, after adding the key to that user's ~/.ssh/authorized_keys. |
A machine restarted with a new address (common on RunPod and Vast.ai): remove it and add it again with the new command.
The platform's key
The platform makes its SSH key (ed25519) on first use and keeps it:
- in Docker and the Helm chart, in the data volume (
/data/ssh/); - from source, in
~/.config/simulusion-platform/ssh/; - or wherever
PLATFORM_SSH_KEYpoints.
Machines keep trusting the platform as long as that key is kept; with a new key they need the new public key. Machines' host keys are remembered next to it the first time the platform connects.
Security
- Whoever controls the platform server can log in to the connected machines as the user you gave. Give it a user meant for this, and keep the server's data volume private.
- Experiments' variable values and repository tokens are stored in the platform's database (never returned by the API), and written on the machine in a file only that user can read.
- Teams see only their own machines and experiments. Admins add and remove machines; members run and stop experiments; viewers can look.
Updated Nov 7, 2026