# Workspaces

> A GPU or CPU development machine with a saved home directory, reached with SSH, VS Code or JupyterLab.

Source: https://www.nodus-compute.ai/docs/guides/workspaces/
Build revision: 53bfc045e800bf7bb44fa18623013c7aa9c9971e

Instances and Workspaces give you your own development environment: a GPU or CPU machine with VS Code in the browser, JupyterLab and SSH. Its home directory, `/home/nodus`, lives on a Volume and is saved every time the Workspace stops, so you can stop it at the end of the day and pick up where you left off. While it is stopped you pay only for the saved files.

You need the `nodus` CLI to connect over SSH ([install it](https://www.nodus-compute.ai/docs/getting-started/) and run `nodus login`). Browser VS Code and JupyterLab need only the console.

## Launch from the console

1. Open **Instances** and choose **Launch instance**, or open **Workspaces › New workspace**.
2. Click anywhere on a GPU model or CPU row. NVIDIA rows show the NVIDIA mark; CPU rows show a chip icon. Review its availability and hourly estimate.
3. Choose **Launch**. When it is ready, open the **Terminal**, **Browser VS Code** or **JupyterLab**.

The console supplies a name, compatible Python/PyTorch environment and saved home folder. Local storage defaults to 100 GiB, or the machine’s capacity when smaller, with a minimum of 80 GiB. **Advanced settings** lets you change these defaults, add limits or schedules, or opt into an ephemeral home. Leave local storage empty to choose it automatically. An explicit size or recovered home’s disk requirement is preserved when you change hardware. You do not need a startup command, SSH key or CLI to use the browser tools. Each GPU model appears once. Choose its region, GPU variant, GPUs per machine and on-demand or interruptible capacity in the launch summary. Options show currently available configurations; changing one updates the machine, CPU, RAM and price together. CPU rows group matching core counts, with region and machine options in the same summary. Availability refreshes every two minutes without clearing the table or your selection. The launcher requires a positive reported machine count. Hardware with unknown stock cannot be selected, and a selection that loses confirmed stock must be replaced before launch. Reported stock is not a reservation; capacity is checked again when compute starts. Direct hardware links fill in the machine’s CPU and RAM while preserving any explicit resource requirements.

Instances and Workspaces share the same `Workspace` API and lifecycle. The console keeps them in separate lists. They also share the organization’s instance and workspace limit across all projects. Stopped machines still count toward that limit. If it is full, start an existing machine, delete one you no longer need, or request an increase from **Settings › Quotas**. The launcher shows the current usage and links to both lists.

If compute cannot start yet, its detail page shows the current scheduling reason. You can wait or stop the machine before changing its configuration. **Logs** shows environment output; commands run in the browser terminal show their output in that terminal.

The console keeps quiet browser terminals connected while you use other tools. If your network disconnects, close and reopen the terminal to start a new shell. Your saved files stay in the home directory.

## Create with the CLI

Terminal window

```console
$ nodus create workspace lab --gpu H100
$ nodus get workspaces
NAME   PHASE     COMPUTE    HOME       STOP-REASON   COST    AGE
lab    Running   1 × H100   lab-home                 $0.09   3m
```

`--gpu H100:2` asks for two GPUs; `--cpu 8 --memory 32Gi` without `--gpu` creates a CPU Workspace. The home Volume is `lab-home`, created on the first start if it does not exist; set `spec.volume` to use another one. The default image is `nodus/workspace-pytorch-cuda` (PyTorch and CUDA) on NVIDIA GPUs, `nodus/workspace-rocm` on AMD GPUs and `nodus/workspace-cpu` on CPU. Every catalog image has VS Code, JupyterLab, Python and the user `nodus`. Custom images must declare an `ENTRYPOINT` or `CMD` that starts their tools. Nodus preserves those arguments from the pinned image, including when restarting after the image tag changes.

The same Workspace as a manifest, applied with `nodus apply -f workspace.yaml`:

workspace.yaml

```yaml
apiVersion: nodus.dev/v1
kind: Workspace
metadata:
  name: ws-home
spec:
  image: nodus/workspace-cpu
  resources:
    cpu: "2"
    memory: 8Gi
  volume: ws-home-home
  idleTimeout: 30m
```

The console also shows the manifest, CLI command and Python equivalent under **Advanced settings**. Your hardware selection preserves its GPU count, memory and interruption policy through review and launch. An unspecified region leaves location unrestricted. Available capacity can change before launch.

To use your organization’s enrolled hardware, set `spec.placement.pool` to its Pool name in the manifest. Accept Route pricing on the Pool first. A Pool configured with `routing.mode: Only` waits for an eligible free host; the Workspace pays the Pool’s Route fee for its assigned GPUs. See [Pools](https://www.nodus-compute.ai/docs/guides/pools/) for enrollment and routing settings.

For assigned private GPU capacity, use the [dedicated pool guide](https://www.nodus-compute.ai/docs/guides/workspaces/private-capacity/) (Beta). It keeps the Workspace on the selected pool and shows its routing fee separately from the capacity contract.

## Connect

### SSH

Terminal window

```console
$ nodus login
$ nodus ssh workspace/lab
nodus@lab:~$ nvidia-smi
$ nodus ssh workspace/lab -- python train.py --epochs 1
```

Sign in once with `nodus login` on each computer using an up-to-date CLI and OpenSSH 8.5 or newer. Login creates a dedicated local SSH key for your account, registers only its public key, and configures every existing and future CPU or GPU Workspace in the organizations you selected. New Workspaces need no separate setup. Your private key stays on your computer with owner-only permissions; sign-in does not start or connect to a Workspace.

Each teammate signs in to their own account. Organization roles and project access determine which Workspaces they can enter. Remove a device’s key under **Account › SSH keys** to revoke it. Removing a teammate’s access also prevents their keys from opening that organization’s Workspaces.

`nodus ssh` connects through the Nodus gateway. No port is open on the machine. OpenSSH verifies the Workspace’s host key against the authenticated API on every connection, with strict host-key checking. A missing or revoked identity fails closed; it does not trust a host key on first use.

### VS Code Remote-SSH, Cursor and JetBrains Gateway

After `nodus login`, open **Desktop VS Code** or **Cursor** in the console, or select the Workspace host in your editor’s Remote-SSH connection dialog. The same account key works for all your authorized Workspaces, including ones created later. Signing in to the website alone cannot configure SSH on your computer.

The `.nodus` host is an SSH alias, not a public DNS address. Login records the CLI executable and saved context, so editors do not depend on your terminal’s environment. Plain `ssh`, `scp` and `rsync` use the same connection. `nodus ssh workspace/lab --config` prints the rule; `nodus ssh workspace/lab --setup` is an optional repair command. Neither command starts or connects to a Workspace.

### Browser terminal, VS Code and JupyterLab

Open the instance or Workspace and choose **Open terminal**, **Browser VS Code** or **JupyterLab**. The terminal runs inside your environment using your console sign-in. Both open on a private address that only members of your organization can reach after signing in.

## Stop, start and what is saved

Terminal window

```console
$ nodus stop workspace/lab
$ nodus start workspace/lab
```

When a Workspace stops, everything in `/home/nodus` is saved to its home Volume and the machine is released. Everything else is temporary, including the `/workspace` directory (the container’s working directory, which has nothing to do with the Workspace kind) and anything installed outside your home. Install Python packages with `pip install --user` or in a virtual environment under `/home/nodus` to keep them.

The next start restores the saved home on a fresh machine. Use `ephemeral: true` for a Workspace with no home Volume, whose files are deleted on stop.

If a stopped environment offers **Update runtime**, confirm it to use the current default environment while keeping your saved home. The update leaves compute stopped. Choose **Start** afterward to review the current price. Ordinary starts keep the same runtime version; updating it is an explicit choice.

A Workspace also stops by itself:

|Stop reason|When|How it starts again|
|-|-|-|
|`Idle`|No SSH session, editor traffic or process for `idleTimeout` (default `1h`)|Connect, open a tool, or `nodus start`|
|`Schedule`|At `schedule.stopAt`|The next `schedule.readyBy`, connecting, or `nodus start`|
|`InsufficientCredits`, `BudgetExceeded`, `MaxCostReached`|Money ran out or a limit was reached|Add credits or raise the limit, then connect or `nodus start`|
|`User`|You ran `nodus stop` or chose **Stop**|Only `nodus start` or **Start**|

Connecting to a Workspace that stopped by itself starts it; `nodus ssh` waits and connects when it is ready. The console requests a fresh quote before a connect or Start wakes a stopped Workspace. Review the numeric rate and confirm Start. If the price or configuration changes, refresh and review the new estimate.

While stopped, open **Details** to change hardware, runtime, disk size, idle timeout or your cost limit. Your next Start uses those settings. If a save fails, the console identifies the failure and distinguishes the last successful revision from the latest unsaved work.

### Schedules

```yaml
spec:
  schedule:
    readyBy: "2026-10-01T09:00:00-07:00"
    stopAt: "2026-10-01T19:00:00-07:00"
```

The Workspace starts 15 minutes before `readyBy` so it is ready on time, and stops at `stopAt`. It records a `ScheduledStart` event, or `ScheduleMissed` when it could not start in time.

An unchanged schedule may stay on the Workspace after its times have passed. You can still stop the Workspace or edit its labels. New or changed `readyBy` values must be at least 15 minutes ahead, and new or changed `stopAt` values must be in the future.

## Run a job on your Workspace files

Terminal window

```console
$ nodus run --from workspace/lab -- python train.py
```

Submitting the Job saves the running Workspace’s current home and pins that revision as a read-only input. For a stopped Workspace, it uses the last saved revision. Later edits to the home do not change the Job’s input, and retrying the same named Job keeps its original revision. Home history pruning keeps revisions referenced by saved Jobs. A dry run checks the request without saving the home. The Job is labelled `nodus.dev/workspace=lab`, so the Workspace’s **Jobs from this workspace** list shows it. Home inputs require a persistent Workspace in the same project and permission to write that Workspace. A Job can select multiple subdirectories from one Workspace with `inputs[].fromWorkspace.path`.

## Sessions and spending limits

Each period a Workspace runs is a session, recorded as an Attempt with its receipt:

Terminal window

```console
$ nodus get attempts -l nodus.dev/workspace=lab
```

`maxCostUSD` stops and saves the Workspace when its cost reaches the limit; raising the limit lets it start again. In the console, select **Raise limit** to open that field in **Details**, save a higher amount, then review the current price and start the Workspace again.

## Shared access

A Workspace belongs to its project. Every member of the organization with access to the project can see it, start it and connect with their own account and SSH key; `spec.sshKeys` limits SSH to the keys you name.

## When a Workspace fails

A Workspace in the `Failed` phase does not restart. Delete it and create it again with the same name (or the same `spec.volume`): the home Volume keeps your files.

Terminal window

```console
$ nodus delete workspace/lab
$ nodus create workspace lab --gpu H100
```

To delete the saved files too, delete the home Volume (`nodus delete volume/lab-home`), or empty it with `nodus volume clear lab-home`.
