mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
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:
@@ -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
|
||||

|
||||
|
||||
<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
|
||||

|
||||
```
|
||||
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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
|
||||

|
||||
|
||||
<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 seconds.
|
||||
Connection latency under 150 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.
|
||||
```
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
```
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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.
|
||||
```
|
||||
|
||||
|
||||
@@ -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]
|
||||
```
|
||||
|
||||
|
||||
@@ -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"
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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' | \
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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/
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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>
|
||||
```
|
||||
|
||||
|
||||
@@ -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"
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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`
|
||||
```
|
||||
|
||||
|
||||
@@ -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...`
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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>
|
||||
```
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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>
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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-.*$"
|
||||
```
|
||||
|
||||
@@ -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' | \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
```
|
||||
|
||||
|
||||
@@ -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"
|
||||
```
|
||||
|
||||
@@ -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" {}
|
||||
|
||||
@@ -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>",
|
||||
|
||||
@@ -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_*
|
||||
```
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user