|
| 1 | +# Customizing dev containers |
| 2 | + |
| 3 | +Coder supports custom configuration in your `devcontainer.json` file through the |
| 4 | +`customizations.coder` block. These options let you control how Coder interacts |
| 5 | +with your dev container without requiring template changes. |
| 6 | + |
| 7 | +## Custom agent name |
| 8 | + |
| 9 | +Each dev container gets an agent name derived from the workspace folder path by |
| 10 | +default. You can set a custom name using the `name` option: |
| 11 | + |
| 12 | +```json |
| 13 | +{ |
| 14 | + "name": "My Dev Container", |
| 15 | + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", |
| 16 | + "customizations": { |
| 17 | + "coder": { |
| 18 | + "name": "my-custom-agent" |
| 19 | + } |
| 20 | + } |
| 21 | +} |
| 22 | +``` |
| 23 | + |
| 24 | +The name must contain only lowercase letters, numbers, and hyphens. This name |
| 25 | +appears in `coder ssh` commands and the dashboard (e.g., |
| 26 | +`coder ssh my-workspace.my-custom-agent`). |
| 27 | + |
| 28 | +## Display apps |
| 29 | + |
| 30 | +Control which built-in Coder apps appear for your dev container using |
| 31 | +`displayApps`: |
| 32 | + |
| 33 | +```json |
| 34 | +{ |
| 35 | + "name": "My Dev Container", |
| 36 | + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", |
| 37 | + "customizations": { |
| 38 | + "coder": { |
| 39 | + "displayApps": { |
| 40 | + "web_terminal": true, |
| 41 | + "ssh_helper": true, |
| 42 | + "port_forwarding_helper": true, |
| 43 | + "vscode": true, |
| 44 | + "vscode_insiders": false |
| 45 | + } |
| 46 | + } |
| 47 | + } |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | +Available display apps: |
| 52 | + |
| 53 | +| App | Description | Default | |
| 54 | +|--------------------------|------------------------------|---------| |
| 55 | +| `web_terminal` | Web-based terminal access | `true` | |
| 56 | +| `ssh_helper` | SSH connection helper | `true` | |
| 57 | +| `port_forwarding_helper` | Port forwarding interface | `true` | |
| 58 | +| `vscode` | VS Code Desktop integration | `true` | |
| 59 | +| `vscode_insiders` | VS Code Insiders integration | `false` | |
| 60 | + |
| 61 | +## Custom apps |
| 62 | + |
| 63 | +Define custom applications for your dev container using the `apps` array: |
| 64 | + |
| 65 | +```json |
| 66 | +{ |
| 67 | + "name": "My Dev Container", |
| 68 | + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", |
| 69 | + "customizations": { |
| 70 | + "coder": { |
| 71 | + "apps": [ |
| 72 | + { |
| 73 | + "slug": "zed", |
| 74 | + "displayName": "Zed Editor", |
| 75 | + "url": "zed://ssh/${localEnv:CODER_WORKSPACE_AGENT_NAME}.${localEnv:CODER_WORKSPACE_NAME}.${localEnv:CODER_WORKSPACE_OWNER_NAME}.coder${containerWorkspaceFolder}", |
| 76 | + "external": true, |
| 77 | + "icon": "/icon/zed.svg", |
| 78 | + "order": 1 |
| 79 | + } |
| 80 | + ] |
| 81 | + } |
| 82 | + } |
| 83 | +} |
| 84 | +``` |
| 85 | + |
| 86 | +This example adds a Zed Editor button that opens the dev container directly in |
| 87 | +the Zed desktop app via its SSH remote feature. |
| 88 | + |
| 89 | +Each app supports the following properties: |
| 90 | + |
| 91 | +| Property | Type | Description | |
| 92 | +|---------------|---------|---------------------------------------------------------------| |
| 93 | +| `slug` | string | Unique identifier for the app (required) | |
| 94 | +| `displayName` | string | Human-readable name shown in the UI | |
| 95 | +| `url` | string | URL to open (supports variable interpolation) | |
| 96 | +| `command` | string | Command to run instead of opening a URL | |
| 97 | +| `icon` | string | Path to an icon (e.g., `/icon/code.svg`) | |
| 98 | +| `openIn` | string | `"tab"` or `"slim-window"` (default: `"slim-window"`) | |
| 99 | +| `share` | string | `"owner"`, `"authenticated"`, `"organization"`, or `"public"` | |
| 100 | +| `external` | boolean | Open as external URL (e.g., for desktop apps) | |
| 101 | +| `group` | string | Group name for organizing apps in the UI | |
| 102 | +| `order` | number | Sort order for display | |
| 103 | +| `hidden` | boolean | Hide the app from the UI | |
| 104 | +| `subdomain` | boolean | Use subdomain-based access | |
| 105 | +| `healthCheck` | object | Health check configuration (see below) | |
| 106 | + |
| 107 | +### Health checks |
| 108 | + |
| 109 | +Configure health checks to monitor app availability: |
| 110 | + |
| 111 | +```json |
| 112 | +{ |
| 113 | + "customizations": { |
| 114 | + "coder": { |
| 115 | + "apps": [ |
| 116 | + { |
| 117 | + "slug": "web-server", |
| 118 | + "displayName": "Web Server", |
| 119 | + "url": "http://localhost:8080", |
| 120 | + "healthCheck": { |
| 121 | + "url": "http://localhost:8080/healthz", |
| 122 | + "interval": 5, |
| 123 | + "threshold": 2 |
| 124 | + } |
| 125 | + } |
| 126 | + ] |
| 127 | + } |
| 128 | + } |
| 129 | +} |
| 130 | +``` |
| 131 | + |
| 132 | +Health check properties: |
| 133 | + |
| 134 | +| Property | Type | Description | |
| 135 | +|-------------|--------|--------------------------------------------------| |
| 136 | +| `url` | string | URL to check for health status | |
| 137 | +| `interval` | number | Seconds between health checks | |
| 138 | +| `threshold` | number | Number of failures before marking app unhealthy | |
| 139 | + |
| 140 | +## Variable interpolation |
| 141 | + |
| 142 | +App URLs and other string values support variable interpolation for dynamic |
| 143 | +configuration. |
| 144 | + |
| 145 | +### Environment variables |
| 146 | + |
| 147 | +Use `${localEnv:VAR_NAME}` to reference environment variables, with optional |
| 148 | +default values: |
| 149 | + |
| 150 | +```json |
| 151 | +{ |
| 152 | + "customizations": { |
| 153 | + "coder": { |
| 154 | + "apps": [ |
| 155 | + { |
| 156 | + "slug": "my-app", |
| 157 | + "url": "http://${localEnv:HOST:127.0.0.1}:${localEnv:PORT:8080}" |
| 158 | + } |
| 159 | + ] |
| 160 | + } |
| 161 | + } |
| 162 | +} |
| 163 | +``` |
| 164 | + |
| 165 | +### Coder-provided variables |
| 166 | + |
| 167 | +Coder provides these environment variables automatically: |
| 168 | + |
| 169 | +| Variable | Description | |
| 170 | +|-------------------------------------|------------------------------------| |
| 171 | +| `CODER_WORKSPACE_NAME` | Name of the workspace | |
| 172 | +| `CODER_WORKSPACE_OWNER_NAME` | Username of the workspace owner | |
| 173 | +| `CODER_WORKSPACE_AGENT_NAME` | Name of the dev container agent | |
| 174 | +| `CODER_WORKSPACE_PARENT_AGENT_NAME` | Name of the parent workspace agent | |
| 175 | +| `CODER_URL` | URL of the Coder deployment | |
| 176 | +| `CONTAINER_ID` | Docker container ID | |
| 177 | + |
| 178 | +### Dev container variables |
| 179 | + |
| 180 | +Standard dev container variables are also available: |
| 181 | + |
| 182 | +| Variable | Description | |
| 183 | +|-------------------------------|--------------------------------------------| |
| 184 | +| `${containerWorkspaceFolder}` | Workspace folder path inside the container | |
| 185 | +| `${localWorkspaceFolder}` | Workspace folder path on the host | |
| 186 | + |
| 187 | +### Session token |
| 188 | + |
| 189 | +Use `$SESSION_TOKEN` in external app URLs to include the user's session token: |
| 190 | + |
| 191 | +```json |
| 192 | +{ |
| 193 | + "customizations": { |
| 194 | + "coder": { |
| 195 | + "apps": [ |
| 196 | + { |
| 197 | + "slug": "custom-ide", |
| 198 | + "displayName": "Custom IDE", |
| 199 | + "url": "custom-ide://open?token=$SESSION_TOKEN&folder=${containerWorkspaceFolder}", |
| 200 | + "external": true |
| 201 | + } |
| 202 | + ] |
| 203 | + } |
| 204 | + } |
| 205 | +} |
| 206 | +``` |
| 207 | + |
| 208 | +## Feature options as environment variables |
| 209 | + |
| 210 | +When your dev container uses features, Coder exposes feature options as |
| 211 | +environment variables. The format is `FEATURE_<FEATURE_NAME>_OPTION_<OPTION_NAME>`. |
| 212 | + |
| 213 | +For example, with this feature configuration: |
| 214 | + |
| 215 | +```json |
| 216 | +{ |
| 217 | + "features": { |
| 218 | + "ghcr.io/coder/devcontainer-features/code-server:1": { |
| 219 | + "port": 9090 |
| 220 | + } |
| 221 | + } |
| 222 | +} |
| 223 | +``` |
| 224 | + |
| 225 | +Coder creates `FEATURE_CODE_SERVER_OPTION_PORT=9090`, which you can reference in |
| 226 | +your apps: |
| 227 | + |
| 228 | +```json |
| 229 | +{ |
| 230 | + "features": { |
| 231 | + "ghcr.io/coder/devcontainer-features/code-server:1": { |
| 232 | + "port": 9090 |
| 233 | + } |
| 234 | + }, |
| 235 | + "customizations": { |
| 236 | + "coder": { |
| 237 | + "apps": [ |
| 238 | + { |
| 239 | + "slug": "code-server", |
| 240 | + "displayName": "Code Server", |
| 241 | + "url": "http://localhost:${localEnv:FEATURE_CODE_SERVER_OPTION_PORT:8080}", |
| 242 | + "icon": "/icon/code.svg" |
| 243 | + } |
| 244 | + ] |
| 245 | + } |
| 246 | + } |
| 247 | +} |
| 248 | +``` |
| 249 | + |
| 250 | +## Next steps |
| 251 | + |
| 252 | +- [Working with dev containers](./working-with-dev-containers.md) — SSH, IDE |
| 253 | + integration, and port forwarding |
| 254 | +- [Troubleshooting dev containers](./troubleshooting-dev-containers.md) — |
| 255 | + Diagnose common issues |
0 commit comments