Remote development environments
Develop inside Cubicle Boxes from a macOS or Linux laptop, with one virtual machine per developer reached over SSH and the private network, VS Code or Cursor Remote-SSH through the alias cubicle ssh-config writes, dev servers at private names such as job-1.acme.cubicle.internal, a template Box snapshot as the team baseline, automatic hibernation 60 minutes after each start, and what Cubicle cannot do for remote development.
Develop inside a Box from a macOS or Linux laptop. Each developer gets a Box, a Linux virtual
machine with its own disk, and works in it over SSH: in a terminal with cubicle ssh, or in VS
Code or Cursor through Remote-SSH. A dev server in the Box opens in the laptop's browser at the
Box's private DNS name, such as http://job-1.acme.cubicle.internal:8000/. A team prepares one
template Box with its tools and creates each developer's Box from its snapshot. Every Box
hibernates 60 minutes after each start, whatever you are doing, so a session longer than an hour
needs another start; see Day to day.
Why a Box
- A full virtual machine. A Box boots its own Linux kernel and runs a whole Linux system, with systemd, an SSH server and user accounts. See Boxes.
- A persistent disk. Your repositories, packages and settings stay on the Box's disk across stop, start and hibernation.
sudofor people. Once you have added an SSH key, your guest account in the Box has passwordlesssudo. See The guest account and sudo.- A private DNS name. Services in the Box are reachable from your laptop on their own ports
at
<box>.<org>.cubicle.internal, and nothing is exposed to the internet. - A desktop console. The Dashboard shows the Box's graphical desktop for programs that need a screen. See Use the desktop console.
- A team baseline. Snapshot one prepared Box and create every developer's Box from the snapshot. See Build a template Box.
How it works
The cubicle CLI and its tunnel, a root network helper, hold a WireGuard connection from your
laptop to Cubicle's Gateway, which forwards traffic only to the Boxes you hold a grant on.
cubicle ssh and cubicle ssh-config write an OpenSSH alias for a Box, with its host key pinned,
so ssh, scp, rsync and Remote-SSH extensions connect to port 22 on the Box's private address
as your own guest account. Other ports in the Box are reachable the same way, by the Box's private
DNS name. Connections only go from your laptop to the Box, and the Box reaches the public IPv4
internet for packages and Git. Networking describes the full path.
Before you begin
- A Cubicle account. Cubicle is invite-only.
- Membership in an organization that can create Boxes,
acmein the examples. A personal organization starts with Box creation turned off; see Box creation approval. In a team where an owner or admin creates the Boxes, a developer needs only membership and a grant. - A laptop running macOS or Linux, on x64 or arm64, where you can use
sudo. Linux also needs systemd-resolved; see platform requirements. Windows is not supported. - A network that allows outbound UDP to Gateway. WireGuard uses only UDP.
- For an editor: VS Code or Cursor with its Remote-SSH extension.
Set up a development Box
-
Install the CLI and the tunnel. The installer asks before it installs the CLI, and
--tunnelthen installs the tunnel, which runssudoand asks for your password.curl -fsSL https://api.cubicle.sh/downloads/install | sh -s -- --tunnel cubicle tunnel status # installed, disconnectedIf
cubicleis not found, add~/.local/binto yourPATH; see Install the CLI. -
Log in. The CLI prints a link and a code; press Enter to open the browser and confirm the code there.
cubicle login # Logged in as dev@example.com. -
Add your SSH public key. Cubicle accepts only
ssh-ed25519keys, and without an argument the CLI reads~/.ssh/id_ed25519.pub.ssh-keygen -t ed25519 # only if ~/.ssh/id_ed25519 does not exist yet cubicle keys add # added SHA256:… -
Create a Box sized for development. The
defaultbase image is Debian-based, and its default size of 2 vCPUs, 2048 MiB of memory and a 12 GiB disk is small for builds. A Box can have up to 64 vCPUs, 262,144 MiB of memory and a 2048 GiB disk; see Limits.cubicle boxes create --org acme job-1 --vcpus 4 --memory 8192 --disk 40 --wait # 0b3f6c2e-8d4a-4f6e-9c1d-7a2b5e8f9d10 acme/job-1 running desired=running@1 node=worker-1 ssh=ready- A Box cannot be resized, so choose its size now.
- Its vCPUs, memory and disk stay reserved while it is stopped or hibernated. When no Node has
room, create fails with
503 capacity. - You created the Box, so you hold a grant on it.
-
Open a shell in the Box.
cubicle sshconnects the tunnel, writes the aliascubicle-acme-job-1and runssshas your guest account.cubicle ssh acme/job-1Install your tools with
sudo, for examplesudo apt-get update && sudo apt-get install -y git, and clone your repository. -
Connect VS Code or Cursor. The tunnel stays connected after
sshexits; if it is not, runcubicle connect. In the editor, run Remote-SSH: Connect to Host… and enter the aliascubicle-acme-job-1. The editor reads the same~/.ssh/config, so the pinned host key and your key apply. For a Box you have not opened withcubicle sshyet, write its alias first:cubicle ssh-config acme/job-1 # configured: ssh cubicle-acme-job-1 -
Run a dev server in the Box, listening on all interfaces, and open it from your laptop:
# In the Box python3 -m http.server 8000 --bind 0.0.0.0Open
http://job-1.acme.cubicle.internal:8000/in your laptop's browser, or runcurl http://job-1.acme.cubicle.internal:8000/.-
Any port works, except TCP 5900, which leads to the desktop console.
-
A server that listens only on
127.0.0.1is not reachable by name. Start it with its host option set to0.0.0.0, or forward its port over SSH and openhttp://localhost:8000/:ssh -N -L 8000:localhost:8000 cubicle-acme-job-1 -
Private names have no HTTPS certificates. Use plain HTTP, or the forwarded
localhostport when your app needslocalhostas its address. -
If your dev server accepts only host names it knows, allow
job-1.acme.cubicle.internalin its settings.
-
SSH into a Box and Reach a Box over the private network cover each step's options and errors.
Set up a team
An owner or admin of the organization prepares a template once and gives each developer a Box made from it.
-
Add each developer to the organization. They need a Cubicle account first, so ask a Cubicle operator to invite anyone who has none.
cubicle members add --org acme dev@example.com --role member # dev@example.com is member -
Build the template Box as a person, over SSH: commands that a service account sends cannot rely on
sudo. Its disk is the smallest disk a Box made from it can have, so keep it small.cubicle boxes create --org acme template --disk 20 --wait cubicle ssh acme/templateIn the Box, install the team's tools system-wide, with packages or into
/usr/local/bin, not into your home directory. Each developer gets their own account and home directory. Then remove your credentials, tokens and shell history, andexit. Prepare the template Box has the details. -
Stop the template Box and snapshot it. Note the snapshot's ID.
cubicle boxes stop acme/template --wait cubicle snapshot acme/template template-v1 # snapshot template-v1: done cubicle snapshots acme/template # SNAPSHOT_ID template-v1 complete 2026-11-05T10:04:12.000Z -
Create each developer's Box from the snapshot, then grant it to them by user ID, the first column of
cubicle members list --org acme:cubicle boxes create --org acme job-1 --snapshot SNAPSHOT_ID --vcpus 4 --memory 8192 --disk 40 --wait cubicle grants add acme/job-1 6b9e0d2c-41af-4c3b-8e2d-5f7a9c1b3d4eYou created the Box, so you hold a grant on it too. Remove yours with
cubicle grants rm acme/job-1 YOUR_USER_IDif you do not need it. -
Each developer follows steps 1 to 3 and 5 to 7 of Set up a development Box with their own Box.
- One Box per developer. Anyone with a grant and an SSH key has root in the Box and can read every home directory in it, including tokens and keys. See The virtual machine is the isolation boundary.
- Who gets grants. Grant each developer their own Box. Only owners and admins add grants, and they need a grant themselves to SSH into a Box. A member who holds a grant on the template Box can create Boxes from its snapshot themselves, but that grant also lets them SSH into the template. See Box grants.
- Give a teammate access. To pair on a Box, an owner or admin runs
cubicle grants add acme/job-1 USER_IDwith the teammate's ID. The teammate then usescubicle ssh acme/job-1with their own guest account andsudo, or opens the dev server by name, which needs no SSH key.cubicle grants rm acme/job-1 USER_IDends their access; their files stay on the disk. See Grant access to a Box. - Know the template's limits. Every Box made from the snapshot runs on the template Box's Node and shares its capacity, and the snapshot holds the template builder's home directory. See Know the limits first.
- Update the baseline. Change the template, take a snapshot with a new name such as
template-v2, and create new Boxes from it. Existing Boxes do not change. See Update the template.
Day to day
A Box hibernates 60 minutes
after its start first reports running, whatever you are doing:
-
SSH sessions, editor connections, builds, console use and network traffic do not extend the hour. You cannot turn automatic hibernation off or change the hour.
-
Only a start resets it. Starting a running Box again gives it a fresh 60 minutes without a reboot, but SSH and private-network traffic pause until its Node has applied the start, and open connections may drop.
-
To see when it happens, read
hibernateAt, or look at Hibernation on the State tab of the Box's details in the Dashboard, which counts down the minutes.cubicle boxes get acme/job-1 | jq -r .hibernateAt # 2026-11-05T11:02:17.000Z
What happens to your work:
| Hibernate, automatically or on request | Stop | Delete | |
|---|---|---|---|
| Files on the disk | Kept | Kept | Deleted, with every snapshot of it |
| Memory and running processes, such as a dev server | Kept: they carry on when the Box starts again | Lost: the next start is a cold boot | Lost |
| Open SSH sessions and editor connections | End | End | End |
| Private DNS name, address, host key and grants | Kept | Kept | Gone |
What stop, hibernate and delete keep
has the full list. The CLI has no hibernate command: to hibernate a Box now, use Hibernate
in its row on the Dashboard's Boxes page.
To pick up after hibernation:
-
Start the Box. A hibernated Box resumes from its saved memory.
cubicle boxes start acme/job-1 --waitIn the Dashboard, use Resume in the Box's row on the Boxes page.
cubicle sshdoes not start a Box: on a hibernated one it fails withbox has no trusted host key or guest account yet (not_requested); retry when it is running. -
Reconnect with
cubicle ssh acme/job-1, or reconnect the editor tocubicle-acme-job-1. The alias and the pinned host key still apply. The Box is routed to your laptop again within about 10 seconds of being ready. After your laptop restarts, runcubicle connectfirst, or usecubicle ssh, which connects.
- A program you start in an SSH session can end when that session ends. Run a dev server you want
to keep across reconnects outside the session, for example with
nohup, in a terminal multiplexer such astmuxthat you install, or as a systemd service. - At the end of the day you need not do anything: the Box hibernates within the hour. Stop it with
cubicle boxes stop acme/job-1 --waitwhen you want a clean boot next time or before a snapshot. Either way it keeps its vCPUs, memory and disk reserved. - Do not shut down or reboot from inside the Box. The Box goes to
failed; start it again. - When the host under a Box restarts, a Box that was running stays stopped, with
restartRequired: true, until you start it, and its memory is lost. See A host restart needs an explicit start. - Push your work to a Git remote. A Box's disk and its snapshots live on one Node, and deleting the Box deletes them for good.
- Your CLI login lasts 30 days. When it expires, run
cubicle login, thencubicle connect.
Stop, hibernate and wake a Box has the steps in the SDK, the API and the Dashboard.
Limits
These come from Cubicle, not from your editor. Not available yet lists what is planned.
- No public URLs. Cubicle has no public URLs, port forwarding or proxies to the internet. A dev server is reachable only from laptops connected to the private network with a grant on the Box, so you cannot share a preview link or receive webhooks from the internet.
- No connections from the Box to you. A Box cannot open connections to your laptop or to
other Boxes, and SSH remote forwarding (
-R) is disabled. A dev server in the Box cannot use a database on your laptop or in a teammate's Box. - No agent or X11 forwarding. Your laptop's SSH agent is not available in the Box. For Git over SSH, create a key in the Box and add it to your Git host, or use HTTPS. Use the desktop console for graphical programs.
- IPv4 only. The tunnel carries IPv4, and IPv6 is disabled in the Box.
- macOS and Linux laptops only. The CLI and the tunnel do not run on Windows.
- One operating-system user per laptop. The tunnel serves the user who installed it, with one Cubicle login at a time. Its routes are system-wide, so every user and program on the laptop can reach your Boxes, including the console on port 5900, which has no password. See Limitations.
- API keys cannot use SSH or the private network. CI jobs and SDK code can run commands in a Box with exec, but cannot reach its ports.
- No always-on Box. Every Box hibernates 60 minutes after each start.
- No resize or rename. To change a Box's size, snapshot it and create a new Box from the
snapshot; its disk can grow but not shrink. The new Box has its own name, address, DNS name and
host key, so run
cubicle ssh-configfor it. - x86-64 Linux without a GPU. Boxes run x86-64 Linux on a kernel that Cubicle manages, and their desktops render in software.
- One Node per template. Every Box made from one snapshot runs on the same Node. When that
Node is full, create fails with
503 capacity.
Related
- SSH into a Box: keys, aliases, host keys, forwarding and SSH errors.
- Reach a Box over the private network: the tunnel, private DNS names and services on other ports.
- Use the desktop console: the Box's graphical desktop in the browser or a VNC client.
- Build a template Box: prepare, snapshot and update a team baseline.
- Stop, hibernate and wake a Box: hibernation in detail.
- Manage organization members: members, roles and grants.
- Box lifecycle: states, automatic hibernation and what each action keeps.
Run CI jobs in Boxes
Run each CI job or scripted task in a fresh Cubicle Box created with a service account API key, with a GitHub Actions workflow that runs tests in a new Box per run, cleanup of leftover Boxes, the cubicle CLI with CB_CLI_API_KEY in shell scripts, grants on existing Boxes and what a CI job cannot do in a Box.
How-to guides
Find the Cubicle how-to guide for one task, from running commands, moving files and SSH to the private network, the desktop console, snapshots, templates, hibernation and organization members.

