> ## Documentation Index
> Fetch the complete documentation index at: https://docs.generalrobotics.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Remote Nodes & Client Mode

This guide covers everything you need to operate GRID Enterprise beyond a single workstation: preparing remote container servers, updating `resource_config.json`, switching between host and client mode, and targeting remote machines from the CLI.

## Prepare Each Remote Server

Every GRID node that hosts containers must run the **container server**—a lightweight FastAPI service that manages Docker lifecycle tasks on behalf of the CLI. Think of it as the daemon that receives commands such as “init”, “update”, and “session start” and executes them on the host.

1. **Install GRID Enterprise** on the remote machine (same prerequisites as the [installation guide](./installation)). A lightweight Python environment is sufficient:
   ```bash theme={null}
   conda create -n grid-server python=3.11
   conda activate grid-server
   pip install "grid-enterprise[server]"
   ```
   The optional `[server]` extra installs the dependencies required to run the container server.
2. **Set up data and licensing** on the remote host:
   ```bash theme={null}
   export GRID_DATA_DIR=/opt/grid   # or ~/.grid
   mkdir -p "$GRID_DATA_DIR"
   cp /path/to/license.json "$GRID_DATA_DIR/license.json"
   ```
3. **Launch the container server**. It keeps running until you stop it (run it in a tmux session, systemd service, or similar):
   ```bash theme={null}
   grid-server --host 0.0.0.0 --port 8060
   ```
   The CLI and container server authenticate via a bearer token. By default both sides use `grid-enterprise-token`; set `GRID_API_TOKEN` to the same value on the server and client if you change it.

## Resource Configuration Refresher

GRID reads its topology from `~/.grid/resource_config.json`. A freshly installed CLI generates the minimal configuration that assumes host mode on the current machine:

```json theme={null}
{
  "serve": true,
  "servers": [
    {
      "id": "local",
      "ip": "127.0.0.1"
    }
  ]
}
```

* **`serve`** – when `true`, the CLI is allowed to run containers locally. Setting it to `false` turns the CLI into a pure client that only orchestrates remote servers.
* **`servers`** – an array of nodes that the CLI can target. Each entry must include an `id` (used with the `@id` syntax) and an `ip`. Additional fields, such as `storage`, are optional.

Place the file at `~/.grid/resource_config.json` (or inside the directory referenced by `GRID_DATA_DIR` if you customised it during installation).

## Switching to Client Mode

If the containers will run on dedicated hosts and your workstation should only issue commands, set `serve` to `false`:

```json theme={null}
{
  "serve": false,
  "servers": [
    {
      "id": "node0",
      "ip": "10.0.0.25"
    }
  ]
}
```

With this flag disabled the CLI no longer spins up a local container server. Every command must specify the node it should operate on, either explicitly (`@node0`) or by selecting a default.

## Adding Remote Nodes

Declare each remote machine in the `servers` array. Here is a typical entry:

```json theme={null}
{
  "id": "lab-gpu-0",
  "ip": "10.40.0.10",
  "storage": {
    "datasets": "/opt/grid/datasets",
    "notebooks": "/opt/grid/notebooks"
  }
}
```

The optional `storage` block is covered in detail in [Mounting Storage](./mounting-storage); it lets you bind host directories into the GRID containers.

Save the file and restart the CLI to pick up the changes.

## Connect from the Client

On the workstation where you operate the CLI, run:

```bash theme={null}
grid
```

If `serve` is `false`, the CLI starts in client-only mode and immediately connects to the remote container server whenever you invoke a command. If `serve` is `true`, the CLI still runs locally but can target additional nodes that you configured.

## Working with Nodes in the CLI

Within the shell, use the `node` commands to inspect and select targets:

```bash theme={null}
node list
node select lab-gpu-0
```

Once you have a default node, all subsequent commands act on it unless you override the target:

```bash theme={null}
init isaac @lab-gpu-0
session start qa-run configs/session.json @lab-gpu-0
open nb @lab-gpu-0
```

If you forget to provide `@<id>`, the CLI warns you and falls back to the current default.

## Network & Access Checklist

Remote nodes must be reachable by the CLI and your browser:

* **8060** from the CLI machine (container server API)
* **8000** from the CLI machine (session API)
* **8890**, **3080**, **9090**, **9877** from your browser if you plan to open notebooks, simulations, or rerun visualisations

Make sure the Docker daemon and NVIDIA GPU drivers on each node match the requirements listed in the installation guide.

With remote nodes configured, you’re ready to keep local datasets in sync via mounts—continue to [Mounting Storage](./mounting-storage) for the details.
