Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion docs/roo-code-cloud/environments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ keywords:
- mise
- Initial Path
- Subdomain Routing
- Proxied Ports
- Direct Port Access
---

# Preview Environments
Expand Down Expand Up @@ -91,6 +93,7 @@ ports:
|-------|-------------|----------|
| `name` | Identifier for the port (used to generate environment variables) | Yes |
| `port` | The port number to expose | Yes |
| `proxied` | Whether traffic goes through the auth proxy (`true` by default). Set to `false` for direct port access (see [Direct Port Access](#direct-port-access-non-proxied)) | No |
| `initial_path` | Default path to append to the preview URL | No |
| `subdomain` | Subdomain to set on the `Host` header when forwarding requests to the app | No |

Expand All @@ -113,7 +116,10 @@ The name is converted to uppercase for the environment variable (e.g., `web` bec

### Limits

You can configure up to **4 named ports** per environment.
Port limits depend on whether ports are proxied (default) or non-proxied:

- **Proxied ports** (default): up to **10** per environment. These share a single internal port slot via multiplexing.
- **Non-proxied ports** (`proxied: false`): up to **1** per environment. Each non-proxied port consumes a dedicated port slot.

### Initial Path

Expand Down Expand Up @@ -189,6 +195,35 @@ Invalid examples:
- **Admin panels**: Serve an admin interface on `admin.localhost:3000` while the main app runs on the root domain
- **Subdomain APIs**: Frameworks like Rails can use `api.localhost:3000` to route API requests to a separate controller namespace

### Direct Port Access (Non-Proxied)

By default, all ports are proxied through an authentication layer that validates requests before forwarding them to your application. Setting `proxied: false` bypasses this proxy and exposes the port directly on the sandbox domain.

```yaml
ports:
- name: WEB
port: 3000
- name: METRICS
port: 9090
proxied: false
```

Use `proxied: false` when you need:

- **Direct socket access** for protocols that don't work well through the HTTP proxy
- **Internal services** that handle their own authentication or don't need external access control

:::warning[Warning]
When `proxied` is `false`, the port is **completely exposed without authentication**, regardless of the `unauthenticated` setting. Only use this for ports that either handle their own security or don't serve sensitive content.
Comment thread
mrubens marked this conversation as resolved.
Outdated
:::

The `ROO_<NAME>_HOST` environment variable for a non-proxied port points to the direct sandbox domain instead of the preview proxy URL. Your application code doesn't need to change -- just use the injected variable as usual:

```typescript
// Works the same whether the port is proxied or not
const metricsUrl = process.env.ROO_METRICS_HOST || 'http://localhost:9090';
```

## Using Environment Variables in Your Code

Use the `ROO_<NAME>_HOST` variables instead of hardcoded URLs so your services can find each other in both preview and local environments:
Expand Down