# Configuration

## getSandbox Options

```typescript
const sandbox = getSandbox(env.Sandbox, 'sandbox-id', {
  normalizeId: true,         // lowercase ID (required for preview URLs)
  sleepAfter: '10m',         // sleep after inactivity: '5m', '1h', '2d' (default: '10m')
  keepAlive: false,          // false = auto-timeout, true = never sleep
  
  containerTimeouts: {
    instanceGetTimeoutMS: 30000,  // 30s for provisioning (default: 30000)
    portReadyTimeoutMS: 90000     // 90s for container startup (default: 90000)
  }
});
```

**Sleep Config**:
- `sleepAfter`: Duration string (e.g., '5m', '10m', '1h') - default: '10m'
- `keepAlive: false`: Auto-sleep (default, cost-optimized)
- `keepAlive: true`: Never sleep (higher cost, requires explicit `destroy()`)
- Sleeping sandboxes wake automatically (cold start)

## Instance Types

wrangler.jsonc `instance_type`:
- `lite`: 256MB RAM, 0.5 vCPU (default)
- `standard`: 512MB RAM, 1 vCPU
- `heavy`: 1GB RAM, 2 vCPU

## Dockerfile Patterns

**Basic**:
```dockerfile
FROM docker.io/cloudflare/sandbox:latest
RUN pip3 install --no-cache-dir pandas numpy
EXPOSE 8080  # Required for wrangler dev
```

**Scientific**:
```dockerfile
FROM docker.io/cloudflare/sandbox:latest
RUN pip3 install --no-cache-dir \
    jupyter-server ipykernel matplotlib \
    pandas seaborn plotly scipy scikit-learn
```

**Node.js**:
```dockerfile
FROM docker.io/cloudflare/sandbox:latest
RUN npm install -g typescript ts-node
```

**CRITICAL**: `EXPOSE` required for `wrangler dev` port access. Production auto-exposes all ports.

## CLI Commands

```bash
# Dev
wrangler dev                    # Start local dev server
wrangler deploy                 # Deploy to production
wrangler tail                   # Monitor logs
wrangler containers list        # Check container status
wrangler secret put KEY         # Set secret
```

## Environment & Secrets

**wrangler.jsonc**:
```jsonc
{
  "vars": {
    "ENVIRONMENT": "production",
    "API_URL": "https://api.example.com"
  },
  "r2_buckets": [{
    "binding": "DATA_BUCKET",
    "bucket_name": "my-data-bucket"
  }]
}
```

**Usage**:
```typescript
const token = env.GITHUB_TOKEN;  // From wrangler secret
await sandbox.exec('git clone ...', {
  env: { GIT_TOKEN: token }
});
```

## Preview URL Setup

**Prerequisites**:
- Custom domain with wildcard DNS: `*.yourdomain.com → worker.yourdomain.com`
- `.workers.dev` domains NOT supported
- `normalizeId: true` in getSandbox
- `proxyToSandbox()` called first in fetch handler

## Cron Triggers (Pre-warming)

```jsonc
{
  "triggers": {
    "crons": ["*/5 * * * *"]  // Every 5 minutes
  }
}
```

```typescript
export default {
  async scheduled(event: ScheduledEvent, env: Env) {
    const sandbox = getSandbox(env.Sandbox, 'main');
    await sandbox.exec('echo "keepalive"');  // Wake sandbox
  }
};
```

## Logging Configuration

**wrangler.jsonc**:
```jsonc
{
  "vars": {
    "SANDBOX_LOG_LEVEL": "debug",  // debug | info | warn | error (default: info)
    "SANDBOX_LOG_FORMAT": "pretty" // json | pretty (default: json)
  }
}
```

**Dev**: `debug` + `pretty`. **Production**: `info`/`warn` + `json`.

## Timeout Environment Overrides

Override default timeouts via environment variables:

```jsonc
{
  "vars": {
    "SANDBOX_INSTANCE_TIMEOUT_MS": "60000",  // Override instanceGetTimeoutMS
    "SANDBOX_PORT_TIMEOUT_MS": "120000"      // Override portReadyTimeoutMS
  }
}
```
