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

# Persistent sandboxes

> A persistent Linux workspace with a URL, SSH, and optional coding-agent CLIs

A persistent, exposed sandbox is a Linux workspace that stays running. Your
files, installed packages, processes, and local databases remain there between
visits. Turn the capabilities on at creation — persistence with `--persistent`
and a published hostname with `--expose` — and you get:

* A stable `<name>-box.run.cloud` URL for your app
* SSH access without exposing a public SSH port
* VS Code Remote SSH
* File transfer with `scp`
* Optional custom domains with managed HTTPS

Earlier releases called this combination a "box" with its own `runcloud box`
command group. Those commands still work as deprecated aliases — see the
[CLI reference](/cli/latest) for the mapping.

## Create a persistent, exposed sandbox

With `--expose`, the CLI creates a non-pausing sandbox with 2 CPU and 24 GiB
of memory, then attaches its hostname:

```bash theme={null}
runcloud sandbox create --name my-project --expose 3000
```

Override either allocation directly when a different shape is needed:

```bash theme={null}
runcloud sandbox create --name my-project --expose 3000 --cpu 4 --memory 32768
```

Start your web process inside the sandbox on the exposed port, such as `3000`.

To publish a hostname on a sandbox you already have, expose it after the fact
(it must have been created with `--persistent` or `--idle-pause 0`):

```bash theme={null}
SANDBOX_ID=$(runcloud sandbox create \
  --image runcloud/box \
  --name my-project \
  --persistent \
  --json | jq -r '.id')
runcloud sandbox expose "$SANDBOX_ID" --port 3000
```

The exposure response includes the stable URL:

```json theme={null}
{
  "id": "box-id",
  "sandboxId": "sbx_...",
  "hostname": "my-project-box.run.cloud",
  "url": "https://my-project-box.run.cloud",
  "port": 3000,
  "status": "ready"
}
```

Hostname names are lowercase DNS labels. A sandbox can have one active
hostname.

## Coding-agent image

Use `runcloud/box-agent` when you want Claude Code and Codex preinstalled:

```bash theme={null}
runcloud sandbox create --name my-project --expose 3000 --image runcloud/box-agent
```

Connect over SSH and start either CLI in `/workspace`:

```bash theme={null}
runcloud sandbox ssh my-project
cd /workspace
claude
# or
codex
```

The image contains no provider credentials. Authenticate with Anthropic or
OpenAI after connecting. Use the regular `runcloud/box` image when you want the
same persistent development environment without preinstalled coding agents.

## SSH

The first setup generates a dedicated key, installs its public half in the
sandbox, and adds a managed host entry to `~/.ssh/config`:

```bash theme={null}
runcloud sandbox setup-ssh my-project
ssh runcloud-my-project
```

You can also skip the second command:

```bash theme={null}
runcloud sandbox ssh my-project
runcloud sandbox ssh my-project -- git status
```

Run Cloud carries SSH over an authenticated connection. You do not need to open
port 22, manage an IP allowlist, or keep a long-lived access token in the SSH
config.

## VS Code Remote SSH

Install Microsoft's **Remote - SSH** extension, then run:

```bash theme={null}
runcloud sandbox code my-project
```

The CLI creates the same SSH configuration used by the terminal and opens
`/workspace` in VS Code. You can also choose `runcloud-my-project` from
**Remote-SSH: Connect to Host**.

## Copy files

Prefix the path inside the sandbox with `:`. Upload a file:

```bash theme={null}
runcloud sandbox cp my-project ./data.sqlite :/workspace/data.sqlite
```

Download it again:

```bash theme={null}
runcloud sandbox cp my-project :/workspace/data.sqlite ./data.sqlite
```

Copy a directory recursively:

```bash theme={null}
runcloud sandbox cp my-project --recursive ./assets :/workspace/assets
```

Because setup uses standard SSH configuration, existing tools such as `scp`,
`rsync`, SFTP clients, and Git-over-SSH can use the `runcloud-my-project` host
too.

## Custom domains

Attach a hostname you control:

```bash theme={null}
runcloud sandbox domain add my-project app.example.com
```

The response tells you which CNAME (or flattened ALIAS at an apex) and any
verification records to add at your DNS provider. Once DNS is in place, check
certificate status:

```bash theme={null}
runcloud sandbox domain list my-project
runcloud sandbox domain status my-project "$DOMAIN_ID"
```

Traffic moves to your sandbox when both `status` and `sslStatus` are `active`.
HTTPS certificates are issued and renewed automatically.

Remove a domain without deleting the sandbox:

```bash theme={null}
runcloud sandbox domain rm my-project "$DOMAIN_ID"
```

## Change the public port

```bash theme={null}
runcloud sandbox expose "$SANDBOX_ID" --port 8080
```

The hostname stays the same while traffic moves to the new port.

## List and inspect

Exposed sandboxes show their hostname in the regular listing:

```bash theme={null}
runcloud sandbox list
runcloud sandbox get "$SANDBOX_ID"
```

If route activation was interrupted, retry it without replacing the hostname:

```bash theme={null}
runcloud sandbox expose "$SANDBOX_ID" --reconcile
```

## Delete

```bash theme={null}
runcloud sandbox rm "$SANDBOX_ID"
```

Destroying an exposed sandbox removes its public hostname and the sandbox
together.
