docs: normalize code-fence languages for Shiki compatibility (#27161)

Normalizes non-standard code-fence language tags across `docs/**` so a
strict highlighter (Shiki, used by Fumadocs) won't fail the build on an
unrecognized language, and unifies redundant synonym tags onto one
canonical form per language. The current renderer (Speed-Highlight)
detects the language from the code content, not the fence label, so this
drift wasn't visible until now.

## Changes

- `hcl` -> `tf` (199 fences, including indented ones nested in
numbered/bulleted lists). Shiki ships `hcl` and `terraform` as two
distinct grammars (not aliases); every `hcl`-tagged fence in `docs/**`
is actually Terraform resource/data/provider syntax, so the more
specific `terraform` grammar is correct for all of them. `tf` is Shiki's
own alias for that grammar, and it's also what GitHub's own markdown
renderer resolves to the same HCL/Terraform highlighting.
- `pwsh`/`powershell` -> `ps1`. Both `ps` and `ps1` are registered
PowerShell aliases in Shiki, but on GitHub's renderer only `.ps1` is a
registered file extension (`.ps` isn't), so `ps1` renders identically to
`powershell` there today while bare `ps` would silently lose
highlighting.
- `env` -> `dotenv` (a dedicated Shiki grammar for `KEY=VALUE` files)
- `text`/`output`/`none`/`url` -> `txt`. Same built-in plain-text
fallback either way, just shorter.
- `Dockerfile` -> `dockerfile` (lowercase)
- `bash`/`shell` -> `sh` (732 fences). Shiki and GitHub both alias all
three to a single shell grammar; this was already the style guide's
stated preference, just not enforced across the existing corpus until
now.
- `markdown` -> `md` (4 fences). Alias of the same grammar in both Shiki
and GitHub.
- `jsonc` -> `json` (1 fence). The block has no comments or trailing
commas, so it doesn't need the comments-capable grammar.
- `ts` -> `tsx` (2 fences, `docs/about/contributing/frontend.md`).
Verified the actual content tokenizes identically under both grammars,
and a sibling block in the same file already needs `tsx` for real JSX,
so unifying to one tag is safe for this file. Documented a caveat: `tsx`
mis-tokenizes the legacy angle-bracket type-assertion syntax
(`<Type>value`), which is invalid in real `.tsx` files anyway, so use
`value as Type` instead.
- `yml` -> `yaml` (1 fence)
- Updated `docs/.style/style-guide/formatting.md` to document all
canonical tags

`promql` (2 fences) and `caddyfile` (2 fences) are left as-is. Shiki
doesn't bundle a grammar for either, so they need a custom grammar
registration when the site adopts Shiki, rather than degrading to `txt`.
Tracked as follow-up work under DOCS-118 and
[DOCS-544](https://linear.app/codercom/issue/DOCS-544/vendor-a-local-promql-grammar-for-shiki-syntax-highlighting)
(promql).

Does not touch `offlinedocs/`.

Linear:
[DOCS-476](https://linear.app/codercom/issue/DOCS-476/normalize-docs-code-fence-languages-de-risk-shikifumadocs)

<details>
<summary>How the fence tags were verified</summary>

Each tag was tested against a real `shiki@latest` highlighter instance
(`codeToHtml`/`codeToTokens`) and cross-checked against GitHub's
`@wooorm/starry-night` grammar sources (the renderer that actually
displays these `.md` files today, in repo browsing and PR diffs), since
that's what determines whether brevity is safe before Shiki adoption:

```text
FAIL  env        -- Language `env` is not included in this bundle.
FAIL  Dockerfile -- Language `Dockerfile` is not included in this bundle.
FAIL  promql     -- Language `promql` is not included in this bundle.
FAIL  caddyfile  -- Language `caddyfile` is not included in this bundle.
FAIL  pwsh       -- Language `pwsh` is not included in this bundle.
FAIL  output     -- Language `output` is not included in this bundle.
```

`hcl` doesn't error in Shiki, since it's a real grammar, but that's
exactly the trap: it was silently rendering every fence with the generic
HCL grammar instead of the Terraform-specific one. Every `hcl`-tagged
fence in `docs/**` was manually checked against `origin/main` and is
genuinely Terraform content.

For `ts`/`tsx`, tokenizing the actual doc content confirmed identical
output under both grammars; a synthetic test with the legacy
angle-bracket cast syntax confirmed `tsx` degrades on that specific
construct, which the style guide now calls out.

The first normalization pass only matched fence tags at column 0
(`^```tag$`), missing tags indented inside numbered/bulleted lists. A
follow-up pass caught the remaining occurrences at any indentation
level.

</details>


---

*This PR description and the underlying changes were prepared with Coder
Agents assistance.*
This commit is contained in:
Nick Vigilante
2026-07-15 14:07:09 -04:00
committed by GitHub
parent d0982e3cc7
commit c84aa564ba
181 changed files with 997 additions and 980 deletions
@@ -24,7 +24,7 @@ Skipping a level breaks the outline.
**Do**:
```markdown
```md
# Configure your workspace
This page walks through the configuration options exposed on a Coder workspace.
@@ -52,7 +52,7 @@ Define them in the template or in the workspace's parameters.
**Don't**:
```markdown
```md
# Configure your workspace
# Configure your environment
@@ -129,7 +129,7 @@ Captions follow the image in a `<small>` tag.
Aim for one or two sentences that convey the same information a sighted reader would extract from the image.
Lead with the subject, not "An image of" or "A screenshot showing".
```markdown
```md
![Template Insights dashboard with weekly active users and connection latency charts](../../images/admin/templates/template-insights.png)
<small>The Template Insights dashboard with active-user and connection-latency widgets.</small>
@@ -144,7 +144,7 @@ For complex diagrams that can't be summarized in alt text, provide a longer desc
Mark images that carry no information beyond visual decoration with empty alt text.
Empty alt text tells the screen reader to skip the image rather than announce a meaningless filename.
```markdown
```md
![](../../images/decorative/divider.png)
```
@@ -29,7 +29,7 @@ Section tags don't save readers from scanning content that doesn't apply to them
**Do**:
```markdown
```md
# Connect Visual Studio Code to your Coder workspace
*Audience: a developer with an existing Coder workspace.*
@@ -41,7 +41,7 @@ For Windsurf, refer to [Windsurf](./windsurf.md).
**Don't**:
```markdown
```md
# Connect to your Coder workspace
This page covers Visual Studio Code, Cursor, Windsurf, JetBrains, Vim, the web terminal, and SSH.
@@ -66,7 +66,7 @@ A page that helps the reader accomplish two unrelated outcomes hides each outcom
**Do**:
```markdown
```md
# Configure single sign-on with Okta
This page walks through configuring OIDC single sign-on against an Okta tenant.
@@ -76,7 +76,7 @@ For Google Workspace, refer to [Configure SSO with Google Workspace](./sso-googl
**Don't**:
```markdown
```md
# Authentication
This page covers OIDC providers (Okta, Azure AD, Google Workspace, generic OIDC),
@@ -100,7 +100,7 @@ A hub page is appropriate when:
**Do**:
```markdown
```md
# Authentication
This page is the entry point for configuring authentication in Coder.
@@ -114,7 +114,7 @@ Pick the provider that matches your identity source:
**Don't**:
```markdown
```md
# Authentication
This page covers OIDC, SAML, GitHub OAuth, password authentication, and the API token model.
@@ -153,7 +153,7 @@ Name the audience by the role the reader recognizes from their own work (`develo
**Do**:
```markdown
```md
# Connect Visual Studio Code to your Coder workspace
This guide is for a developer with an existing Coder workspace.
@@ -164,7 +164,7 @@ For Windsurf, refer to [Windsurf](./windsurf.md).
**Don't**:
```markdown
```md
# Kubernetes
Coder runs on Kubernetes.
@@ -185,7 +185,7 @@ For pages of that kind, add an `IMPORTANT` callout at the beginning of the page
**Do**:
```markdown
```md
# Configure single sign-on with Okta
This guide is for a Coder deployment administrator
@@ -13,7 +13,7 @@ This rule covers H1 through H6 and matches the way the heading reads aloud.
**Do**:
```markdown
```md
# Configure your workspace
## Set up SSH access
### Connect through JetBrains Toolbox
@@ -21,7 +21,7 @@ This rule covers H1 through H6 and matches the way the heading reads aloud.
**Don't**:
```markdown
```md
# Configure Your Workspace
## Set Up SSH Access
### Connect Through JetBrains Toolbox
@@ -38,7 +38,7 @@ Reserve gerund-leading headings for the rare case where neither alternative read
**Do**:
```markdown
```md
## Install Coder
## Installation
## Configure your workspace
@@ -47,7 +47,7 @@ Reserve gerund-leading headings for the rare case where neither alternative read
**Don't**:
```markdown
```md
## Installing Coder
## Configuring your workspace
```
@@ -80,7 +80,7 @@ The rule has scoped exceptions:
**Do**:
```markdown
```md
## What's a workspace
## Quick reference
## What does the `panic!` macro do?
@@ -89,7 +89,7 @@ The rule has scoped exceptions:
**Don't**:
```markdown
```md
## What's a workspace?
## Quick reference!
## Workspaces are great!
+31 -14
View File
@@ -136,19 +136,34 @@ Use the most specific language tag available:
Use `sh` when the block is input the reader types or a script they save, and the block doesn't also show output.
- `console` for an interactive session that shows the typed command and its output together.
Prefix each typed line with `$`.
- `powershell` for Windows command-line blocks.
- `ps1` for Windows command-line blocks.
PowerShell is the default Windows shell in the Coder docs.
`pwsh` and `powershell` are not the canonical tag; use `ps1`.
`ps1` is Shiki's PowerShell alias, and it's also GitHub's `.ps1` file extension, which its markdown renderer falls back to when a fence label isn't a recognized language name; `ps` isn't registered either way and won't highlight on GitHub today.
- `tf` for Terraform and HCL.
`terraform` and `hcl` are not the canonical tag; use `tf`.
Shiki ships `terraform` and `hcl` as two distinct grammars; `tf` is an alias of the more specific `terraform` grammar (not `hcl`), and matches what nearly every Coder docs code block actually is.
- `yaml` for YAML.
`yml` is not the canonical tag; use `yaml`.
- `go` for Go.
- `json` for JSON.
- `text` for command output shown on its own, and for any block with no syntax to highlight.
`jsonc` is a distinct Shiki grammar for JSON that permits comments; use it only for blocks that actually contain comments, otherwise use `json`.
- `dotenv` for `.env`-style `KEY=VALUE` blocks.
- `txt` for command output shown on its own, and for any block with no syntax to highlight.
`text`, `output`, `none`, and `url` are not the canonical tag; use `txt`.
- `dockerfile` for Dockerfiles, lowercase.
`Dockerfile` (capitalized) is not a valid tag.
- `md` for Markdown, including Markdown shown as a fenced example inside another Markdown file.
`markdown` is not the canonical tag; use `md`.
- `tsx` for TypeScript, including plain (non-JSX) TypeScript.
`ts` and `typescript` are not the canonical tag; use `tsx`.
`tsx` mis-tokenizes the legacy angle-bracket type-assertion syntax (`<Type>value`), which is invalid in real `.tsx` files anyway; write casts as `value as Type` instead, which is unambiguous under both grammars and is already the idiomatic style.
`bash` and `shell` are aliases of `sh`.
Use `sh` so the corpus stays consistent.
A command with no output shown is `sh`, not `console`.
To show a command together with its output, either use one `console` block with `$` before the typed line, or split the command into an `sh` block and the output into a `text` block.
To show a command together with its output, either use one `console` block with `$` before the typed line, or split the command into an `sh` block and the output into a `txt` block.
The auto-generated Coder CLI reference under `docs/reference/cli/` labels its command-usage blocks `console`.
That output is generated.
@@ -156,7 +171,9 @@ Do not copy the pattern into hand-written pages.
The docs site highlights code with [Speed-Highlight](https://github.com/speed-highlight/core), which detects the language from the code content, not from the fence label.
The fence label still drives highlighting on GitHub and in most editors, and `markdownlint` rule `MD040` requires one, so always declare the most specific language.
For content with no sensible language tag, fall back to `text`.
A future docs renderer may adopt [Shiki](https://shiki.style), which fails the build on a fence label it doesn't recognize as a language or alias, so use only tags Shiki supports.
For content with no sensible language tag, fall back to `txt`.
A fence label needing a grammar Shiki doesn't bundle (for example `promql` or `caddyfile`) stays as-is; register it as a custom grammar when the site adopts Shiki, rather than degrading it to `txt`.
**Do**:
@@ -233,7 +250,7 @@ curl -L https://coder.com/install.sh | sh
### Windows
```powershell
```ps1
winget install Coder.Coder
```
@@ -266,13 +283,13 @@ If one item is a complete sentence, rewrite the rest so every item is a complete
**Do**:
```markdown
```md
1. Run `coder login` to authenticate.
2. Create the workspace template.
3. Build the workspace from the template.
```
```markdown
```md
The provisioner supports:
- AWS
@@ -280,7 +297,7 @@ The provisioner supports:
- Google Cloud
```
```markdown
```md
The agent reconnect logic uses the following timeouts:
- Initial reconnect: 1 second.
@@ -290,13 +307,13 @@ The agent reconnect logic uses the following timeouts:
**Don't**:
```markdown
```md
1. The user runs `coder login` to authenticate
2. Creating the workspace template comes next.
3. Then the workspace gets built from the template
```
```markdown
```md
The provisioner supports:
- AWS.
@@ -312,14 +329,14 @@ When such a list needs a lead-in, end the lead-in with a colon on a clause that
**Do**:
```markdown
```md
You have two options:
- Install the tool with `apt-get` in the template's startup script.
- Bake the tool into the workspace image.
```
```markdown
```md
## Learn more
- [Extending templates](./extending-templates.md)
@@ -328,7 +345,7 @@ You have two options:
**Don't**:
```markdown
```md
Install it where it persists across rebuilds:
- Add it to the template's startup script with `apt-get`.
@@ -383,7 +400,7 @@ Reference the asset with a relative path from the Markdown source.
Captions follow the image in a `<small>` tag.
```markdown
```md
![Template Insights dashboard with weekly active users and connection latency charts](../../images/admin/templates/template-insights.png)
<small>The Template Insights dashboard with active-user and connection-latency widgets.</small>
@@ -45,7 +45,7 @@ The visible result is the same as a regular space, but the line breaker treats t
In the Markdown source (what you type):
```markdown
```md
The default timeout is 30&nbsp;seconds.
Connection latency under 150&nbsp;ms shows green.
```
@@ -64,7 +64,7 @@ The number and the unit move to the next line together rather than separating.
In the Markdown source:
```markdown
```md
The default timeout is 30 seconds.
Connection latency under 150ms shows green.
```
+2 -2
View File
@@ -200,7 +200,7 @@ Two rationales apply:
**Do**:
```markdown
```md
## Learn more
- [Configure SSH access](./ssh.md)
@@ -209,7 +209,7 @@ Two rationales apply:
**Don't**:
```markdown
```md
## Next steps
- [Configure SSH access](./ssh.md)
+6 -6
View File
@@ -14,7 +14,7 @@ Learn more [how Nix works](https://nixos.org/guides/how-nix-works).
1. After you've installed Nix, instantiate the development with the `nix-shell`
command:
```shell
```sh
cd ~/code/coder
# https://nix.dev/tutorials/declarative-and-reproducible-developer-environments
@@ -31,7 +31,7 @@ Learn more [how Nix works](https://nixos.org/guides/how-nix-works).
[hooks configured](https://direnv.net/docs/hook.html), you can add `use nix`
to `.envrc` to automatically instantiate the development environment:
```shell
```sh
cd ~/code/coder
echo "use nix" >.envrc
direnv allow
@@ -41,7 +41,7 @@ Learn more [how Nix works](https://nixos.org/guides/how-nix-works).
[`direnv`](https://direnv.net/docs/hook.html) will prepare the environment
for you:
```shell
```sh
cd ~/code/coder
direnv: loading ~/code/coder/.envrc
@@ -232,7 +232,7 @@ RC tags can be created from `main` or from a release branch. The
`create-release-branch` type creates `release/X.Y` and tags the next RC in one
step, continuing the RC numbering sequence.
```text
```txt
main: --*--*--*--*--*--*--*--*--*--
| rc.0 rc.1 |
| +--- create-release-branch ---+
@@ -358,7 +358,7 @@ If `./scripts/develop.sh` exits with a "database migration conflict" error,
it means the database has migrations from another branch that don't exist
on the current one. You have two options:
```shell
```sh
# Roll back the mismatched migrations (preserves your dev data):
./scripts/develop.sh --db-rollback
@@ -373,7 +373,7 @@ On macOS, a [direnv bug](https://github.com/direnv/direnv/issues/1345) can cause
`error: creating directory` when you attempt to run, build, or test, add a
`mkdir` line to your `.envrc`:
```shell
```sh
use nix
mkdir -p "$TMPDIR"
```
+4 -4
View File
@@ -151,7 +151,7 @@ Database migrations are managed with
To add new migrations, use the following command:
```shell
```sh
./coderd/database/migrations/create_migration.sh my name
/home/coder/src/coder/coderd/database/migrations/000070_my_name.up.sql
/home/coder/src/coder/coderd/database/migrations/000070_my_name.down.sql
@@ -188,7 +188,7 @@ migration of multiple features or complex configurations.
To add a new partial fixture, run the following command:
```shell
```sh
./coderd/database/migrations/create_fixture.sh my fixture
/home/coder/src/coder/coderd/database/migrations/testdata/fixtures/000070_my_fixture.up.sql
```
@@ -201,7 +201,7 @@ To create a full dump, run a fully fledged Coder deployment and use it to
generate data in the database. Then shut down the deployment and take a snapshot
of the database.
```shell
```sh
mkdir -p coderd/database/migrations/testdata/full_dumps/v0.12.2 && cd $_
pg_dump "postgres://coder@localhost:..." -a --inserts >000069_dump_v0.12.2.up.sql
```
@@ -212,7 +212,7 @@ emails, OAuth tokens and other secrets. Then commit the dump to the project.
To find out what the latest migration for a version of Coder is, use the
following command:
```shell
```sh
git ls-files v0.12.2 -- coderd/database/migrations/*.up.sql
```
+1 -1
View File
@@ -76,7 +76,7 @@ Use _code font_ for:
Use _code blocks_ for code samples and other blocks of code. Be sure to indicate
the language your using to apply the proper syntax highlighting.
```text
```txt
This is a codeblock.
```
+3 -3
View File
@@ -153,7 +153,7 @@ Typically, each API endpoint corresponds to its own `Request` and `Response`
types. However, some endpoints require additional parameters for successful
execution. Here's an illustrative example:"
```ts
```tsx
export const getAgentListeningPorts = async (
agentID: string,
): Promise<TypesGen.ListeningPortsResponse> => {
@@ -167,7 +167,7 @@ export const getAgentListeningPorts = async (
Sometimes, a frontend operation can have multiple API calls which can be wrapped
as a single function.
```ts
```tsx
export const updateWorkspaceVersion = async (
workspace: TypesGen.Workspace,
): Promise<TypesGen.WorkspaceBuild> => {
@@ -274,7 +274,7 @@ You can either run `scripts/remote_playwright.sh` from `coder/coder` on your
local machine, or execute the following command if you don't have the repo
available:
```bash
```sh
bash <(curl -sSL https://raw.githubusercontent.com/coder/coder/main/scripts/remote_playwright.sh) [workspace]
```
+15 -15
View File
@@ -26,20 +26,20 @@ Before contributing modules, ensure you have:
1. **Fork and clone the repository**:
```bash
```sh
git clone https://github.com/your-username/registry.git
cd registry
```
2. **Install dependencies**:
```bash
```sh
bun install
```
3. **Understand the structure**:
```text
```txt
registry/[namespace]/
├── modules/ # Your modules
├── .images/ # Namespace avatar and screenshots
@@ -52,20 +52,20 @@ Before contributing modules, ensure you have:
If you're a new contributor, create your namespace directory:
```bash
```sh
mkdir -p registry/[your-username]
mkdir -p registry/[your-username]/.images
```
Add your namespace avatar by downloading your GitHub avatar and saving it as `avatar.png`:
```bash
```sh
curl -o registry/[your-username]/.images/avatar.png https://github.com/[your-username].png
```
Create your namespace README at `registry/[your-username]/README.md`:
```markdown
```md
---
display_name: "Your Name"
bio: "Brief description of what you do"
@@ -89,7 +89,7 @@ Brief description of who you are and what you do.
Use the provided script to generate your module structure:
```bash
```sh
./scripts/new_module.sh [your-username]/[module-name]
cd registry/[your-username]/modules/[module-name]
```
@@ -104,7 +104,7 @@ This creates:
Edit `main.tf` to build your module's features. Here's an example based on the `git-clone` module structure:
```terraform
```tf
terraform {
required_providers {
coder = {
@@ -168,7 +168,7 @@ output "repo_dir" {
Create `main.test.ts` to test your module features:
```typescript
```tsx
import { runTerraformApply, runTerraformInit, testRequiredVariables } from "~test"
describe("git-clone", async () => {
@@ -197,7 +197,7 @@ describe("git-clone", async () => {
Update `README.md` with complete documentation:
```markdown
```md
---
display_name: "Git Clone"
description: "Clone a Git repository into your Coder workspace"
@@ -256,7 +256,7 @@ Your module README should include:
Run tests to ensure your module works correctly:
```bash
```sh
# Test your specific module
bun test -t 'git-clone'
@@ -319,7 +319,7 @@ When you modify a module, update its version following semantic versioning:
Use the version bump script to update versions:
```bash
```sh
./.github/scripts/version-bump.sh patch|minor|major
```
@@ -327,20 +327,20 @@ Use the version bump script to update versions:
1. **Create a feature branch**:
```bash
```sh
git checkout -b feat/modify-git-clone-module
```
2. **Test thoroughly**:
```bash
```sh
bun test -t 'git-clone'
bun fmt
```
3. **Commit with clear messages**:
```bash
```sh
git add .
git commit -m "feat(git-clone):add git-clone module"
```
+18 -18
View File
@@ -31,20 +31,20 @@ Before contributing templates, ensure you have:
1. **Fork and clone the repository**:
```bash
```sh
git clone https://github.com/your-username/registry.git
cd registry
```
2. **Install dependencies**:
```bash
```sh
bun install
```
3. **Understand the structure**:
```text
```txt
registry/[namespace]/
├── templates/ # Your templates
├── .images/ # Namespace avatar and screenshots
@@ -57,20 +57,20 @@ Before contributing templates, ensure you have:
If you're a new contributor, create your namespace directory:
```bash
```sh
mkdir -p registry/[your-username]
mkdir -p registry/[your-username]/.images
```
Add your namespace avatar by downloading your GitHub avatar and saving it as `avatar.png`:
```bash
```sh
curl -o registry/[your-username]/.images/avatar.png https://github.com/[your-username].png
```
Create your namespace README at `registry/[your-username]/README.md`:
```markdown
```md
---
display_name: "Your Name"
bio: "Brief description of what you do"
@@ -94,7 +94,7 @@ Brief description of who you are and what you do.
Create a directory for your template:
```bash
```sh
mkdir -p registry/[your-username]/templates/[template-name]
cd registry/[your-username]/templates/[template-name]
```
@@ -103,7 +103,7 @@ cd registry/[your-username]/templates/[template-name]
Create `main.tf` with your complete Terraform configuration:
```terraform
```tf
terraform {
required_providers {
coder = {
@@ -189,7 +189,7 @@ resource "coder_metadata" "workspace_info" {
Create `README.md` with comprehensive documentation:
```markdown
```md
---
display_name: "Ubuntu Development Environment"
description: "Complete Ubuntu workspace with VS Code, Git, and development tools"
@@ -262,7 +262,7 @@ You can customize this template by:
Use registry modules for common features:
```terraform
```tf
# VS Code in browser
module "code-server" {
count = data.coder_workspace.me.start_count
@@ -311,7 +311,7 @@ module "dotfiles" {
Provide meaningful customization options:
```terraform
```tf
variable "git_repo_url" {
description = "Git repository to clone"
type = string
@@ -337,7 +337,7 @@ variable "workspace_name" {
Test your template locally with Coder:
```bash
```sh
# Navigate to your template directory
cd registry/[your-username]/templates/[template-name]
@@ -400,13 +400,13 @@ Before submitting your template, verify:
1. **Create a feature branch**:
```bash
```sh
git checkout -b feat/add-python-template
```
2. **Test thoroughly**:
```bash
```sh
# Test with Coder
coder templates push test-python-template -d .
coder create test-workspace --template test-python-template
@@ -417,7 +417,7 @@ Before submitting your template, verify:
3. **Commit with clear messages**:
```bash
```sh
git add .
git commit -m "Add Python development template with FastAPI setup"
```
@@ -432,7 +432,7 @@ Before submitting your template, verify:
### Docker-based template
```terraform
```tf
# Simple Docker template
resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count
@@ -446,7 +446,7 @@ resource "docker_container" "workspace" {
### AWS EC2 template
```terraform
```tf
# AWS EC2 template
resource "aws_instance" "workspace" {
count = data.coder_workspace.me.start_count
@@ -463,7 +463,7 @@ resource "aws_instance" "workspace" {
### Kubernetes template
```terraform
```tf
# Kubernetes template
resource "kubernetes_pod" "workspace" {
count = data.coder_workspace.me.start_count
+16 -16
View File
@@ -24,7 +24,7 @@ If you have experience with a provider that is not listed here, please
After you create an OAuth application, set environment variables to configure the Coder server to use it:
```env
```dotenv
CODER_EXTERNAL_AUTH_0_ID="<USER_DEFINED_ID>"
CODER_EXTERNAL_AUTH_0_TYPE=<github|gitlab|azure-devops|bitbucket-cloud|bitbucket-server|etc>
CODER_EXTERNAL_AUTH_0_CLIENT_ID=<OAuth app client ID>
@@ -67,7 +67,7 @@ Reference the documentation for your chosen provider for more information on how
Use [`external-auth`](../../reference/cli/external-auth.md) in the Coder CLI to access a token within the workspace:
```shell
```sh
coder external-auth access-token <USER_DEFINED_ID>
```
@@ -101,7 +101,7 @@ Behind the scenes, Coder:
To manually access these tokens within a workspace:
```shell
```sh
coder external-auth access-token <USER_DEFINED_ID>
```
@@ -124,7 +124,7 @@ You must add the SSH key to your Git provider.
1. View your Coder Git SSH key:
```shell
```sh
coder publickey
```
@@ -142,7 +142,7 @@ acting as an OAuth client to external identity providers.
Coder will usually assume PKCE support is available with "S256" as the code challenge method. Manual
configuration is available to override any default behavior.
```env
```dotenv
# Enable PKCE with S256 (recommended when supported)
CODER_EXTERNAL_AUTH_0_PKCE_METHODS="S256"
@@ -156,7 +156,7 @@ CODER_EXTERNAL_AUTH_0_PKCE_METHODS="none"
Azure DevOps requires the following environment variables:
```env
```dotenv
CODER_EXTERNAL_AUTH_0_ID="primary-azure-devops"
CODER_EXTERNAL_AUTH_0_TYPE=azure-devops
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
@@ -170,7 +170,7 @@ CODER_EXTERNAL_AUTH_0_TOKEN_URL="https://app.vssps.visualstudio.com/oauth2/token
Azure DevOps (via Entra ID) requires the following environment variables:
```env
```dotenv
CODER_EXTERNAL_AUTH_0_ID="primary-azure-devops"
CODER_EXTERNAL_AUTH_0_TYPE=azure-devops-entra
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
@@ -185,7 +185,7 @@ CODER_EXTERNAL_AUTH_0_AUTH_URL="https://login.microsoftonline.com/<TENANT ID>/oa
Bitbucket Server requires the following environment variables:
```env
```dotenv
CODER_EXTERNAL_AUTH_0_ID="primary-bitbucket-server"
CODER_EXTERNAL_AUTH_0_TYPE=bitbucket-server
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxx
@@ -199,7 +199,7 @@ This callback path includes the value of `CODER_EXTERNAL_AUTH_0_ID`.
### Gitea
```env
```dotenv
CODER_EXTERNAL_AUTH_0_ID="gitea"
CODER_EXTERNAL_AUTH_0_TYPE=gitea
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxxx
@@ -219,7 +219,7 @@ or to integrate with an existing GitHub authentication.
For a more complete, step-by-step guide, follow the
[configure a GitHub OAuth app](#configure-a-github-oauth-app) section instead.
```env
```dotenv
CODER_EXTERNAL_AUTH_0_ID="primary-github"
CODER_EXTERNAL_AUTH_0_TYPE=github
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
@@ -236,7 +236,7 @@ as `https://example.com/external-auth/primary-github/callback`, where
GitHub Enterprise requires the following environment variables:
```env
```dotenv
CODER_EXTERNAL_AUTH_0_ID="primary-github"
CODER_EXTERNAL_AUTH_0_TYPE=github
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
@@ -255,7 +255,7 @@ as `https://example.com/external-auth/primary-github/callback`, where
GitLab self-managed requires the following environment variables:
```env
```dotenv
CODER_EXTERNAL_AUTH_0_ID="primary-gitlab"
CODER_EXTERNAL_AUTH_0_TYPE=gitlab
# This value is the "Application ID"
@@ -281,7 +281,7 @@ Visit the [JFrog Artifactory](../../admin/integrations/jfrog-artifactory.md) gui
Custom authentication and token URLs should be used for self-managed Git
provider deployments.
```env
```dotenv
CODER_EXTERNAL_AUTH_0_AUTH_URL="https://github.example.com/oauth/authorize"
CODER_EXTERNAL_AUTH_0_TOKEN_URL="https://github.example.com/oauth/token"
CODER_EXTERNAL_AUTH_0_REVOKE_URL="https://github.example.com/oauth/revoke"
@@ -296,7 +296,7 @@ CODER_EXTERNAL_AUTH_0_REGEX=github\.company\.com
Optionally, you can request custom scopes:
```env
```dotenv
CODER_EXTERNAL_AUTH_0_SCOPES="repo:read repo:write write:gpg_key"
```
@@ -343,7 +343,7 @@ CODER_EXTERNAL_AUTH_0_SCOPES="repo:read repo:write write:gpg_key"
before linking. To surface an **Install GitHub App** link in the
Coder UI, set the following environment variable:
```env
```dotenv
CODER_EXTERNAL_AUTH_0_APP_INSTALL_URL=https://github.com/apps/<your-app-slug>/installations/new
```
@@ -358,7 +358,7 @@ Below is an example configuration with multiple providers:
> git config --global credential.useHttpPath true
> ```
```env
```dotenv
# Provider 1) github.com
CODER_EXTERNAL_AUTH_0_ID=primary-github
CODER_EXTERNAL_AUTH_0_TYPE=github
+4 -4
View File
@@ -53,7 +53,7 @@ environments.
The following command will provision a number of Coder workspaces using the
specified template and extra parameters:
```shell
```sh
coder exp scaletest create-workspaces \
--retry 5 \
--count "${SCALETEST_PARAM_NUM_WORKSPACES}" \
@@ -77,7 +77,7 @@ The command does the following:
For more built-in `scaletest` options, use the `--help` flag:
```shell
```sh
coder exp scaletest create-workspaces --help
```
@@ -87,7 +87,7 @@ Given an existing set of workspaces created previously with `create-workspaces`,
the following command will generate traffic similar to that of Coder's Web
Terminal against those workspaces.
```shell
```sh
# Produce load at about 1000MB/s (25MB/40ms).
coder exp scaletest workspace-traffic \
--template "${SCALETEST_PARAM_GREEDY_AGENT_TEMPLATE}" \
@@ -127,7 +127,7 @@ The `workspace-traffic` supports also other modes - SSH traffic, workspace app:
The scaletest utility will attempt to clean up all workspaces it creates. If you
wish to clean up all workspaces, you can run the following command:
```shell
```sh
coder exp scaletest cleanup \
--cleanup-job-timeout 2h \
--cleanup-timeout 15min
@@ -25,7 +25,7 @@ choose a template from the
1. Use the `template init` command to initialize your choice of image:
```shell
```sh
coder template init --id kubernetes-devcontainer
```
@@ -34,7 +34,7 @@ choose a template from the
1. `cd` into the directory and push the template to your Coder deployment:
```shell
```sh
cd kubernetes-devcontainer && coder templates push
```
@@ -52,7 +52,7 @@ choose a template from the
- CLI:
```shell
```sh
coder templates push <template-name> -d <path to folder containing main.tf>
```
@@ -65,7 +65,7 @@ choose a template from the
- To zip the files through the command line:
```shell
```sh
zip templates.zip Dockerfile main.tf
```
@@ -40,7 +40,7 @@ Use the
[devcontainers-cli](https://registry.coder.com/modules/devcontainers-cli) module
to ensure the `@devcontainers/cli` is installed in your workspace:
```terraform
```tf
module "devcontainers-cli" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/devcontainers-cli/coder"
@@ -57,7 +57,7 @@ The
resource automatically starts a Dev Container in your workspace, ensuring it's
ready when you access the workspace:
```terraform
```tf
resource "coder_devcontainer" "my-repository" {
count = data.coder_workspace.me.start_count
agent_id = coder_agent.dev.id
@@ -83,7 +83,7 @@ default behavior.
If you need to explicitly disable Dev Containers, set the
`CODER_AGENT_DEVCONTAINERS_ENABLE` environment variable to `false`:
```terraform
```tf
resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count
image = "codercom/oss-dogfood:latest"
@@ -153,7 +153,7 @@ and [`coder_env`](https://registry.terraform.io/providers/coder/coder/latest/doc
resources to a `coder_devcontainer` by referencing its `subagent_id` attribute
as the `agent_id`:
```terraform
```tf
resource "coder_devcontainer" "my-repository" {
count = data.coder_workspace.me.start_count
agent_id = coder_agent.dev.id
@@ -227,7 +227,7 @@ For the full reference, see
Here's a simplified template example that uses Dev Containers with manual
configuration:
```terraform
```tf
terraform {
required_providers {
coder = { source = "coder/coder" }
@@ -277,7 +277,7 @@ resource "coder_env" "env" {
By default, discovered containers appear in the dashboard but developers must
manually start them. To have them start automatically, enable autostart:
```terraform
```tf
resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count
image = "codercom/oss-dogfood:latest"
+3 -3
View File
@@ -32,7 +32,7 @@ If your organization already uses the Coder-DX integration, you can find a list
Use `users list` to export the list of users to a CSV file:
```shell
```sh
coder users list > users.csv
```
@@ -42,7 +42,7 @@ Visit the [users list](../../reference/cli/users_list.md) documentation for more
Use [get users](../../reference/api/users.md#get-users):
```bash
```sh
curl -X GET http://coder-server:8080/api/v2/users \
-H 'Accept: application/json' \
-H 'Coder-Session-Token: API_KEY'
@@ -50,7 +50,7 @@ curl -X GET http://coder-server:8080/api/v2/users \
To export the results to a CSV file, you can use the `jq` tool to process the JSON response:
```bash
```sh
curl -X GET http://coder-server:8080/api/v2/users \
-H 'Accept: application/json' \
-H 'Coder-Session-Token: API_KEY' | \
+1 -1
View File
@@ -56,7 +56,7 @@ To set this up, follow these steps:
1. Add a new [external authentication](../external-auth/index.md) to Coder by setting these
environment variables in a manner consistent with your Coder deployment. Replace `JFROG_URL` with your JFrog Artifactory base URL:
```env
```dotenv
# JFrog Artifactory External Auth
CODER_EXTERNAL_AUTH_1_ID="jfrog"
CODER_EXTERNAL_AUTH_1_TYPE="jfrog"
+1 -1
View File
@@ -13,7 +13,7 @@ or deployment, such as:
Install the `coder-logstream-kube` helm chart on the cluster where the
deployment is running.
```shell
```sh
helm repo add coder-logstream-kube https://helm.coder.com/logstream-kube
helm install coder-logstream-kube coder-logstream-kube/coder-logstream-kube \
--namespace coder \
@@ -12,7 +12,7 @@ in the Terraform provider.
First, create a kubeconfig file with
[multiple contexts](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/).
```shell
```sh
kubectl config get-contexts
CURRENT NAME CLUSTER
@@ -27,7 +27,7 @@ If you deployed Coder on Kubernetes, you can attach a kubeconfig as a secret.
This assumes Coder is deployed on the `coder` namespace and your kubeconfig file
is in ~/.kube/config.
```shell
```sh
kubectl create secret generic kubeconfig-secret -n coder --from-file=~/.kube/config
```
@@ -104,7 +104,7 @@ cluster. Change the namespace accordingly.
Run this command against your remote cluster to create a ServiceAccount, Role,
RoleBinding, and token:
```shell
```sh
kubectl apply -n coder-workspaces -f - <<EOF
apiVersion: v1
kind: ServiceAccount
@@ -147,7 +147,7 @@ EOF
The output should be similar to:
```text
```txt
serviceaccount/coder-v2 created
secret/coder-v2 created
role.rbac.authorization.k8s.io/coder-v2 created
@@ -193,7 +193,7 @@ macOS and Linux.
To get the cluster address:
```shell
```sh
kubectl cluster-info
Kubernetes control plane is running at https://example.domain:6443
@@ -202,7 +202,7 @@ export CLUSTER_ADDRESS=https://example.domain:6443
To fetch the CA certificate and token:
```shell
```sh
export CLUSTER_CA_CERTIFICATE=$(kubectl get secrets coder-v2 -n coder-workspaces -o jsonpath="{.data.ca\.crt}")
export CLUSTER_SERVICEACCOUNT_TOKEN=$(kubectl get secrets coder-v2 -n coder-workspaces -o jsonpath="{.data.token}")
@@ -210,7 +210,7 @@ export CLUSTER_SERVICEACCOUNT_TOKEN=$(kubectl get secrets coder-v2 -n coder-work
Create the template with these values:
```shell
```sh
coder templates push \
--variable host=$CLUSTER_ADDRESS \
--variable cluster_ca_certificate=$CLUSTER_CA_CERTIFICATE \
@@ -221,7 +221,7 @@ coder templates push \
If you're on a Windows machine (or if one of the commands fail), try grabbing
the values manually:
```shell
```sh
# Get cluster API address
kubectl cluster-info
+15 -15
View File
@@ -22,13 +22,13 @@ Coder can act as an OAuth2 authorization server, allowing third-party applicatio
Add the `oauth2` experiment flag to your Coder server:
```bash
```sh
coder server --experiments oauth2
```
Or set the environment variable:
```env
```dotenv
CODER_EXPERIMENTS=oauth2
```
@@ -47,7 +47,7 @@ CODER_EXPERIMENTS=oauth2
Create an application using the Coder API:
```bash
```sh
curl -X POST \
-H "Authorization: Bearer $CODER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
@@ -61,7 +61,7 @@ curl -X POST \
Generate a client secret:
```bash
```sh
curl -X POST \
-H "Authorization: Bearer $CODER_SESSION_TOKEN" \
"$CODER_URL/api/v2/oauth2-provider/apps/$APP_ID/secrets"
@@ -86,7 +86,7 @@ If client authentication fails, the token endpoint returns **HTTP 401** with an
1. **Authorization Request**: Redirect users to Coder's authorization endpoint:
```url
```txt
https://coder.example.com/oauth2/authorize?
client_id=your-client-id&
response_type=code&
@@ -98,7 +98,7 @@ If client authentication fails, the token endpoint returns **HTTP 401** with an
**Option A: HTTP Basic authentication (`client_secret_basic`, recommended)**
```bash
```sh
curl -X POST \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-H "Content-Type: application/x-www-form-urlencoded" \
@@ -110,7 +110,7 @@ If client authentication fails, the token endpoint returns **HTTP 401** with an
**Option B: Form parameters (`client_secret_post`)**
```bash
```sh
curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
@@ -123,7 +123,7 @@ If client authentication fails, the token endpoint returns **HTTP 401** with an
3. **API Access**: Use the access token to call Coder's API:
```bash
```sh
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
"$CODER_URL/api/v2/users/me"
```
@@ -141,14 +141,14 @@ confidential clients must include PKCE parameters:
1. Generate a code verifier and challenge:
```bash
```sh
CODE_VERIFIER=$(openssl rand -base64 96 | tr -d "=+/" | cut -c1-128)
CODE_CHALLENGE=$(echo -n $CODE_VERIFIER | openssl dgst -sha256 -binary | base64 | tr -d "=+/" | cut -c1-43)
```
2. Include PKCE parameters in the authorization request:
```url
```txt
https://coder.example.com/oauth2/authorize?
client_id=your-client-id&
response_type=code&
@@ -159,7 +159,7 @@ confidential clients must include PKCE parameters:
3. Include the code verifier in the token exchange (see [Client Authentication Methods](#client-authentication-methods)):
```bash
```sh
curl -X POST \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-H "Content-Type: application/x-www-form-urlencoded" \
@@ -187,7 +187,7 @@ Refresh an expired access token.
**Option A: HTTP Basic authentication (`client_secret_basic`)**
```bash
```sh
curl -X POST \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-H "Content-Type: application/x-www-form-urlencoded" \
@@ -198,7 +198,7 @@ curl -X POST \
**Option B: Form parameters (`client_secret_post`)**
```bash
```sh
curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
@@ -212,7 +212,7 @@ curl -X POST \
Revoke all tokens for an application:
```bash
```sh
curl -X DELETE \
-H "Authorization: Bearer $CODER_SESSION_TOKEN" \
"$CODER_URL/oauth2/tokens?client_id=$CLIENT_ID"
@@ -222,7 +222,7 @@ curl -X DELETE \
Coder provides comprehensive test scripts for OAuth2 development:
```bash
```sh
# Navigate to the OAuth2 test scripts
cd scripts/oauth2/
+1 -1
View File
@@ -38,6 +38,6 @@ This module installs and authenticates the `vault` CLI in your Coder workspace.
Users then can use the `vault` CLI to interact with Vault; for example, to fetch
a secret stored in the KV backend.
```shell
```sh
vault kv get -namespace=YOUR_NAMESPACE -mount=MOUNT_NAME SECRET_NAME
```
+2 -2
View File
@@ -42,7 +42,7 @@ There are two ways to add a license to a Coder deployment:
1. Open a terminal.
1. Log in to your Coder deployment:
```shell
```sh
coder login <access url>
```
@@ -50,7 +50,7 @@ There are two ways to add a license to a Coder deployment:
- For a `.jwt` license file:
```shell
```sh
coder licenses add -f <path to your license key>
```
+3 -3
View File
@@ -61,7 +61,7 @@ This could be due to a number of reasons, including but not limited to:
To troubleshoot further, you can log into the machine running Coder and attempt
to run the following command:
```shell
```sh
curl -v ${CODER_ACCESS_URL}/healthz
# Expected output:
# * Trying XXX.XXX.XXX.XXX:443
@@ -165,7 +165,7 @@ performance may be impacted for clients closest to the unhealthy DERP server.
**Solution:** Ensure that the DERP server is available and reachable over the
network, for example:
```shell
```sh
curl -v "https://coder.company.com/derp"
# Expected output:
# * Trying XXX.XXX.XXX.XXX
@@ -246,7 +246,7 @@ Access URL.
1. Ensure that Coder's configured Access URL can be reached from the server
running Coder, using standard troubleshooting tools like `curl`:
```shell
```sh
curl -v "https://coder.company.com"
```
+4 -4
View File
@@ -148,7 +148,7 @@ After setting the required fields above:
1. Set the following configuration options:
```text
```txt
CODER_EMAIL_SMARTHOST=smtp.gmail.com:465
CODER_EMAIL_AUTH_USERNAME=<user>@<domain>
CODER_EMAIL_AUTH_PASSWORD="<app password created above (no spaces)>"
@@ -167,7 +167,7 @@ After setting the required fields above:
1. Set up an account on Microsoft 365 or outlook.com
1. Set the following configuration options:
```text
```txt
CODER_EMAIL_SMARTHOST=smtp-mail.outlook.com:587
CODER_EMAIL_TLS_STARTTLS=true
CODER_EMAIL_AUTH_USERNAME=<user>@<domain>
@@ -289,13 +289,13 @@ To send a custom notification, execute [`coder notifications custom <title> <mes
- Send yourself a quick update:
```shell
```sh
coder templates push -y && coder notifications custom "Template push complete" "Template version uploaded."
```
- Use in a script after a long-running task:
```shell
```sh
#!/usr/bin/env bash
set -o pipefail
+5 -5
View File
@@ -51,13 +51,13 @@ To build the server to receive webhooks and interact with Slack:
1. Initialize your project by running:
```bash
```sh
npm init -y
```
2. Install the Bolt library:
```bash
```sh
npm install @slack/bolt
```
@@ -165,14 +165,14 @@ To build the server to receive webhooks and interact with Slack:
4. Set environment variables to identify the Slack app:
```bash
```sh
export SLACK_BOT_TOKEN=xoxb-...
export SLACK_SIGNING_SECRET=0da4b...
```
5. Start the web application by running:
```bash
```sh
node app.js
```
@@ -195,7 +195,7 @@ must respond appropriately.
To enable webhook integration in Coder, define the POST webhook endpoint
matching the deployed Slack bot:
```bash
```sh
export CODER_NOTIFICATIONS_WEBHOOK_ENDPOINT=http://localhost:6000/v1/webhook`
```
+1 -1
View File
@@ -136,7 +136,7 @@ The process of setting up a Teams workflow consists of three key steps:
To enable webhook integration in Coder, define the POST webhook endpoint created
by your Teams workflow:
```bash
```sh
export CODER_NOTIFICATIONS_WEBHOOK_ENDPOINT=https://prod-16.eastus.logic.azure.com:443/workflows/f8fbe3e8211e4b638...`
```
+3 -3
View File
@@ -80,7 +80,7 @@ Template admins can overwrite the site-wide access URL at the template level by
leveraging the `url` argument when
[defining the Coder provider](https://registry.terraform.io/providers/coder/coder/latest/docs#url-1):
```terraform
```tf
provider "coder" {
url = "https://coder.namespace.svc.cluster.local"
}
@@ -126,7 +126,7 @@ for both public and [Air-gapped deployments](../../install/airgap.md).
However, Tailscale maintains a global fleet of [DERP relays](https://tailscale.com/kb/1118/custom-derp-servers/#what-are-derp-servers) intended for their product, and has allowed Coder to access and use them.
You can launch `coder server` with Tailscale's DERPs like so:
```bash
```sh
coder server --derp-config-url https://controlplane.tailscale.com/derpmap/default
```
@@ -159,7 +159,7 @@ After you have custom DERP servers, you can launch Coder with them like so:
}
```
```bash
```sh
coder server --derp-config-path derpmap.json
```
+3 -3
View File
@@ -171,7 +171,7 @@ protocol configuration for each shared port individually.
You can access any port on the workspace and can configure the port protocol
manually by appending a `s` to the port in the URL.
```text
```txt
# Uses HTTP
https://33295--agent--workspace--user--apps.example.com/
# Uses HTTPS
@@ -194,7 +194,7 @@ must include credentials (set `credentials: "include"` if using `fetch`) or the
requests cannot be authenticated and you will see an error resembling the
following:
```text
```txt
Access to fetch at
'<https://coder.example.com/api/v2/applications/auth-redirect>' from origin
'<https://8000--dev--user--apps.coder.example.com>' has been blocked by CORS
@@ -207,7 +207,7 @@ resource. If an opaque response serves your needs, set the request's mode to
Below is a list of the cross-origin headers Coder sets with example values:
```text
```txt
access-control-allow-credentials: true
access-control-allow-methods: PUT
access-control-allow-headers: X-Custom-Header
+8 -8
View File
@@ -24,7 +24,7 @@ The following tools require wildcard access URL:
`CODER_WILDCARD_ACCESS_URL` is necessary for [port forwarding](port-forwarding.md#dashboard) via the dashboard or running [coder_apps](../templates/index.md) on an absolute path. Set this to a wildcard subdomain that resolves to Coder (e.g. `*.coder.example.com`).
```bash
```sh
export CODER_WILDCARD_ACCESS_URL="*.coder.example.com"
coder server
```
@@ -40,7 +40,7 @@ Wildcard access URLs require a TLS certificate that covers the wildcard domain.
Configure Coder to handle TLS directly using the wildcard certificate:
```bash
```sh
export CODER_TLS_ENABLE=true
export CODER_TLS_CERT_FILE=/path/to/wildcard.crt
export CODER_TLS_KEY_FILE=/path/to/wildcard.key
@@ -72,13 +72,13 @@ You'll need to configure DNS to point wildcard subdomains to your Coder server:
> browsers consider these "public" domains and will refuse Coder's cookies,
> which are vital to the proper operation of this feature.
```text
```txt
*.coder.example.com A <your-coder-server-ip>
```
Or alternatively, using a CNAME record:
```text
```txt
*.coder.example.com CNAME coder.example.com
```
@@ -86,7 +86,7 @@ Or alternatively, using a CNAME record:
If you're using [workspace proxies](workspace-proxies.md) for geo-distributed teams, each proxy requires its own wildcard access URL configuration:
```bash
```sh
# Main Coder server
export CODER_WILDCARD_ACCESS_URL="*.coder.example.com"
@@ -99,7 +99,7 @@ export CODER_WILDCARD_ACCESS_URL="*.london.coder.example.com"
Each proxy's wildcard domain must have corresponding DNS records:
```text
```txt
*.sydney.coder.example.com A <sydney-proxy-ip>
*.london.coder.example.com A <london-proxy-ip>
```
@@ -108,7 +108,7 @@ Each proxy's wildcard domain must have corresponding DNS records:
In your Coder templates, enable subdomain applications using the `subdomain` parameter:
```hcl
```tf
resource "coder_app" "code-server" {
agent_id = coder_agent.main.id
slug = "code-server"
@@ -132,7 +132,7 @@ If workspace applications are not working:
- Restart the Coder server if you made changes to the environment variable
2. Check DNS resolution for wildcard subdomains:
```bash
```sh
dig test.coder.example.com
nslookup test.coder.example.com
```
+10 -10
View File
@@ -35,7 +35,7 @@ Create the workspace proxy and make sure to save the returned authentication
token for said proxy. This is the token the workspace proxy will use to
authenticate back to primary coderd.
```bash
```sh
$ coder wsproxy create --name=newyork --display-name="USA East" --icon="/emojis/2194.png"
Workspace Proxy "newyork" created successfully. Save this token, it will not be shown again.
Token: 2fb6500b-bb47-4783-a0db-dedde895b865:05271b4ef9432bac14c02b3c56b5a2d7f05453718a1f85ba7e772c0a096c7175
@@ -43,7 +43,7 @@ Token: 2fb6500b-bb47-4783-a0db-dedde895b865:05271b4ef9432bac14c02b3c56b5a2d7f054
To verify it was created.
```bash
```sh
$ coder wsproxy ls
NAME URL STATUS STATUS
newyork unregistered
@@ -55,7 +55,7 @@ Deploying the workspace proxy will also register the proxy with coderd and make
the workspace proxy usable. If the proxy deployment is successful,
`coder wsproxy ls` will show an `ok` status code:
```shell
```sh
$ coder wsproxy ls
NAME URL STATUS STATUS
primary https://dev.coder.com ok
@@ -80,7 +80,7 @@ Workspace proxy configuration overlaps with a subset of the coderd
configuration. To see the full list of configuration options:
`coder wsproxy server --help`
```bash
```sh
# Proxy specific configuration. These are REQUIRED
# Example: https://coderd.example.com
CODER_PRIMARY_ACCESS_URL="https://<url_of_coderd_dashboard>"
@@ -133,7 +133,7 @@ coder:
Using Helm, install the workspace proxy chart
```bash
```sh
helm install coder coder-v2/coder --namespace <your workspace proxy namespace> -f ./values-wsproxy.yaml
```
@@ -143,7 +143,7 @@ and up the deployment's replicas.
### Running on a VM
```bash
```sh
# Set configuration options via environment variables, a config file, or cmd flags
coder wsproxy server
```
@@ -156,7 +156,7 @@ can configure the workspace proxy by settings in
To run workspace proxy as a system service on the host:
```bash
```sh
# Use systemd to start workspace proxy now and on reboot
sudo systemctl enable --now coder-workspace-proxy
@@ -166,7 +166,7 @@ journalctl -u coder-workspace-proxy.service -b
To restart workspace proxy after applying system changes:
```shell
```sh
sudo systemctl restart coder-workspace-proxy
```
@@ -188,13 +188,13 @@ file to include a custom entrypoint:
#### Docker run
```bash
```sh
docker run --rm -it --entrypoint /opt/coder ghcr.io/coder/coder:latest wsproxy server
```
#### Custom Dockerfile
```Dockerfile
```dockerfile
FROM ghcr.io/coder/coder:latest
ENTRYPOINT ["/opt/coder", "wsproxy", "server"]
```
@@ -71,7 +71,7 @@ Follow these steps to identify problematic jobs or daemons:
1. Filter jobs by `pending` status in the dashboard, or use the CLI:
```bash
```sh
coder provisioner jobs list -s pending
```
@@ -79,6 +79,6 @@ Follow these steps to identify problematic jobs or daemons:
1. Cancel the job through the dashboard, or use the CLI:
```shell
```sh
coder provisioner jobs cancel <job-id>
```
+2 -2
View File
@@ -183,7 +183,7 @@ You may choose to run a `VACUUM` or `VACUUM FULL` operation on the audit logs ta
- **Run during a planned maintenance window** to ensure ample time for the operation to complete and minimize impact to users
- **Stop all running instances of `coderd`** to prevent connection errors while the table is locked. The actual steps for this will depend on your particular deployment setup. For example, if your `coderd` deployment is running on Kubernetes:
```bash
```sh
kubectl scale deployment coder --replicas=0 -n coder
```
@@ -199,7 +199,7 @@ You may choose to run a `VACUUM` or `VACUUM FULL` operation on the audit logs ta
After the vacuum completes, scale coderd back up:
```bash
```sh
kubectl scale deployment coder --replicas= -n coder
```
+2 -2
View File
@@ -59,13 +59,13 @@ values using that key to a new key.
- Generate a 32-byte random key and base64-encode it. For example:
```shell
```sh
dd if=/dev/urandom bs=32 count=1 | base64
```
- Store this key in a secure location (for example, a Kubernetes secret):
```shell
```sh
kubectl create secret generic coder-external-token-encryption-keys --from-literal=keys=<key>
```
+2 -2
View File
@@ -98,13 +98,13 @@ coder:
if running as a system service, set an environment variable
`CODER_SUPPORT_LINKS` in `/etc/coder.d/coder.env` as follows,
```env
```dotenv
CODER_SUPPORT_LINKS='[{"name": "Hello GitHub", "target": "https://github.com/coder/coder", "icon": "bug"}, {"name": "Hello Slack", "target": "https://codercom.slack.com/archives/C014JH42DBJ", "icon": "https://raw.githubusercontent.com/coder/coder/main/site/static/icon/slack.svg"}, {"name": "Hello Discord", "target": "https://discord.gg/coder", "icon": "https://raw.githubusercontent.com/coder/coder/main/site/static/icon/discord.svg", "location": "navbar"}, {"name": "Hello Foobar", "target": "https://discord.gg/coder", "icon": "/emojis/1f3e1.png"}]'
```
For CLI, use,
```shell
```sh
export CODER_SUPPORT_LINKS='[{"name": "Hello GitHub", "target": "https://github.com/coder/coder", "icon": "bug"}, {"name": "Hello Slack", "target": "https://codercom.slack.com/archives/C014JH42DBJ", "icon": "https://raw.githubusercontent.com/coder/coder/main/site/static/icon/slack.svg"}, {"name": "Hello Discord", "target": "https://discord.gg/coder", "icon": "https://raw.githubusercontent.com/coder/coder/main/site/static/icon/discord.svg", "location": "navbar"}, {"name": "Hello Foobar", "target": "https://discord.gg/coder", "icon": "/emojis/1f3e1.png"}]'
coder-server
```
+2 -2
View File
@@ -53,7 +53,7 @@ Go duration units (`h`, `m`, `s`):
### CLI Example
```bash
```sh
coder server \
--audit-logs-retention=365d \
--connection-logs-retention=90d \
@@ -64,7 +64,7 @@ coder server \
### Environment Variables Example
```bash
```sh
export CODER_AUDIT_LOGS_RETENTION=365d
export CODER_CONNECTION_LOGS_RETENTION=90d
export CODER_API_KEYS_RETENTION=7d
+2 -2
View File
@@ -21,7 +21,7 @@ to reverse proxy your deployment for simple setup.
You can change which port(s) Coder listens on.
```shell
```sh
# Listen on port 80
export CODER_HTTP_ADDRESS=0.0.0.0:80
@@ -83,7 +83,7 @@ working directory prior to step 1.
1. Create the TLS secret in your Kubernetes cluster
```shell
```sh
kubectl create secret tls coder-tls -n <coder-namespace> --key="tls.key" --cert="tls.crt"
```
@@ -94,7 +94,7 @@ You can also show agent metadata for information about the workspace's host.
available in most Linux distributions and provides virtual memory, CPU and IO
statistics. Running `top` produces output that looks like:
```text
```txt
%Cpu(s): 65.8 us, 4.4 sy, 0.0 ni, 29.3 id, 0.3 wa, 0.0 hi, 0.2 si, 0.0 st
MiB Mem : 16009.0 total, 493.7 free, 4624.8 used, 10890.5 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 11021.3 avail Mem
@@ -104,7 +104,7 @@ MiB Swap: 0.0 total, 0.0 free, 0.0 used. 11021.3 avail Mem
available in most Linux distributions and provides virtual memory, CPU and IO
statistics. Running `vmstat` produces output that looks like:
```text
```txt
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 19580 4781680 12133692 217646944 0 2 4 32 1 0 1 1 98 0 0
@@ -115,7 +115,7 @@ considerably more parseable than `vmstat` but often not included in base images.
It is easily installed by most package managers under the name `dstat`. The
output of running `dstat 1 1` looks like:
```text
```txt
--total-cpu-usage-- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai stl| read writ| recv send| in out | int csw
1 1 98 0 0|3422k 25M| 0 0 | 153k 904k| 123k 174k
@@ -127,7 +127,7 @@ Agent metadata can generate a significant write load and overwhelm your Coder
database if you're not careful. The approximate writes per second can be
calculated using the formula:
```text
```txt
(metadata_count * num_running_agents * 2) / metadata_avg_interval
```
@@ -160,7 +160,7 @@ this secret.
The following shows a minimal example using a the JSON API key from a GCP
service account to pull a private image:
```bash
```sh
# Create the secret
$ kubectl create secret docker-registry <name> \
--docker-server=us.gcr.io \
@@ -197,7 +197,7 @@ Before using Podman, please review the following documentation:
[smart-device-manager](https://github.com/smarter-project/smarter-device-manager#enabling-access)
to securely expose a FUSE devices to pods.
```shell
```sh
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: DaemonSet
@@ -235,7 +235,7 @@ Before using Podman, please review the following documentation:
2. Be sure to label your nodes to enable smarter-device-manager:
```shell
```sh
kubectl get nodes
kubectl label nodes --all smarter-device-manager=enabled
```
@@ -251,7 +251,7 @@ Before using Podman, please review the following documentation:
[kubernetes-with-podman](https://github.com/coder/community-templates/tree/main/kubernetes-podman)
example template, or make your own.
```shell
```sh
echo "kubernetes-with-podman" | coder templates init
cd ./kubernetes-with-podman
coder templates create
@@ -265,7 +265,7 @@ Before using Podman, please review the following documentation:
Rootless containers rely on Linux user-namespaces.
[Bottlerocket](https://github.com/bottlerocket-os/bottlerocket) disables them by default (`user.max_user_namespaces = 0`), so Podman commands will return an error until you raise the limit:
```output
```txt
cannot clone: Invalid argument
user namespaces are not enabled in /proc/sys/user/max_user_namespaces
```
@@ -280,7 +280,7 @@ user namespaces are not enabled in /proc/sys/user/max_user_namespaces
1. Reboot the node.
1. Verify that the value is more than `0`:
```shell
```sh
sysctl -n user.max_user_namespaces
```
@@ -46,7 +46,7 @@ In Coder v2.25.0 and later, Dynamic Parameters are automatically enabled for new
1. Update your template to use version >=2.4.0 of the Coder provider with the following Terraform block.
```terraform
```tf
terraform {
required_providers {
coder = {
@@ -148,7 +148,7 @@ Users can avoid restrictions like `disabled` if they create a workspace via the
This attribute accepts JSON like so:
```terraform
```tf
data "coder_parameter" "styled_parameter" {
...
styling = jsonencode({
@@ -182,7 +182,7 @@ Single-select parameters with options can use the `form_type="dropdown"` attribu
[Try dropdown lists on the Parameter Playground](https://playground.coder.app/parameters/kgNBpjnz7x)
```terraform
```tf
locals {
ides = [
"VS Code",
@@ -219,7 +219,7 @@ The large text entry option can be used to enter long strings like AI prompts, s
[Try textarea parameters on the Parameter Playground](https://playground.coder.app/parameters/RCAHA1Oi1_)
```terraform
```tf
data "coder_parameter" "text_area" {
name = "text_area"
@@ -249,7 +249,7 @@ For example, adding multiple IDEs with a single parameter.
[Try multi-select parameters on the Parameter Playground](https://playground.coder.app/parameters/XogX54JV_f)
```terraform
```tf
locals {
ides = [
"VS Code", "JetBrains IntelliJ",
@@ -289,7 +289,7 @@ This is the original styling for list parameters.
[Try radio parameters on the Parameter Playground](https://playground.coder.app/parameters/3OMDp5ANZI).
```terraform
```tf
data "coder_parameter" "environment" {
name = "environment"
display_name = "Environment"
@@ -325,7 +325,7 @@ This can be used for a TOS confirmation or to expose advanced options.
[Try checkbox parameters on the Parameters Playground](https://playground.coder.app/parameters/ycWuQJk2Py).
```terraform
```tf
data "coder_parameter" "enable_gpu" {
name = "enable_gpu"
display_name = "Enable GPU"
@@ -342,7 +342,7 @@ The `validation` block is used to constrain (or clamp) the minimum and maximum v
[Try slider parameters on the Parameters Playground](https://playground.coder.app/parameters/RsBNcWVvfm).
```terraform
```tf
data "coder_parameter" "cpu_cores" {
name = "cpu_cores"
display_name = "CPU Cores"
@@ -366,7 +366,7 @@ Note that this does not secure information on the backend and is purely cosmetic
Note: This text may not be properly hidden in the Playground.
The `mask_input` styling attribute is supported in v2.24.0 and later.
```terraform
```tf
data "coder_parameter" "private_api_key" {
name = "private_api_key"
display_name = "Your super secret API key"
@@ -405,7 +405,7 @@ Use Terraform conditionals and the `count` block to allow a checkbox to expose o
[Try conditional parameters on the Parameter Playground](https://playground.coder.app/parameters/xmG5MKEGNM).
```terraform
```tf
data "coder_parameter" "show_cpu_cores" {
name = "show_cpu_cores"
display_name = "Toggles next parameter"
@@ -440,7 +440,7 @@ This allows you to suggest an option dynamically without strict enforcement.
[Try dynamic defaults in the Parameter Playground](https://playground.coder.app/parameters/DEi-Bi6DVe).
```terraform
```tf
locals {
ides = [
"VS Code",
@@ -505,7 +505,7 @@ A parameter's validation block can leverage inputs from other parameters.
[Try dynamic validation in the Parameter Playground](https://playground.coder.app/parameters/sdbzXxagJ4).
```terraform
```tf
data "coder_parameter" "git_repo" {
name = "git_repo"
display_name = "Git repo"
@@ -557,7 +557,7 @@ Note that parameters must be indexed when using the `count` attribute.
[Try daisy-chaining parameters in the Parameter Playground](https://playground.coder.app/parameters/jLUUhoDLIa).
```terraform
```tf
locals {
ides = [
@@ -659,7 +659,7 @@ data source.
[Try out admin-only options in the Playground](https://playground.coder.app/parameters/5Gn9W3hYs7).
```terraform
```tf
locals {
roles = [for r in data.coder_workspace_owner.me.rbac_roles: r.name]
@@ -701,7 +701,7 @@ This way developers can't accidentally induce low-latency with world-spanning co
[Try user-aware regions in the parameter playground](https://playground.coder.app/parameters/tBD-mbZRGm)
```terraform
```tf
locals {
eu_regions = [
@@ -752,7 +752,7 @@ Some users associate groups with namespaces, such as Kubernetes, then allow user
[Try groups as options in the Parameter Playground](https://playground.coder.app/parameters/lKbU53nYjl).
```terraform
```tf
locals {
groups = data.coder_workspace_owner.me.groups
}
@@ -839,7 +839,7 @@ Dynamic Parameters require Terraform modules to be archived and stored in the da
You may see warnings in the provisioner logs:
```text
```txt
[API] 2026-01-29 22:00:22.691 [warn] provisionerd-nixos-0.executor: some (or all) terraform modules were not archived, template will have reduced function skipped_modules=large:git::https://github.com/coder/large-module.git
```
@@ -40,7 +40,7 @@ external authentication will work with native `git` commands.
To check the auth token being used **from inside a running workspace**, run:
```shell
```sh
# If the exit code is non-zero, then the user is not authenticated with the
# external provider.
coder external-auth access-token <external-auth-id>
@@ -39,7 +39,7 @@ come bundled with your Coder deployment.
`CODER_EXTERNAL_AUTH_X_ICON` environment variable, where `X` is the number
of the provider.
```env
```dotenv
CODER_EXTERNAL_AUTH_0_ICON=/icon/github.svg
CODER_EXTERNAL_AUTH_1_ICON=/icon/google.svg
```
@@ -95,7 +95,7 @@ You can use these examples to add new Coder apps:
## code-server
```hcl
```tf
resource "coder_app" "code-server" {
agent_id = coder_agent.main.id
slug = "code-server"
@@ -109,7 +109,7 @@ resource "coder_app" "code-server" {
## Filebrowser
```hcl
```tf
resource "coder_app" "filebrowser" {
agent_id = coder_agent.main.id
display_name = "file browser"
@@ -123,7 +123,7 @@ resource "coder_app" "filebrowser" {
## Zed
```hcl
```tf
resource "coder_app" "zed" {
agent_id = coder_agent.main.id
slug = "slug"
@@ -15,7 +15,7 @@ If you have a suggestion or encounter an issue, please
Install the JetBrains Client Downloader binary. Note that the server must be a Linux-based distribution:
```shell
```sh
wget -O jetbrains-clients-downloader-linux-x86_64.tar.gz \
'https://data.services.jetbrains.com/products/download?code=JCD&platform=linux_x86-64' && \
tar -xzvf jetbrains-clients-downloader-linux-x86_64.tar.gz
@@ -39,7 +39,7 @@ To install both backends and clients, you will need to run two commands.
### Backends
```shell
```sh
mkdir ~/backends
./jetbrains-clients-downloader-linux-x86_64-*/bin/jetbrains-clients-downloader --products-filter <product-code> --build-filter <build-number> --platforms-filter linux-x64,windows-x64,osx-x64 --download-backends ~/backends
```
@@ -48,7 +48,7 @@ mkdir ~/backends
This is the same command as above, with the `--download-backends` flag removed.
```shell
```sh
mkdir ~/clients
./jetbrains-clients-downloader-linux-x86_64-*/bin/jetbrains-clients-downloader --products-filter <product-code> --build-filter <build-number> --platforms-filter linux-x64,windows-x64,osx-x64 ~/clients
```
@@ -87,7 +87,7 @@ option.
You will need to add the following files on your local machine in order for
Gateway to pull the backend and client from the server.
```shell
```sh
$ cat productsInfoUrl # a path to products.json that was generated by the backend's downloader (it could be http://, https://, or file://)
https://internal.site/backends/<PRODUCT_CODE>/products.json
@@ -9,7 +9,7 @@ For a faster first time connection with JetBrains IDEs, pre-install the IDEs bac
Install the JetBrains Client Downloader binary:
```shell
```sh
wget -O jetbrains-clients-downloader-linux-x86_64.tar.gz \
'https://data.services.jetbrains.com/products/download?code=JCD&platform=linux_x86-64' && \
tar -xzvf jetbrains-clients-downloader-linux-x86_64.tar.gz
@@ -18,14 +18,14 @@ rm jetbrains-clients-downloader-linux-x86_64.tar.gz
## Install Gateway backend
```shell
```sh
mkdir ~/JetBrains
./jetbrains-clients-downloader-linux-x86_64-*/bin/jetbrains-clients-downloader --products-filter <product-code> --build-filter <build-number> --platforms-filter linux-x64 --download-backends ~/JetBrains
```
For example, to install the build `243.26053.27` of IntelliJ IDEA:
```shell
```sh
./jetbrains-clients-downloader-linux-x86_64-*/bin/jetbrains-clients-downloader --products-filter IU --build-filter 243.26053.27 --platforms-filter linux-x64 --download-backends ~/JetBrains
tar -xzvf ~/JetBrains/backends/IU/*.tar.gz -C ~/JetBrains/backends/IU
rm -rf ~/JetBrains/backends/IU/*.tar.gz
@@ -35,7 +35,7 @@ rm -rf ~/JetBrains/backends/IU/*.tar.gz
Add the following command to your template's `startup_script`:
```shell
```sh
~/JetBrains/*/bin/remote-dev-server.sh registerBackendLocationForGateway
```
@@ -80,7 +80,7 @@ to resolve modules via [Artifactory](https://jfrog.com/artifactory/).
1. Create a virtual repository with name `tf`
1. Follow the below instructions to publish coder modules to Artifactory
```shell
```sh
git clone https://github.com/coder/registry
cd registry/registry/coder/modules
jf tfc
@@ -140,13 +140,13 @@ with read only access to the necessary repos.
If you are running Coder on a VM, make sure that you have `git` installed and
the `coder` user has access to the following files:
```shell
```sh
# /home/coder/.gitconfig
[credential]
helper = store
```
```shell
```sh
# /home/coder/.git-credentials
# GitHub example:
@@ -166,7 +166,7 @@ your own git credentials.
Next, create the secret in Kubernetes. Be sure to do this in the same namespace
that Coder is installed in.
```shell
```sh
export NAMESPACE=coder
kubectl apply -f - <<EOF
apiVersion: v1
@@ -420,7 +420,7 @@ parameters in one of two ways:
To enable this feature, you need to set the `auto-fill-parameters` experiment flag:
```shell
```sh
coder server --experiments=auto-fill-parameters
```
@@ -39,7 +39,7 @@ In your template, add a `prebuilds` block within a `coder_workspace_preset` defi
instances your Coder deployment should maintain, and optionally configure a `expiration_policy` block to set a TTL
(Time To Live) for unclaimed prebuilt workspaces to ensure stale resources are automatically cleaned up.
```hcl
```tf
data "coder_workspace_preset" "goland" {
name = "GoLand: Large"
parameters = {
@@ -295,7 +295,7 @@ The troubleshooting steps below will help you assess and resolve this situation:
Run:
```bash
```sh
coder prebuilds pause
```
@@ -307,7 +307,7 @@ This prevents further pollution of your provisioner queues by stopping the prebu
Next, run:
```bash
```sh
coder provisioner jobs list --status=pending --initiator=prebuilds
```
@@ -321,7 +321,7 @@ Human-initiated jobs are prioritized above prebuild jobs in the provisioner queu
To expedite fixing a broken template by ensuring maximum provisioner availability, cancel all pending prebuild jobs:
```bash
```sh
coder provisioner jobs list --status=pending --initiator=prebuilds | jq -r '.[].id' | xargs -n1 -P2 -I{} coder provisioner jobs cancel {}
```
@@ -333,7 +333,7 @@ At this stage, most prebuild related impact will have been mitigated. There may
If you need to expedite the processing of human-related jobs at the cost of some infrastructure housekeeping, you can run:
```bash
```sh
coder provisioner jobs list --status=running --initiator=prebuilds | jq -r '.[].id' | xargs -n1 -P2 -I{} coder provisioner jobs cancel {}
```
@@ -343,7 +343,7 @@ Once the provisioner queue has been cleared and all templates have been fixed, r
#### Resume prebuild reconciliation
```bash
```sh
coder prebuilds resume
```
@@ -367,7 +367,7 @@ For example, when these values are used in immutable fields like the AWS instanc
To prevent this, add a `lifecycle` block with `ignore_changes`:
```hcl
```tf
resource "docker_container" "workspace" {
lifecycle {
ignore_changes = [env, image] # include all fields which caused drift
@@ -414,7 +414,7 @@ This keeps other provisioners available to handle user-initiated jobs.
1. Update the template to conditionally add the prebuild tag for prebuild jobs.
```hcl
```tf
data "coder_workspace_tags" "prebuilds" {
count = data.coder_workspace_owner.me.name == "prebuilds" ? 1 : 0
tags = {
@@ -39,18 +39,18 @@ The host machine must be running a Linux kernel >= 5.8 with the kernel config
To check your kernel version, run:
```shell
```sh
uname -r
```
To validate the required kernel config is enabled, run either of the following
commands on your nodes directly (_not_ from a workspace terminal):
```shell
```sh
cat /proc/config.gz | gunzip | grep CONFIG_DEBUG_INFO_BTF
```
```shell
```sh
cat "/boot/config-$(uname -r)" | grep CONFIG_DEBUG_INFO_BTF
```
@@ -82,7 +82,7 @@ would like to add workspace process logging to, follow these steps:
in the exectrace repo.
-->
```hcl
```tf
locals {
# This is the init script for the main workspace container that runs before the
# agent starts to configure workspace process logging.
@@ -142,7 +142,7 @@ would like to add workspace process logging to, follow these steps:
in the exectrace repo.
-->
```hcl
```tf
resource "kubernetes_pod" "main" {
...
spec {
@@ -176,7 +176,7 @@ would like to add workspace process logging to, follow these steps:
in the exectrace repo.
-->
```hcl
```tf
resource "kubernetes_pod" "main" {
...
spec {
@@ -224,7 +224,7 @@ would like to add workspace process logging to, follow these steps:
in the exectrace repo.
-->
```hcl
```tf
resource "kubernetes_pod" "main" {
...
spec {
@@ -248,7 +248,7 @@ restarted.
To view the process logs for a specific workspace you can use `kubectl` to print
the logs:
```bash
```sh
kubectl logs pod-name --container exectrace
```
@@ -291,7 +291,7 @@ or workspace.
To view your logs, go to the CloudWatch dashboard (which is available on the
**Log Insights** tab) and run a query similar to the following:
```text
```txt
fields @timestamp, log_processed.fields.cmdline
| sort @timestamp asc
| filter kubernetes.container_name="exectrace"
@@ -11,7 +11,7 @@ so the agent itself stays alive under resource pressure.
the nice value below its current value. In Kubernetes, add
it to the container's security context:
```hcl
```tf
container {
security_context {
capabilities {
@@ -62,7 +62,7 @@ workloads.
The following Kubernetes template snippet enables process
priority management on the workspace container:
```hcl
```tf
resource "kubernetes_deployment" "workspace" {
# ... other configuration
@@ -138,7 +138,7 @@ runs another Coder agent.
The agent logs whether process priority management is active
at startup. Look for these lines in the agent log:
```text
```txt
"process priority management enabled"
"process priority management not enabled (linux-only)"
```
@@ -23,7 +23,7 @@ Add the following example to the template's `main.tf`.
Change the `90`, `80`, and `95` to a threshold that's more appropriate for your
deployment:
```hcl
```tf
resource "coder_agent" "main" {
arch = data.coder_provisioner.dev.arch
os = data.coder_provisioner.dev.os
@@ -59,7 +59,7 @@ variables, you can employ a straightforward solution:
1. Push the new template revision using Coder CLI:
```shell
```sh
coder templates push my-template -y # no need to use --var
```
@@ -57,7 +57,7 @@ For advanced use, we recommend installing code-server in your VM snapshot or
container image. Here's a Dockerfile which leverages some special
[code-server features](https://coder.com/docs/code-server):
```Dockerfile
```dockerfile
FROM codercom/enterprise-base:ubuntu
# install the latest version
@@ -26,7 +26,7 @@ If you add a Terraform provider to `required_providers` without specifying a
version requirement, Terraform will always fetch the latest version on each
invocation:
```terraform
```tf
terraform {
required_providers {
coder = {
@@ -47,7 +47,7 @@ To prevent this, add a
[version constraint](https://developer.hashicorp.com/terraform/language/expressions/version-constraints)
to each provider in the `required_providers` block:
```terraform
```tf
terraform {
required_providers {
coder = {
@@ -69,7 +69,7 @@ provider will be limited to all versions matching `1.0.x`.
The above also applies to Terraform modules. In the below example, the module
`razzledazzle` is locked to version `1.2.3`.
```terraform
```tf
module "razzledazzle" {
source = "registry.example.com/modules/razzle/dazzle"
version = "1.2.3"
@@ -64,7 +64,7 @@ You can create and manage external workspaces using either the **CLI** or the **
1. **Create an external workspace**
```bash
```sh
coder external-workspaces create hello-world \
--template=externally-managed-workspace -y
```
@@ -74,13 +74,13 @@ You can create and manage external workspaces using either the **CLI** or the **
2. **List external workspaces**
```bash
```sh
coder external-workspaces list
```
Example output:
```bash
```sh
WORKSPACE TEMPLATE STATUS HEALTHY LAST BUILT CURRENT VERSION OUTDATED
hello-world externally-managed-workspace Started true 15m happy_mendel9 false
```
@@ -89,13 +89,13 @@ You can create and manage external workspaces using either the **CLI** or the **
Use this command to query the script you must run on the external machine:
```bash
```sh
coder external-workspaces agent-instructions hello-world
```
Example:
```bash
```sh
Please run the following command to attach external agent to the workspace hello-world:
curl -fsSL "https://<DEPLOYMENT_URL>/api/v2/init-script/linux/amd64" | CODER_AGENT_TOKEN="<token>" sh
@@ -103,7 +103,7 @@ You can create and manage external workspaces using either the **CLI** or the **
You can also output JSON for automation:
```bash
```sh
coder external-workspaces agent-instructions hello-world --output=json
```
@@ -92,7 +92,7 @@ in the right-hand corner of the page to delete the template.
Using the CLI, login to Coder and run the following command to delete a
template:
```shell
```sh
coder templates delete <template-name>
```
+2 -2
View File
@@ -25,7 +25,7 @@ The id in the template's `coder_external_auth` data source must match the
If you want the template to clone a specific git repo:
```hcl
```tf
# Require external authentication to use this template
data "coder_external_auth" "github" {
id = "primary-github"
@@ -56,7 +56,7 @@ resource "coder_agent" "dev" {
If you want the template to support any repository via
[parameters](./extending-templates/parameters.md)
```hcl
```tf
# Require external authentication to use this template
data "coder_external_auth" "github" {
id = "primary-github"
@@ -6,7 +6,7 @@ This example shows a complete, production-ready script that starts Claude Code
only after a repository has been cloned. It includes error handling, graceful
degradation, and cleanup on exit:
```bash
```sh
#!/bin/bash
set -euo pipefail
@@ -81,7 +81,7 @@ We've omitted some details (such as persistent storage) for brevity, but these a
### Before
```terraform
```tf
data "coder_provisioner" "me" {}
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}
@@ -139,7 +139,7 @@ Based on the above, we can improve both the startup time and reliability of the
Here is the updated version of the template:
```terraform
```tf
data "coder_provisioner" "me" {}
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}
@@ -26,7 +26,7 @@ The goal of startup script coordination is to provide a single reliable source o
To start using workspace startup coordination, add calls to `coder exp sync (start|complete)` in your startup scripts where required:
```bash
```sh
trap 'coder exp sync complete my-script' EXIT
coder exp sync want my-script my-other-script
coder exp sync start my-script
@@ -7,14 +7,14 @@
From a workspace terminal, test if sync is working using `coder exp sync ping`:
```bash
```sh
coder exp sync ping
```
* If sync is working, expect the output to be `Success`.
* Otherwise, you will see an error message similar to the below:
```bash
```sh
error: connect to agent socket: connect to socket: dial unix /tmp/coder-agent.sock: connect: permission denied
```
@@ -22,13 +22,13 @@ error: connect to agent socket: connect to socket: dial unix /tmp/coder-agent.so
You can check the status of a specific unit using `coder exp sync status`:
```bash
```sh
coder exp sync status git-clone
```
If the unit exists, you will see output similar to the below:
```bash
```sh
# coder exp sync status git-clone
Unit: git-clone
Status: completed
@@ -37,7 +37,7 @@ Ready: true
If the unit is not known to the agent, you will see output similar to the below:
```bash
```sh
# coder exp sync status doesnotexist
Unit: doesnotexist
Status: not registered
@@ -51,13 +51,13 @@ No dependencies found
If you are unsure which units are registered, or want a quick overview of every unit's state, use `coder exp sync list`:
```bash
```sh
coder exp sync list
```
This displays all registered units, their statuses, and whether they are ready to start:
```bash
```sh
UNIT STATUS READY
git-clone completed true
env-setup started true
@@ -66,7 +66,7 @@ ide-configure pending false
You can also get JSON output for scripting:
```bash
```sh
coder exp sync list --output json
```
@@ -89,7 +89,7 @@ If the workspace startup scripts fail:
* Review `/tmp/coder-script-*.log` inside the workspace for script errors.
* Verify the Coder CLI is available in `$PATH` inside the workspace:
```bash
```sh
command -v coder
```
@@ -97,7 +97,7 @@ If the workspace startup scripts fail:
If you see an error similar to the below in your startup script logs, you have defined a cyclic dependency:
```bash
```sh
error: declare dependency failed: cannot add dependency: adding edge for unit "bar": failed to add dependency
adding edge (bar -> foo): cycle detected
```
@@ -34,7 +34,7 @@ To use startup dependencies in your templates, you must:
Here's a simple example of a script that depends on another unit completing
first:
```bash
```sh
#!/bin/bash
UNIT_NAME="my-setup"
@@ -59,7 +59,7 @@ own work.
If your unit depends on multiple other units, you can declare all dependencies
before starting:
```bash
```sh
#!/bin/bash
UNIT_NAME="my-app"
DEPENDENCIES="git-clone,env-setup,database-migration"
@@ -91,13 +91,13 @@ coder exp sync complete "$UNIT_NAME"
Use `coder exp sync list` to see all registered units and their current state:
```bash
```sh
coder exp sync list
```
Example output:
```bash
```sh
UNIT STATUS READY
git-clone completed true
env-setup started true
@@ -126,7 +126,7 @@ Once you're satisfied, [promote the new template version](../../../reference/cli
Not all workspaces will have the Coder CLI available in `$PATH`. Check for availability of the Coder CLI before using
sync commands:
```bash
```sh
if command -v coder > /dev/null 2>&1; then
coder exp sync start "$UNIT_NAME"
else
@@ -139,7 +139,7 @@ fi
Units **must** call `coder exp sync complete` to unblock dependent units. Use `trap` to ensure
completion even if your script exits early or encounters errors:
```bash
```sh
SYNC_STARTED=0
if coder exp sync start "$UNIT_NAME"; then
@@ -173,7 +173,7 @@ ensure that your unit does not conflict with others.
Add comments explaining why dependencies exist:
```hcl
```tf
resource "coder_script" "ide_setup" {
# Depends on git-clone because we need .vscode/extensions.json
# Depends on env-setup because we need $NODE_PATH configured
@@ -189,7 +189,7 @@ resource "coder_script" "ide_setup" {
The Coder Agent detects and rejects circular dependencies, but they indicate a design problem:
```bash
```sh
# This will fail
coder exp sync want "unit-a" "unit-b"
coder exp sync want "unit-b" "unit-a"
@@ -224,7 +224,7 @@ Upon timeout, the command will exit with an error code and print `timeout waitin
You can adjust this timeout as necessary for long-running operations:
```bash
```sh
coder exp sync start "long-operation" --timeout 10m
```
+5 -5
View File
@@ -132,7 +132,7 @@ what's going on.
Here's a short example of an informative startup script:
```shell
```sh
echo "Running startup script..."
echo "Run: long-running-command"
/path/to/long-running-command
@@ -184,7 +184,7 @@ Refer to [Cannot connect to the Docker daemon](../../install/docker.md#cannot-co
When you query `ContainerMemory` and encounter the error:
```shell
```sh
open /sys/fs/cgroup/memory.max: no such file or directory
```
@@ -204,19 +204,19 @@ This error mostly affects Raspberry Pi OS, but might also affect older Debian-ba
1. Add cgroup entries to `cmdline.txt` in `/boot/firmware` (or `/boot/` on older Pi OS releases):
```text
```txt
cgroup_memory=1 cgroup_enable=memory
```
You can use `sed` to add it to the file for you:
```bash
```sh
sudo sed -i '$s/$/ cgroup_memory=1 cgroup_enable=memory/' /boot/firmware/cmdline.txt
```
1. Reboot:
```bash
```sh
sudo reboot
```
+7 -7
View File
@@ -34,13 +34,13 @@ To use the default configuration:
1. By default, only the admin user can sign up.
To allow additional users to sign up with GitHub, add:
```shell
```sh
CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS=true
```
1. (Optional) If you want to limit sign-ups to specific GitHub organizations, set:
```shell
```sh
CODER_OAUTH2_GITHUB_ALLOWED_ORGS="your-org"
```
@@ -49,7 +49,7 @@ To use the default configuration:
You can disable the default GitHub app by [configuring your own app](#step-1-configure-the-oauth-application-in-github)
or by adding the following environment variable to your [Coder server configuration](../../reference/cli/server.md#options):
```shell
```sh
CODER_OAUTH2_GITHUB_DEFAULT_PROVIDER_ENABLE=false
```
@@ -87,7 +87,7 @@ CODER_OAUTH2_GITHUB_DEFAULT_PROVIDER_ENABLE=false
Go to your Coder host and run the following command to start up the Coder server:
```shell
```sh
coder server --oauth2-github-allow-signups=true --oauth2-github-allowed-orgs="your-org" --oauth2-github-client-id="8d1...e05" --oauth2-github-client-secret="57ebc9...02c24c"
```
@@ -98,7 +98,7 @@ Alternatively, if you are running Coder as a system service, you can achieve the
same result as the command above by adding the following environment variables
to the `/etc/coder.d/coder.env` file:
```shell
```sh
CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS=true
CODER_OAUTH2_GITHUB_ALLOWED_ORGS="your-org"
CODER_OAUTH2_GITHUB_CLIENT_ID="8d1...e05"
@@ -136,7 +136,7 @@ coder:
To upgrade Coder, run:
```shell
```sh
helm upgrade <release-name> coder-v2/coder -n <namespace> -f values.yaml
```
@@ -152,7 +152,7 @@ This is enabled by default for the default GitHub app and cannot be disabled for
For your own custom GitHub OAuth app, you can enable device flow by setting:
```shell
```sh
CODER_OAUTH2_GITHUB_DEVICE_FLOW=true
```
+8 -8
View File
@@ -15,7 +15,7 @@ synchronize Coder groups, roles, and organizations based on claims from your IdP
To confirm that your OIDC provider is sending claims, log in with OIDC and visit
the following URL with an `Owner` account:
```text
```txt
https://[coder.example.com]/api/v2/debug/[your-username]/debug-link
```
@@ -53,7 +53,7 @@ group sync for each organization.
1. Fetch the corresponding group IDs using the following endpoint:
```text
```txt
https://[coder.example.com]/api/v2/groups
```
@@ -301,7 +301,7 @@ Visit the Coder UI to confirm these changes:
1. Set the following in your Coder server [configuration](../setup/index.md).
```env
```dotenv
# Depending on your identity provider configuration, you may need to explicitly request a "roles" scope
CODER_OIDC_SCOPES=openid,profile,email,offline_access,roles
@@ -335,7 +335,7 @@ You can initiate an organization sync through the Coder dashboard or CLI:
1. Fetch the corresponding organization IDs using the following endpoint:
```text
```txt
https://[coder.example.com]/api/v2/organizations
```
@@ -454,12 +454,12 @@ If you enable this, your OIDC provider might be sending over many unnecessary
groups. Use filtering options on the OIDC provider to limit the groups sent over
to prevent creating excess groups.
```env
```dotenv
# as an environment variable
CODER_OIDC_GROUP_AUTO_CREATE=true
```
```shell
```sh
# as a flag
--oidc-group-auto-create=true
```
@@ -471,12 +471,12 @@ want to filter out groups that do not match a certain pattern. For example, if
you want to only allow groups that start with `my-group-` to be created, you can
set the following environment variable.
```env
```dotenv
# as an environment variable
CODER_OIDC_GROUP_REGEX_FILTER="^my-group-.*$"
```
```shell
```sh
# as a flag
--oidc-group-regex-filter="^my-group-.*$"
```
+8 -8
View File
@@ -82,7 +82,7 @@ The new user will appear in the **Users** list. Use the toggle to change their
To create a user via the Coder CLI, run:
```shell
```sh
coder users create
```
@@ -116,7 +116,7 @@ To suspend a user via the web UI:
To suspend a user via the CLI, run:
```shell
```sh
coder users suspend <username|user_id>
```
@@ -135,7 +135,7 @@ To activate a user via the web UI:
To activate a user via the CLI, run:
```shell
```sh
coder users activate <username|user_id>
```
@@ -161,7 +161,7 @@ logging in.
You can also reset a password via the CLI:
```shell
```sh
# run `coder reset-password <username> --help` for usage instructions
coder reset-password <username>
```
@@ -172,7 +172,7 @@ coder reset-password <username>
### Resetting a password on Kubernetes
```shell
```sh
kubectl exec -it deployment/coder -n coder -- /bin/bash
coder reset-password <username>
@@ -232,7 +232,7 @@ You can use the Coder CLI or API to retrieve your list of users.
Use `users list` to export the list of users to a CSV file:
```shell
```sh
coder users list > users.csv
```
@@ -242,7 +242,7 @@ Visit the [users list](../../reference/cli/users_list.md) documentation for more
Use [get users](../../reference/api/users.md#get-users):
```shell
```sh
curl -X GET http://coder-server:8080/api/v2/users \
-H 'Accept: application/json' \
-H 'Coder-Session-Token: API_KEY'
@@ -250,7 +250,7 @@ curl -X GET http://coder-server:8080/api/v2/users \
To export the results to a CSV file, you can use [`jq`](https://jqlang.org/) to process the JSON response:
```shell
```sh
curl -X GET http://coder-server:8080/api/v2/users \
-H 'Accept: application/json' \
-H 'Coder-Session-Token: API_KEY' | \
+2 -2
View File
@@ -19,7 +19,7 @@ This guide shows how to configure Coder to authenticate users with Google using
Set the following environment variables on your Coder deployment and restart Coder:
```env
```dotenv
CODER_OIDC_ISSUER_URL=https://accounts.google.com
CODER_OIDC_CLIENT_ID=<client id>
CODER_OIDC_CLIENT_SECRET=<client secret>
@@ -39,7 +39,7 @@ CODER_OIDC_ICON_URL=/icon/google.svg
Google uses auth URL parameters to issue refresh tokens. Configure:
```env
```dotenv
# Keep standard scopes
CODER_OIDC_SCOPES=openid,profile,email
# Add Google-specific auth URL params
+8 -8
View File
@@ -13,7 +13,7 @@ Your OIDC provider will ask you for the following parameter:
Set the following environment variables on your Coder deployment and restart Coder:
```env
```dotenv
CODER_OIDC_ISSUER_URL="https://issuer.corp.com"
CODER_OIDC_EMAIL_DOMAIN="your-domain-1,your-domain-2"
CODER_OIDC_CLIENT_ID="533...des"
@@ -57,7 +57,7 @@ Coder requires all OIDC email addresses to be verified by default. If the
provider, Coder will validate that its value is `true`. If needed, you can
disable this behavior with the following setting:
```env
```dotenv
CODER_OIDC_IGNORE_EMAIL_VERIFIED=true
```
@@ -84,7 +84,7 @@ If your upstream identity provider uses a different claim, you can set
If you'd like to change the OpenID Connect button text and/or icon, you can
configure them like so:
```env
```dotenv
CODER_OIDC_SIGN_IN_TEXT="Sign in with Gitea"
CODER_OIDC_ICON_URL=https://gitea.io/images/gitea.png
```
@@ -107,13 +107,13 @@ The general steps to configure persistent user sessions are:
For most providers, add the `offline_access` scope:
```env
```dotenv
CODER_OIDC_SCOPES=openid,profile,email,offline_access
```
For Google, add auth URL parameters (`CODER_OIDC_AUTH_URL_PARAMS`) too:
```env
```dotenv
CODER_OIDC_SCOPES=openid,profile,email
CODER_OIDC_AUTH_URL_PARAMS='{"access_type": "offline", "prompt": "consent"}'
```
@@ -130,7 +130,7 @@ The general steps to configure persistent user sessions are:
To remove email and password login, set the following environment variable on
your Coder deployment:
```env
```dotenv
CODER_DISABLE_PASSWORD_AUTH=true
```
@@ -157,7 +157,7 @@ authentication. Upon deactivation, users are
[Configure](../../setup/index.md) your SCIM application with an auth key and supply
it the Coder server.
```env
```dotenv
CODER_SCIM_AUTH_HEADER="your-api-key"
```
@@ -166,7 +166,7 @@ CODER_SCIM_AUTH_HEADER="your-api-key"
If your OpenID Connect provider requires client TLS certificates for
authentication, you can configure them like so:
```env
```dotenv
CODER_TLS_CLIENT_CERT_FILE=/path/to/cert.pem
CODER_TLS_CLIENT_KEY_FILE=/path/to/key.pem
```
+2 -2
View File
@@ -24,7 +24,7 @@ This guide shows how to configure Coder to authenticate users with Microsoft Ent
Set the following environment variables on your Coder deployment and restart Coder:
```env
```dotenv
CODER_OIDC_ISSUER_URL=https://login.microsoftonline.com/{tenant-id}/v2.0 # Replace {tenant-id} with your Azure tenant ID
CODER_OIDC_CLIENT_ID=<client id, located in "Overview">
CODER_OIDC_CLIENT_SECRET=<client secret, saved from step 6>
@@ -42,7 +42,7 @@ CODER_OIDC_ICON_URL=/icon/microsoft.svg
## Enable refresh tokens (recommended)
```env
```dotenv
# Keep standard scopes
CODER_OIDC_SCOPES=openid,profile,email,offline_access
```
+4 -4
View File
@@ -35,7 +35,7 @@ Go to the Azure Portal > **Azure Active Directory** > **App registrations** > Yo
1. In your [Coder configuration](../../../reference/cli/server.md#--oidc-auth-url-params), request the same scopes:
```env
```dotenv
CODER_OIDC_SCOPES=openid,profile,email,offline_access
```
@@ -60,7 +60,7 @@ Without this, users will be logged out when their access token expires.
In your [Coder configuration](../../../reference/cli/server.md#--oidc-auth-url-params):
```env
```dotenv
CODER_OIDC_SCOPES=openid,profile,email
CODER_OIDC_AUTH_URL_PARAMS='{"access_type": "offline", "prompt": "consent"}'
```
@@ -76,7 +76,7 @@ including the ability to refresh access tokens without requiring the user to rea
Add the `offline_access` scope to enable refresh tokens in your
[Coder configuration](../../../reference/cli/server.md#--oidc-auth-url-params):
```env
```dotenv
CODER_OIDC_SCOPES=openid,profile,email,offline_access
CODER_OIDC_AUTH_URL_PARAMS='{"access_type":"offline"}'
```
@@ -99,7 +99,7 @@ CODER_OIDC_AUTH_URL_PARAMS='{"access_type":"offline"}'
1. In your [Coder configuration](../../../reference/cli/server.md#--oidc-scopes), add the `offline_access` scope:
```env
```dotenv
CODER_OIDC_SCOPES=openid,profile,email,offline_access
```
+1 -1
View File
@@ -79,7 +79,7 @@ provisioner as the built-in provisioners are scoped to the default organization.
1. Using Coder CLI, run the following command to create a key that will be used
to authenticate the provisioner:
```shell
```sh
coder provisioner keys create data-cluster-key --org data-platform
Successfully created provisioner key data-cluster! Save this authentication token, it will not be shown again.
+1 -1
View File
@@ -29,7 +29,7 @@ quota than an online workspace.
A common use case is separating costs for a persistent volume and ephemeral
compute:
```hcl
```tf
resource "docker_volume" "home_volume" {
name = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}-root"
}
+1 -1
View File
@@ -141,7 +141,7 @@ per template. You can do so by installing the
[binary](https://github.com/coder/boundary) into the workspace image or at
start-up. You can do so with the following command:
```bash
```sh
curl -fsSL https://raw.githubusercontent.com/coder/boundary/main/install.sh | bash
```
@@ -93,7 +93,7 @@ above (or add "clone" to the list of allowed syscalls).
Once updated, you can run the container with the custom seccomp profile:
```bash
```sh
docker run -it \
--cap-add=NET_ADMIN \
--security-opt seccomp=seccomp-v25.0.13.json \
+1 -1
View File
@@ -26,7 +26,7 @@ with `NET_ADMIN`) so that Agent Firewall can create namespaces and run nsjail.
**Task definition (Terraform) — `linuxParameters`:**
```hcl
```tf
container_definitions = jsonencode([{
name = "coder-agent"
image = "your-coder-agent-image"
+2 -2
View File
@@ -97,7 +97,7 @@ spec:
User namespaces are often disabled (`user.max_user_namespaces=0`) on Bottlerocket
nodes. Check and enable user namespaces:
```bash
```sh
# Check current value
sysctl user.max_user_namespaces
@@ -108,7 +108,7 @@ sysctl -w user.max_user_namespaces=65536
If `sysctl -w` is not allowed, configure it via Bottlerocket bootstrap settings
when creating the node group (e.g., in Terraform):
```hcl
```tf
bootstrap_extra_args = <<-EOT
[settings.kernel.sysctl]
"user.max_user_namespaces" = "65536"
+3 -3
View File
@@ -39,7 +39,7 @@ a path-safe convenience for reading supporting files.
### Directory structure
```text
```txt
.agents/skills/
├── deep-review/
│ ├── SKILL.md
@@ -57,7 +57,7 @@ a path-safe convenience for reading supporting files.
Each `SKILL.md` starts with YAML frontmatter containing a `name` and an
optional `description`, followed by the full instructions in markdown:
```markdown
```md
---
name: deep-review
description: "Multi-reviewer code review with domain-specific reviewers"
@@ -93,7 +93,7 @@ frontmatter with a kebab-case `name`, an optional `description`, and a
markdown body. This keeps content portable between personal skills and
workspace skills.
```markdown
```md
---
name: personal-reviewer
description: "Personal review guidance"
+1 -1
View File
@@ -269,7 +269,7 @@ curl -X POST https://coder.example.com/api/experimental/chats \
Stream updates in real time by connecting to the WebSocket endpoint:
```text
```txt
GET /api/experimental/chats/{chat}/stream
```
@@ -6,13 +6,13 @@
## Enable the experiment
```shell
```sh
coder server --experiments=chat-advisor
```
Or set the environment variable:
```shell
```sh
CODER_EXPERIMENTS=chat-advisor
```
@@ -27,7 +27,7 @@ is `3650` days.
Use the experimental admin API to read or update the value:
```text
```txt
GET /api/experimental/chats/config/debug-retention-days
PUT /api/experimental/chats/config/debug-retention-days
```
@@ -30,7 +30,7 @@ disable retention entirely.
Use the experimental admin API to read or update the value:
```text
```txt
GET /api/experimental/chats/config/retention-days
PUT /api/experimental/chats/config/retention-days
```
@@ -13,7 +13,7 @@ For public `github.com`, no additional configuration is needed.
For self-hosted GitHub Enterprise, add `API_BASE_URL` to your
[existing configuration](../../../admin/external-auth/index.md#github-enterprise):
```env
```dotenv
CODER_EXTERNAL_AUTH_0_ID="primary-github"
CODER_EXTERNAL_AUTH_0_TYPE=github
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
@@ -45,7 +45,7 @@ The default GitLab scopes (`read_user`) are sufficient for basic
authentication. To use merge request features (diffs, status checks) with
Coder Agents, configure:
```env
```dotenv
CODER_EXTERNAL_AUTH_0_ID="primary-gitlab"
CODER_EXTERNAL_AUTH_0_TYPE=gitlab
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
@@ -62,7 +62,7 @@ pushing commits and creating merge requests.
For self-hosted GitLab, set `AUTH_URL` and `TOKEN_URL` to your instance.
Coder derives `API_BASE_URL` automatically from `AUTH_URL`:
```env
```dotenv
CODER_EXTERNAL_AUTH_0_ID="primary-gitlab"
CODER_EXTERNAL_AUTH_0_TYPE=gitlab
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
@@ -236,7 +236,7 @@ The agent reads `display_name` and `description` fields to understand what a
parameter controls. Treat these the same way you treat template descriptions —
be specific and use natural language.
```hcl
```tf
data "coder_parameter" "region" {
name = "region"
display_name = "Deployment Region"
@@ -288,7 +288,7 @@ For guidance on building and maintaining workspace images, see
If the template targets a specific repository, pre-clone it and set the
working directory so the agent starts in the right place:
```hcl
```tf
resource "coder_agent" "main" {
os = "linux"
arch = "amd64"
@@ -6,13 +6,13 @@
## Enable the experiment
```shell
```sh
coder server --experiments=chat-virtual-desktop
```
Or set the environment variable:
```shell
```sh
CODER_EXPERIMENTS=chat-virtual-desktop
```
@@ -167,7 +167,7 @@ curl https://coder.example.com/api/v2/tasks/me/my-task/logs \
**Chats API**. You open a one-way WebSocket connection:
```text
```txt
GET wss://coder.example.com/api/experimental/chats/{chat}/stream
```
+1 -1
View File
@@ -90,7 +90,7 @@ outranks a lower tier, regardless of usage.
Within a relevance tier, or when no query is given, templates are ordered by
an affinity score:
```text
```txt
affinity = 10 x (active + 0.5 x deleted) x 0.5^(days_since_last_use / 14)
+ ln(1 + active_developers)
```
@@ -14,7 +14,7 @@ Once enabled, `coderd` runs the AI Gateway Proxy in-process and intercepts traff
AI Gateway Proxy is disabled by default. To enable it, set the following configuration options:
```shell
```sh
CODER_AI_GATEWAY_ENABLED=true \
CODER_AI_GATEWAY_PROXY_ENABLED=true \
CODER_AI_GATEWAY_PROXY_CERT_FILE=/path/to/ca.crt \
@@ -34,7 +34,7 @@ See [CA Certificate](#ca-certificate) for how to generate and obtain these files
By default, the proxy listener accepts plain HTTP connections.
To serve the listener over HTTPS, provide a TLS certificate and key:
```shell
```sh
CODER_AI_GATEWAY_PROXY_TLS_CERT_FILE=/path/to/listener.crt
CODER_AI_GATEWAY_PROXY_TLS_KEY_FILE=/path/to/listener.key
# or via CLI flags:
@@ -56,7 +56,7 @@ By default, this is the embedded AI Gateway at `<coderd-access-url>/api/v2/ai-ga
To forward intercepted requests to an AI Gateway that is not embedded in this Coder deployment, set:
```shell
```sh
CODER_AI_GATEWAY_PROXY_TARGET=https://ai-gateway.example.com/
# or via CLI flag:
--ai-gateway-proxy-target=https://ai-gateway.example.com/
@@ -97,7 +97,7 @@ To prevent unauthorized use, restrict network access to the proxy so that only a
In case the AI Gateway [proxy target](#proxy-target) hostname (the Coder access URL by default) resolves to a private address, it is automatically exempt from this restriction so the proxy can always reach the configured AI Gateway.
If you need to allow access to additional internal networks via the proxy, use the Allowlist CIDRs option ([`CODER_AI_GATEWAY_PROXY_ALLOWED_PRIVATE_CIDRS`](../../../reference/cli/server.md#--ai-gateway-proxy-allowed-private-cidrs)):
```shell
```sh
CODER_AI_GATEWAY_PROXY_ALLOWED_PRIVATE_CIDRS=10.0.0.0/8,172.16.0.0/12
# or via CLI flag:
--ai-gateway-proxy-allowed-private-cidrs=10.0.0.0/8,172.16.0.0/12
@@ -117,14 +117,14 @@ Generate a CA certificate specifically for AI Gateway Proxy:
1) Generate a private key:
```shell
```sh
openssl genrsa -out ca.key 4096
chmod 400 ca.key
```
1) Create a self-signed CA certificate (valid for 10 years):
```shell
```sh
openssl req -new -x509 -days 3650 \
-key ca.key \
-out ca.crt \
@@ -133,7 +133,7 @@ openssl req -new -x509 -days 3650 \
Configure AI Gateway Proxy with both files:
```shell
```sh
CODER_AI_GATEWAY_PROXY_CERT_FILE=/path/to/ca.crt
CODER_AI_GATEWAY_PROXY_KEY_FILE=/path/to/ca.key
```
@@ -145,7 +145,7 @@ This simplifies deployment since AI tools that already trust your organization's
Your organization's CA issues a certificate and private key pair for the proxy. Configure the proxy with both files:
```shell
```sh
CODER_AI_GATEWAY_PROXY_CERT_FILE=/path/to/intermediate-ca.crt
CODER_AI_GATEWAY_PROXY_KEY_FILE=/path/to/intermediate-ca.key
```
@@ -167,7 +167,7 @@ AI tools need to trust the CA certificate before connecting through the proxy.
For **self-signed certificates**, AI tools must be configured to trust the CA certificate. The certificate (without the private key) is available at:
```shell
```sh
https://<coder-url>/api/v2/ai-gateway/proxy/ca-cert.pem
```
@@ -191,7 +191,7 @@ The AI Gateway Proxy enforces a minimum TLS version of 1.2.
In addition to the required proxy configuration, set the following to enable TLS on the proxy:
```shell
```sh
CODER_AI_GATEWAY_PROXY_TLS_CERT_FILE=/path/to/listener.crt
CODER_AI_GATEWAY_PROXY_TLS_KEY_FILE=/path/to/listener.key
# or via CLI flags:
@@ -210,14 +210,14 @@ Without a matching SAN, clients will reject the connection.
1) Generate a private key:
```shell
```sh
openssl genrsa -out listener.key 4096
chmod 400 listener.key
```
1) Create a self-signed certificate:
```shell
```sh
openssl req -new -x509 -days 365 \
-key listener.key \
-out listener.crt \
@@ -269,13 +269,13 @@ To ensure AI Gateway also routes requests through the upstream proxy, make sure
Configure the upstream proxy URL:
```shell
```sh
CODER_AI_GATEWAY_PROXY_UPSTREAM=http://<corporate-proxy-url>:8080
```
For HTTPS upstream proxies, if the upstream proxy uses a certificate not trusted by the system, provide the CA certificate:
```shell
```sh
CODER_AI_GATEWAY_PROXY_UPSTREAM=https://<corporate-proxy-url>:8080
CODER_AI_GATEWAY_PROXY_UPSTREAM_CA=/path/to/corporate-ca.crt
```
@@ -296,7 +296,7 @@ Consult the tool's documentation for specific instructions.
Alternatively, most tools support the standard `HTTPS_PROXY` environment variable, though this is not guaranteed for all tools:
```shell
```sh
export HTTPS_PROXY="https://coder:${CODER_SESSION_TOKEN}@<proxy-host>:8888"
```
@@ -320,7 +320,7 @@ Consult the tool's documentation for specific instructions.
Download the certificate:
```shell
```sh
curl -o coder-ai-gateway-proxy-ca.pem \
-H "Coder-Session-Token: ${CODER_SESSION_TOKEN}" \
https://<coder-url>/api/v2/ai-gateway/proxy/ca-cert.pem
@@ -331,7 +331,7 @@ Replace `<coder-url>` with your Coder deployment URL.
When [TLS is enabled](#proxy-tls-configuration) on the proxy, AI tools must trust both the [MITM CA certificate](#ca-certificate) and the [TLS certificate](#proxy-tls-configuration).
Combine both certificates into a single PEM file:
```shell
```sh
cat coder-ai-gateway-proxy-ca.pem listener.crt > combined-ca.pem
```
@@ -351,7 +351,7 @@ Different AI tools use different runtimes, each with their own environment varia
Set the environment variables associated with the AI tool's runtime.
If you're unsure which runtime the tool uses, or if you use multiple AI tools, the simplest approach is to set all of them:
```shell
```sh
export NODE_EXTRA_CA_CERTS="/path/to/coder-ai-gateway-proxy-ca.pem"
export SSL_CERT_FILE="/path/to/coder-ai-gateway-proxy-ca.pem"
export REQUESTS_CA_BUNDLE="/path/to/coder-ai-gateway-proxy-ca.pem"
@@ -365,7 +365,7 @@ This makes the certificate trusted by all applications on the system.
On Linux:
```shell
```sh
sudo cp coder-ai-gateway-proxy-ca.pem /usr/local/share/ca-certificates/
sudo update-ca-certificates
```
@@ -400,7 +400,7 @@ This primarily affects deployments using a self-signed or internal CA, since pub
in the system trust store.
If the certificate is signed by a CA not in the system trust store, the connection fails and the Coder server logs:
```shell
```sh
WARN: Cannot read TLS response from mitm'd server tls: failed to verify certificate: x509: certificate signed by unknown authority
```
@@ -412,7 +412,7 @@ reloads the trust store.
If an AI tool fails with:
```shell
```sh
x509: certificate signed by unknown authority
```
@@ -426,7 +426,7 @@ The proxy intercepts HTTPS traffic only for hostnames matching the base URL of a
Gateway. Check that the provider is enabled and its base URL matches the hostname the tool is connecting to. Verify that
`HTTPS_PROXY` points at the proxy. When interception is working, coderd logs:
```shell
```sh
routing MITM request to AI Gateway
```
@@ -438,7 +438,7 @@ The Coder token must be supplied as the password in the proxy credentials, for e
`https://coder:${CODER_SESSION_TOKEN}@<proxy-host>:8888`. When a CONNECT request has no usable token, the proxy replies
with `407 Proxy Authentication Required` and logs:
```shell
```sh
WARN rejecting CONNECT request host=... provider=... reason=missing_credentials
```
@@ -459,7 +459,7 @@ See [Client Configuration](#client-configuration) for how to configure the proxy
Tunneled requests to private or reserved IP ranges are blocked by default. When a request is blocked, coderd logs:
```shell
```sh
WARN blocking connection to private/reserved IP hostname=... port=... resolved_ip=...
```
@@ -9,7 +9,7 @@ Claude Code can be configured using environment variables. All modes require a *
## Centralized API Key
```bash
```sh
# AI Gateway base URL.
export ANTHROPIC_BASE_URL="<your-deployment-url>/api/v2/ai-gateway/anthropic"
@@ -19,7 +19,7 @@ export ANTHROPIC_AUTH_TOKEN="<your-coder-api-token>"
## BYOK (Personal API Key)
```bash
```sh
# AI Gateway base URL.
export ANTHROPIC_BASE_URL="<your-deployment-url>/api/v2/ai-gateway/anthropic"
@@ -35,7 +35,7 @@ unset ANTHROPIC_AUTH_TOKEN
## BYOK (Claude Subscription)
```bash
```sh
# AI Gateway base URL.
export ANTHROPIC_BASE_URL="<your-deployment-url>/api/v2/ai-gateway/anthropic"
@@ -53,7 +53,7 @@ account.
Template admins can pre-configure Claude Code for a seamless experience. Admins can automatically inject the user's Coder session token and the AI Gateway base URL into the workspace environment.
```hcl
```tf
module "claude-code" {
source = "registry.coder.com/coder/claude-code/coder"
version = "4.7.3"
@@ -67,7 +67,7 @@ module "claude-code" {
[Coder Tasks](../../tasks.md) provides a framework for agents to complete background development operations autonomously. Claude Code can be configured in your Tasks automatically:
```hcl
```tf
resource "coder_ai_task" "task" {
count = data.coder_workspace.me.start_count
app_id = module.claude-code.task_app_id
+4 -4
View File
@@ -23,7 +23,7 @@ wire_api = "responses"
To authenticate with AI Gateway, get your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)** and set it in your environment:
```bash
```sh
export OPENAI_API_KEY="<your-coder-api-token>"
```
@@ -46,7 +46,7 @@ env_http_headers = { "X-Coder-AI-Governance-Token" = "CODER_API_TOKEN" }
Set both environment variables:
```bash
```sh
# Your personal OpenAI API key, forwarded to OpenAI.
export OPENAI_API_KEY="<your-openai-api-key>"
@@ -79,7 +79,7 @@ env_http_headers = { "X-Coder-AI-Governance-Token" = "CODER_API_TOKEN" }
Set your Coder API token and ensure `OPENAI_API_KEY` is not set:
```bash
```sh
# Your Coder API token, used for authentication with AI Gateway.
export CODER_API_TOKEN="<your-coder-api-token>"
@@ -150,7 +150,7 @@ Responses API. AI Gateway does not support WebSocket transport, so each
request attempts a WebSocket connection and retries up to 5 times before
falling back to HTTPS. When this happens you will see:
```text
```txt
Falling back from WebSockets to HTTPS transport.
```
+3 -3
View File
@@ -27,7 +27,7 @@ For installation instructions, see [GitHub Copilot CLI documentation](https://do
Set the `HTTPS_PROXY` environment variable:
```shell
```sh
export HTTPS_PROXY="https://coder:${CODER_API_TOKEN}@<proxy-host>:8888"
```
@@ -39,7 +39,7 @@ Note: if [TLS is not enabled](../ai-gateway-proxy/setup.md#proxy-tls-configurati
Copilot CLI is built on Node.js and uses the `NODE_EXTRA_CA_CERTS` environment variable for custom certificates:
```shell
```sh
export NODE_EXTRA_CA_CERTS="/path/to/coder-ai-gateway-proxy-ca.pem"
```
@@ -47,7 +47,7 @@ See [Client Configuration CA certificate trust](../ai-gateway-proxy/setup.md#tru
When [TLS is enabled](../ai-gateway-proxy/setup.md#proxy-tls-configuration) on the proxy, combine the MITM CA certificate and the TLS certificate into a single file:
```shell
```sh
cat coder-ai-gateway-proxy-ca.pem listener.crt > combined-ca.pem
export NODE_EXTRA_CA_CERTS="/path/to/combined-ca.pem"
```
+1 -1
View File
@@ -68,7 +68,7 @@ While users can manually configure these tools with a long-lived API key, templa
In this example, Claude Code respects these environment variables and will route all requests via AI Gateway.
```hcl
```tf
data "coder_workspace_owner" "me" {}
data "coder_workspace" "me" {}
+1 -1
View File
@@ -85,7 +85,7 @@ module "mux" {
If you prefer a file-based config, edit `~/.mux/providers.jsonc`:
```jsonc
```json
{
"openai": {
"apiKey": "<your-coder-api-token>",
+2 -2
View File
@@ -26,7 +26,7 @@ AI Gateway makes use of [External Auth](../../admin/external-auth/index.md) appl
For example, GitHub has a [remote MCP server](https://github.com/github/github-mcp-server?tab=readme-ov-file#remote-github-mcp-server) and we can use it as follows.
```bash
```sh
CODER_EXTERNAL_AUTH_0_TYPE=github
CODER_EXTERNAL_AUTH_0_CLIENT_ID=...
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=...
@@ -38,7 +38,7 @@ See the diagram in [Implementation Details](./reference.md#implementation-detail
You can also control which tools are injected by using an allow and/or a deny regular expression on the tool names:
```env
```dotenv
CODER_EXTERNAL_AUTH_0_MCP_TOOL_ALLOW_REGEX=(.+_gist.*)
CODER_EXTERNAL_AUTH_0_MCP_TOOL_DENY_REGEX=(create_gist)
```
@@ -146,7 +146,7 @@ Unlike the scalar settings above, you **cannot mix the two prefixes**. Setting
both `CODER_AIBRIDGE_PROVIDER_*` and `CODER_AI_GATEWAY_PROVIDER_*` variables in
the same deployment causes startup to fail with:
```text
```txt
cannot mix CODER_AIBRIDGE_PROVIDER_* and CODER_AI_GATEWAY_PROVIDER_* environment variables, please consolidate onto CODER_AI_GATEWAY_PROVIDER_*
```
+1 -1
View File
@@ -47,7 +47,7 @@ persistence on the agentapi module. Set `enable_state_persistence = true`
so that AgentAPI saves and restores conversation history across pause and
resume cycles:
```hcl
```tf
module "agentapi" {
source = "registry.coder.com/coder/agentapi/coder"
version = ">= 2.2.0"
+4 -4
View File
@@ -96,7 +96,7 @@ You must also set `coder-template-name` as part of this. The GHA example has thi
- By viewing the URL of the template in the UI, e.g. `https://<your-coder-url>/templates/<org-name>/<template-name>`
- Using the Coder CLI:
```bash
```sh
# List all templates in your organization
coder templates list
@@ -110,7 +110,7 @@ You can also choose to modify the other [input parameters](https://github.com/co
If your prompt uses the GitHub CLI `gh`, your template must pass the user's GitHub token to the agent. Add this to your template's Terraform:
```terraform
```tf
data "coder_external_auth" "github" {
id = "github" # Must match your CODER_EXTERNAL_AUTH_0_ID
}
@@ -165,7 +165,7 @@ We recommend that you further adapt this workflow to better match your process.
- Modify the underlying use case to handle updating documentation, implementing a small feature, reviewing bug reports for completeness, or even writing unit tests
- Modify the workflow trigger for other scenarios such as:
```yml
```yaml
# Comment-based trigger slash commands
on:
issue_comment:
@@ -251,7 +251,7 @@ Generate a new token with these permissions at `https://<your-coder-url>/deploym
From within the running task workspace, check if the token is still valid:
```bash
```sh
# Check if the token still works
curl -H "Authorization: token ${GITHUB_TOKEN}" \
https://api.github.com/user
+1 -1
View File
@@ -66,7 +66,7 @@ The following code snippet can be dropped into any existing template in Coder v2
> [!NOTE]
> This requires at least version 2.13.0 of the `coder/coder` Terraform provider.
```hcl
```tf
data "coder_parameter" "setup_script" {
name = "setup_script"
display_name = "Setup Script"
+3 -3
View File
@@ -108,7 +108,7 @@ version that includes this support.
For Claude Code, update the module version in your template:
```hcl
```tf
module "claude-code" {
source = "registry.coder.com/coder/claude-code/coder"
version = ">= 4.8.0" # Minimum version with pause/resume support
@@ -160,7 +160,7 @@ modules performing cleanup.
**Docker**: Add to your `docker_container` resource:
```hcl
```tf
resource "docker_container" "workspace" {
# Both attributes are needed for graceful shutdown.
destroy_grace_seconds = 300 # 5 minutes
@@ -172,7 +172,7 @@ resource "docker_container" "workspace" {
**Kubernetes**: Add to your `kubernetes_pod` resource:
```hcl
```tf
resource "kubernetes_pod" "main" {
timeouts {
delete = "6m" # Must exceed the grace period below.
+2 -2
View File
@@ -72,7 +72,7 @@ resource "coder_ai_task" "task" {
Below is a minimal illustrative example of a Coder Tasks template pre-2.28.0.
**Note that this is NOT a full template.**
```hcl
```tf
terraform {
required_providers {
coder = {
@@ -128,7 +128,7 @@ In v2.28 and above, the following changes were made:
Example (**not** a full template):
```hcl
```tf
terraform {
required_providers {
coder = {
+1 -1
View File
@@ -63,7 +63,7 @@ A template becomes a Task-capable template if it defines a `coder_ai_task` resou
> [!NOTE]
> The `coder_ai_task` resource is not defined within the [Claude Code Module](https://registry.coder.com/modules/coder/claude-code?tab=readme). You need to define it yourself.
```hcl
```tf
terraform {
required_providers {
coder = {
@@ -128,7 +128,7 @@ ruby --version
The command fails:
```text
```txt
ruby: command not found
```

Some files were not shown because too many files have changed in this diff Show More