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.*
## Summary
Fixes two classes of invalid/broken HTML in hand-written docs. Both are
visible problems in today's rendered docs, independent of any
docs-engine work.
1. **`</br>` is not a real HTML tag.** `br` is a void element with no
closing form; browsers error-correct `</br>`, but it is invalid HTML.
Replaced all 15 usages with `<br />` across:
- `docs/admin/templates/extending-templates/dynamic-parameters.md`
- `docs/admin/users/idp-sync.md`
- `docs/tutorials/best-practices/organizations.md`
2. **Browser-swallowed placeholder URL.** In
`docs/ai-coder/github-to-tasks.md`,
`https://<your-coder-url>/settings/external-auth` was unformatted, so
HTML renderers parse `<your-coder-url>` as an unknown tag and drop it.
The live docs currently render the broken text `re-authenticate at
https:///settings/external-auth`. Wrapped in backticks, matching every
other instance in the same file.
Table realignment noise in the diff is from `fmt/markdown` (`<br />` is
one character wider than `</br>`).
A repo-wide grep confirms no remaining `</br>` and no other unformatted
`https://<placeholder>` URLs in prose (other hits are inside code fences
or already backticked). The equivalent placeholder issues in
**generated** reference docs (CLI help strings, swagger annotations) are
intentionally out of scope and tracked separately in
[DOCS-551](https://linear.app/codercom/issue/DOCS-551/backtick-placeholder-syntax-in-generated-reference-docs-cli-help).
Tracking issue:
[DOCS-550](https://linear.app/codercom/issue/DOCS-550/fix-invalid-br-tags-and-browser-swallowed-placeholder-url-in-hand)
---
Created by Coder Agents on behalf of @nickvigilante.
Lands the first concrete rule under the `Coder` style:
`Coder.BrandNames`, a bundled `substitution` rule that enforces
canonical brand casing in prose. HashiCorp is the first entry;
[DOCS-188](https://linear.app/codercom/issue/DOCS-188) extends it with
GitHub, OpenTofu, Kubernetes, Terraform, JetBrains, and VS Code.
## What changes
Four commits, ordered so each is independently valid:
1. **`docs: fix HashiCorp casing in prose and sidebar`**
([06d769dad1](https://github.com/coder/coder/pull/25501/commits/06d769dad179cf85c535b058df3b6bafdc1f9565)).
5 Markdown files plus 2 `docs/manifest.json` entries. Drives the corpus
violation count to zero.
2. **`feat(docs/.style/styles/Coder): add Coder.BrandNames Vale rule`**
([e00fc780a7](https://github.com/coder/coder/pull/25501/commits/e00fc780a7a20dcf82105d997af5cfcddd4b1855)).
New `BrandNames.yml` with the HashiCorp swap at `level: error`, plus a
new `### Brand names` subsection in `docs/.style/style-guide.md`.
3. **`docs(.style/styles/Coder/README.md): scrub planned-rules notes
obsoleted by Coder.BrandNames`**
([af8833b9f5](https://github.com/coder/coder/pull/25501/commits/af8833b9f58dd617732ae533bbf53eb4fc2e816a)).
Removes the README's "intentionally empty for now" lead-in and the
obsolete HashiCorp casing bullet from the planned-coverage list.
4. **`docs: apply semantic line breaks and fix Vale findings on
PR-touched files`**
([e9f11df188](https://github.com/coder/coder/pull/25501/commits/e9f11df1886fdf0d5efc5e8a2cab95fecbd898f9)).
Pre-review pass on every Markdown file this PR modifies. Full sembr and
Vale-warning cleanup on the style-guide infrastructure
(`style-guide.md`, `Coder/README.md`); sembr applied to the HashiCorp
swap paragraph only on the five product docs, per scoping discussion
with @nickvigilante.
## Severity rationale
`error` from day one. HashiCorp's brand owner publishes a canonical
casing; any other casing in prose is wrong, not a judgment call. Matches
the `error = low FPs x high gravity` framework. False-positive rate is
effectively zero because Vale's `substitution` rule skips inline code,
fenced code blocks, and URLs by default, so `hashicorp/kubernetes`
(Terraform provider source) and `developer.hashicorp.com` stay
untouched.
## Verification
- `make lint/markdown`: 0 errors across 487 files.
- `make lint/prose`: 1 error, 1 warning, 1 suggestion in 468 files. All
three findings are the intentional `Coder.DemoError`,
`Coder.DemoWarning`, and `Coder.DemoSuggestion` annotations on
`docs/.style/style-guide/demo/demo.md` (added on main as part of the
[DOCS-425](https://linear.app/codercom/issue/DOCS-425) inline-annotation
demo), not real findings. `Coder.BrandNames` fires zero times against
the cleaned-up corpus.
- `make pre-commit-light`: passed (7s).
- Self-test: ran the rule against an unmodified `docs/` and confirmed it
flags the 7 prose instances the cleanup commit fixes, then re-ran
against the post-cleanup state and confirmed zero alerts.
## Known future conflict
When [#26632](https://github.com/coder/coder/pull/26632)
([DOCS-434](https://linear.app/codercom/issue/DOCS-434)) merges, the
monolithic `docs/.style/style-guide.md` is split into the
`docs/.style/style-guide/` multi-page structure. The `### Brand names`
subsection added in commit 2 will need to land in
`docs/.style/style-guide/word-choice.md` (which already references the
rule), and the `link:` in `docs/.style/styles/Coder/BrandNames.yml` will
need to update from `style-guide.md#brand-names` to
`style-guide/word-choice.md#brand-names`. Resolution path documented in
an inline comment on this PR.
<details>
<summary>Implementation plan and decision log</summary>
### Why bundle into Coder.BrandNames rather than one file per brand
Vale's convention (mirrored by `Google.WordList` with ~70 swaps in a
single file) is to bundle `substitution` rules when they share severity,
message template, and link. All brand-name rules share that shape:
`error`, `Use '%s' instead of '%s'`, link to the style guide section.
Bundling reduces "add a brand" to a one-line YAML diff and keeps
`CODEOWNERS` and blame coherent. Per-rule performance is irrelevant at
this scale; Vale's per-rule overhead is sub-millisecond and dwarfed by
Markdown parsing.
### Why the cleanup lands first
Commits are ordered cleanup-then-rule so each commit is a known-good
state:
- After commit 1: corpus is HashiCorp-clean, but no rule exists yet.
- After commit 2: rule exists and lints a clean corpus.
Reversing the order would land the rule at commit 1 (firing 7 errors on
uncleaned content) and resolve them at commit 2. Under `--no-exit` the
CI job still passes, but the inline annotations on commit 1 would be
misleading.
### Why HashiCorp first instead of all brands at once
Proof-of-concept value. HashiCorp is the smallest cleanup (7 prose lines
plus 2 sidebar lines = 9 lines), zero FPs, zero ambiguity. Once the loop
(rule plus cleanup plus style-guide section) is proven,
[DOCS-188](https://linear.app/codercom/issue/DOCS-188) appends the other
brands as additional commits to the same bundle.
### Brand-token sensitivity
The `swap:` table only matches:
- `Hashicorp` (capital H, lowercase rest), the actual wrong form in the
corpus.
- `HASHICORP` (all caps), defensive; doesn't appear in current corpus
but cheap to include.
`hashicorp` (all lowercase) is **not** in the swap table. The lowercase
form appears 49 times in URLs (`developer.hashicorp.com`,
`registry.terraform.io/providers/hashicorp/...`,
`github.com/hashicorp/...`) and 6 times as Terraform provider sources
(`source = "hashicorp/kubernetes"`), all of which are correct lowercase
by convention. Vale's substitution rule scope ensures URLs and code
blocks are skipped, but skipping the rule entirely for `hashicorp`
(lowercase) is the explicit decision; if a prose typo of lowercase
"hashicorp" ever shows up, we'd catch it through `Vale.Spelling`
([DOCS-187](https://linear.app/codercom/issue/DOCS-187)) instead.
### Self-reference in the style guide
The `### Brand names` section's example table needed `Hashicorp` and
`HashiCorp` as literal demonstration tokens. Wrapping them in backticks
(`` `Hashicorp` ``, `` `HashiCorp` ``) keeps Vale from flagging the
wrong-case example as a real violation. This is correct typography too:
demonstration tokens get code formatting.
### Manifest.json
Vale doesn't lint JSON, so the two `docs/manifest.json` entries are
fixed by direct edit rather than tool enforcement. The sidebar `path`
(`./admin/integrations/vault.md`) is unchanged; the title change does
not affect the page URL on coder.com. No redirect needed in
`coder/coder.com:redirects.json`.
### Pre-mortem
- **Generated docs noise**: `Coder.BrandNames` does not fire on
auto-generated `docs/reference/` content because no codersdk identifier
matches the swap pattern. Zero risk.
- **Future-additions friction**: adding GitHub to the swap table is one
YAML line and a cleanup commit. The bundling shape pays off here.
- **Disable footgun**: if a contributor needs to write the wrong casing
on purpose (quoting an external bug report verbatim, for example), they
can wrap the literal in backticks (already correct typography) or use
the per-line Vale skip comment.
</details>
Closes [DOCS-34](https://linear.app/codercom/issue/DOCS-34).
---
*Filed via [Coder Agents](https://coder.com/docs/ai-coder/agents) on
Nick's behalf.*
## What
Add `DOCKER_HOST` guidance for non-default Docker socket paths to two
pages:
- `docs/install/docker.md`: expands the **Cannot connect to the Docker
daemon**
troubleshooting section with the `DOCKER_HOST` fix and how to persist it
to
your shell startup file.
- `docs/admin/templates/troubleshooting.md`: adds a concise **Cannot
connect to
the Docker daemon** entry that cross-references the install guide for
the full
steps.
## Why
`install/docker.md` previously documented only the default socket path
(`/var/run/docker.sock`). When Docker runs through a tool that uses a
per-user
socket, such as rootless Docker on Linux, or Colima, Podman, or Rancher
Desktop
on macOS, the daemon exposes its socket at a non-default path, so the
Coder
server cannot connect until `DOCKER_HOST` is set. The guidance frames
Colima as
one example, notes that default socket paths vary by tool, and persists
the
setting in a shell-agnostic way.
Generated by Coder Agents on behalf of @nickvigilante.
Makes it easier to pick the right workspace image, both in the template
builder and in the docs.
- Template builder: the Docker and Kubernetes bases now expose a
`container_image` variable in the wizard (freeform text, defaults to
`codercom/example-base:ubuntu`), and their prerequisites explain why
image choice matters, with tradeoffs between
`codercom/example-base:ubuntu` (minimal) and
`codercom/example-universal:ubuntu` (catch-all), plus pointers to
[coder/images](https://github.com/coder/images) and the image management
docs.
- Docs: reworked [image
management](https://coder.com/docs/@ben%2Fdevrel-201-image-guidance-prereqs/admin/templates/managing-templates/image-management)
into a clearer maturity ladder (minimal → golden → project-specific →
developer customization), with pullable image references in every
example, `codercom/oss-dogfood` as a project-specific example, and Dev
Containers + [mise](https://mise.jdx.dev/) as ways to customize without
new images.
Companion PR for the starter templates: coder/registry#943
Part of DEVREL-201.
🤖 Generated with Coder Agents using Claude, on behalf of @bpmct (wizard
variable by @jeremyruppel in #27024)
---------
Co-authored-by: Jeremy Ruppel <jeremyruppel@users.noreply.github.com>
## Summary
Update documentation across 9 files to present the template builder as
the primary template creation method, replacing the old starter
templates flow as the default entry point.
The template builder is a guided wizard that lets admins select base
infrastructure, add registry modules, configure variables, and produce
validated Terraform without writing HCL.
## Changes
**Primary docs (significant rewrites):**
- `docs/admin/templates/creating-templates.md`: Added "Using the
template builder" as the first section with full 5-step wizard
documentation, screenshots, airgap/registry notes, and alternative
creation links. Moved CLI starter template flow to its own section.
Fixed "You can the" typo.
- `docs/get-started/index.md`: Rewrote Steps 4-6 to use the builder with
the Docker base template instead of the Coder Quickstart (which is not a
builder base template). Generalized workspace parameter instructions.
- `docs/start/first-template.md`: Rewrote to use the builder. Removed
old starter templates references, TODO notes, typo, and commented-out
sections.
**Secondary docs (targeted edits):**
- `docs/admin/templates/index.md`: Replaced starter templates section
with builder-first "Create a template" section.
- `docs/admin/templates/managing-templates/index.md`: Renamed "Starter
templates" to "Creating templates" pointing to the builder.
- `docs/install/airgap.md`: Added "Template builder" section documenting
`CODER_DISABLE_TEMPLATE_BUILDER` and
`CODER_TEMPLATE_BUILDER_REGISTRY_URL`.
- `docs/tutorials/template-from-scratch.md`: Added TIP callout
recommending the builder. Fixed `coder templates create` -> `coder
templates push` inconsistency.
- `docs/admin/integrations/devcontainers/envbuilder/add-envbuilder.md`:
Updated Dashboard tab to reference the builder and "Upload an existing
template" alternative.
- `docs/about/screenshots.md`: Updated caption and image reference for
template builder.
**Screenshots added:**
- `templatebuilder_01_bases.png` (base selection step)
- `templatebuilder_02_modules.png` (module selection step)
- `templatebuilder_03_module_customization.png` (module settings step)
- `templatebuilder_04_customizations.png` (template customizations step)
<details>
<summary>Implementation plan</summary>
# Plan: Update docs/ for Template Builder Launch
## Summary
The Template Builder is a new guided wizard at `/templates/new/builder`
that lets admins create templates by selecting a base infrastructure
template, composing it with registry modules, configuring variables, and
producing a validated Terraform bundle without writing HCL. The docs
need to be updated to present this as the primary/recommended template
creation path, while preserving the existing paths (upload, CLI,
duplicate) as alternatives.
## Key behavioral facts from the code
- **Route**: `/templates/new/builder` (new), `/templates/new` (old,
still exists)
- **Entry point**: The "New Template" button on the Templates page links
to `/templates/new/builder` when the builder is enabled; otherwise falls
back to `/starter-templates`
- **5-step wizard**:
1. **Select base infrastructure** (e.g., Docker, AWS EC2, Kubernetes)
2. **Base template parameters** (optional, skipped if base has none)
3. **Select modules** (IDE, AI Agent, Source Control, etc.;
multi-select, grouped by category)
4. **Module settings** (optional, skipped if no configurable variables)
5. **Template customizations** (name, display name, description, icon,
organization)
- **Alternative creation links** are shown on step 1: "Start from
scratch", "Upload an existing template", "Browse community templates",
"Use template agent skill"
- **Disabled via**: `CODER_DISABLE_TEMPLATE_BUILDER` env var /
`--disable-template-builder` flag. When disabled, redirects to old
`/templates/new` flow
- **Registry URL override**: `CODER_TEMPLATE_BUILDER_REGISTRY_URL`
(default: `registry.coder.com`)
- **Requires outbound access** to `registry.coder.com` for `terraform
init` at compose time
- **Modules are bundled** with the Coder release binary; the builder
does not fetch metadata from the registry at runtime
- **Sensitive variables** (secrets) are not collected by the builder;
they are deferred to workspace creation time
- **Module conflicts** show a warning but do not block creation
- **One-way**: No re-entry into the builder for existing templates; edit
HCL directly after creation
## Files to update
### Tier 1: Primary creation flow docs (significant rewrites)
#### 1. `docs/admin/templates/creating-templates.md`
**Current state**: Documents three creation paths: "From a starter
template" (primary), "From an existing template", "From scratch
(advanced)".
**Changes**:
- Add a new section **"Using the template builder"** as the first and
primary section (before "From a starter template").
- Describe the 5-step wizard flow: select base infrastructure, configure
base parameters, select modules, configure module settings, set template
customizations.
- Mention that the builder is enabled by default and requires outbound
access to `registry.coder.com`.
- Note that sensitive variables are collected from developers at
workspace creation, not during template building.
- Add a callout about disabling the builder for airgapped deployments
(`CODER_DISABLE_TEMPLATE_BUILDER`).
- Note the `CODER_TEMPLATE_BUILDER_REGISTRY_URL` option for self-hosted
registry mirrors.
- Keep existing "From a starter template", "From an existing template",
and "From scratch" sections largely intact, but reframe them as
alternative paths.
- Update the "From a starter template" Web UI instructions to note the
new entry point routing (the "New Template" button now goes to the
builder when enabled).
- Fix existing typo: "You can the [Coder CLI]" should be "You can use
the [Coder CLI]".
#### 2. `docs/start/first-template.md`
**Current state**: Beginner tutorial walking through creating a template
from the Docker starter template via the old flow. Has a typo (`s` at
end of line 32), commented-out workspace creation section, and TODO
notes.
**Changes**:
- Rewrite steps 2 and 3 to use the Template Builder as the primary path.
- Step 2: Navigate to **Templates**, select **New Template**, which
opens the Template Builder.
- Step 3: Walk through the builder wizard steps (select Docker base,
optionally select modules like code-server, configure template
name/description, create).
- Remove the typo on line 32 (`s`).
- Keep the "Modify your template" section (step 6) intact since it
covers post-creation editing which is unchanged.
- Remove or update the reference to "Starter Templates" as a separate
page since the builder subsumes that entry point.
#### 3. `docs/get-started/index.md`
**Current state**: Quickstart guide. Step 4 says "Select **Templates** →
**New Template**" then pick "Coder Quickstart" from starter templates.
**Changes**:
- Update Step 4 to describe using the Template Builder.
- The flow becomes: Select **Templates** → **New Template** → builder
opens → select **Coder Quickstart** as the base template → optionally
add modules → set name/description → **Create Template**.
- Update the "What just happened?" explanation to mention the builder
composed and validated the Terraform.
- Screenshot reference `create-quickstart-template.png` will need a new
screenshot (note this in the PR; screenshots are out of scope for this
change but should be flagged).
### Tier 2: Secondary references (targeted edits)
#### 4. `docs/admin/templates/index.md`
**Current state**: Overview page mentioning starter templates as the
primary creation path.
**Changes**:
- Update the "Starter templates" section to mention the Template Builder
as the recommended way to create templates, with starter templates
serving as base templates within the builder.
- Update the link to point to the builder section: `[Create a template
with the template
builder](./creating-templates.md#using-the-template-builder)`.
- Update the screenshot reference and caption. The "Starter Templates"
page screenshot may no longer be the first thing admins see.
#### 5. `docs/admin/templates/managing-templates/index.md`
**Current state**: Documents starter templates, editing, updating,
deleting.
**Changes**:
- Update the "Starter templates" section to mention the Template Builder
as the primary creation path, with starter templates available as base
templates within it.
- Update the image reference from `starter-templates.png` if it shows
the old flow.
#### 6. `docs/tutorials/template-from-scratch.md`
**Current state**: Detailed tutorial for writing a template from scratch
with Terraform.
**Changes**:
- Add a brief note at the top recommending the Template Builder for
users who want to create templates without writing Terraform, with a
link to
`docs/admin/templates/creating-templates.md#using-the-template-builder`.
- In section "7. Create the template in Coder" → "Dashboard" tab, update
the UI steps. The "Upload template" option is now accessed via the old
creation flow at `/templates/new` (or through the "Upload an existing
template" link in the builder's alternatives).
- Fix the inconsistency where text says `coder templates create` but the
code block uses `coder templates push`.
#### 7.
`docs/admin/integrations/devcontainers/envbuilder/add-envbuilder.md`
**Current state**: Documents creating envbuilder templates via
Dashboard, CLI, and Registry tabs.
**Changes**:
- In the Dashboard tab, update the instructions. The "Create Template"
button now opens the builder by default. Users need to use the "Upload
an existing template" alternative link or navigate to `/templates/new`
directly.
- Update "From scratch" reference since that option is now an
alternative link in the builder.
- The CLI and Registry tabs remain unchanged.
#### 8. `docs/install/airgap.md`
**Current state**: Documents air-gapped installations. No mention of
Template Builder.
**Changes**:
- Add a note in the relevant section about the Template Builder
requiring outbound access to `registry.coder.com`.
- Document `CODER_DISABLE_TEMPLATE_BUILDER` for fully air-gapped
deployments.
- Document `CODER_TEMPLATE_BUILDER_REGISTRY_URL` for deployments using a
self-hosted registry mirror.
#### 9. `docs/about/screenshots.md`
**Current state**: Contains a caption "Template administrators can
either create a new Template from scratch or choose a Starter Template".
**Changes**:
- Update the caption to mention the Template Builder as the primary
creation method.
- Screenshot reference may need updating (flag for new screenshot).
### Tier 3: Minor/link-only updates
#### 10. `docs/admin/users/organizations.md`
- If it references the old "Create Template" screen with an org picker,
add a note that the Template Builder also includes organization
selection in its final step.
#### 11. `docs/ai-coder/tasks.md`
- If it mentions creating templates, add a passing reference to the
Template Builder as an option.
## Files NOT to update
- `docs/reference/api/templatebuilder.md`: Auto-generated API reference.
Already correct.
- `docs/reference/api/schemas.md`: Auto-generated. Already correct.
- `docs/reference/cli/server.md`: Auto-generated. Already has
`--disable-template-builder` and `--template-builder-registry-url`.
- `docs/reference/cli/templates_create.md`: Already deprecated.
- `docs/reference/cli/templates.md`: No changes needed.
## Implementation order
1. `docs/admin/templates/creating-templates.md` (primary creation docs,
most content)
2. `docs/get-started/index.md` (quickstart)
3. `docs/start/first-template.md` (beginner tutorial)
4. `docs/admin/templates/index.md` (overview)
5. `docs/admin/templates/managing-templates/index.md` (managing
overview)
6. `docs/install/airgap.md` (airgap note)
7. `docs/tutorials/template-from-scratch.md` (from-scratch tutorial)
8. `docs/admin/integrations/devcontainers/envbuilder/add-envbuilder.md`
(envbuilder)
9. `docs/about/screenshots.md` (screenshot captions)
10. Minor link/reference updates in tier 3 files
## Style notes
- Follow the Diataxis framework; keep tutorials as tutorials, reference
as reference.
- Use present tense, active voice, second person.
- Bold for UI elements: **Templates**, **New Template**, **Create
Template**.
- No emdash/endash.
- Do not add screenshots; flag where new screenshots are needed as
comments/TODOs.
- Run `make fmt/markdown` and `make lint/markdown` after all changes.
- Verify all pages are already in `docs/manifest.json` (no new pages
being added, only existing pages being updated).
</details>
> 🤖 Generated by Coder Agents
Add a top-level "Get started" docs section to the nav and move the Quickstart to /docs/get-started, with inbound link updates and the install page TIP pointing to the Quickstart.
Filed via Coder Agents on Nick's behalf.
Closes [DOCS-415](https://linear.app/codercom/issue/DOCS-415).
## TL;DR
Repoints 7 broken links across 5 docs files that the 2026-06-22 weekly
`check-docs.yml` Linkspector run flagged. Two other links from the same
run (the dead `nix` ref and the dead `reflectoring.io` ref in
`CONTRIBUTING.md`) were already folded into
[#26341](https://github.com/coder/coder/pull/26341).
## Why
Broken external and anchor links degrade reader trust, leak SEO juice,
and make the docs look stale. The weekly `check-docs` job exists
precisely to catch this kind of rot before customers do; the
surfacing-to-fix turnaround on these 7 is one PR. Run that surfaced
them: [actions/runs/27948011619 job
82697664858](https://github.com/coder/coder/actions/runs/27948011619/job/82697664858).
## Scope
| File | Line(s) | Old target | New target | Why |
|------|---------|-----------|------------|-----|
| `docs/tutorials/best-practices/organizations.md` | 62 | anchor
`#update-template-metadata-by-id` | `#update-template-settings-by-id` |
API endpoint renamed in
[#19228](https://github.com/coder/coder/pull/19228) (Aug 2025). New
heading at line 1105 of `docs/reference/api/templates.md`. |
| `docs/install/registry-mirror-artifactory.md` | 197 | JFrog
`terraform-registry` |
`terraform-opentofu-and-terraform-backend-repositories` | JFrog
consolidated their Terraform / OpenTofu / Backend docs into a single
page. |
| `docs/admin/templates/extending-templates/modules.md` | 76, 206 |
JFrog `set-up-a-terraform-module/provider-registry` and
`terraform-registry` | same consolidated JFrog page (root, no anchor) |
Same JFrog consolidation. Anchor dropped, see decision log. |
| `docs/admin/integrations/dx-data-cloud.md` | 84 |
`https://help.getdx.com/en/` | `https://docs.getdx.com/` | DX migrated
their help center to a separate docs domain. |
| `docs/about/contributing/frontend.md` | 37, 71 |
`https://reactrouter.com/en/main` | `https://reactrouter.com/` | React
Router dropped the `/en/main` prefix. |
## Validation
- All 7 replacement URLs return HTTP 200 (manual `curl -L -o /dev/null
-w '%{http_code}'` per URL; linkspector's puppeteer crashed in the agent
env, so it was run case-by-case)
- `make lint/markdown lint/emdash` clean locally
- Pre-commit hook (`scripts/githooks/pre-commit` -> `make
pre-commit-light`) clean
- No `/docs/` route changes; pure markdown content
## Not triggering `/coder-agents-review`
Docs-only markdown edit, no CI or build config changes; per `AGENTS.md`
the bot review is reserved for product / CI changes. `doc-check` handles
this category.
## Pre-mortem
| Concern | Mitigation |
|---|---|
| Replacement URL also turns out to be broken later | All 7 verified
HTTP 200 today; next weekly `check-docs` run will catch any future
regression. |
| JFrog anchor drop on `modules.md` (76, 206) loses navigation context |
Verified the consolidated JFrog page has no clean section anchor for the
original target; linking the root page is the honest fix. If JFrog ships
a better TOC anchor later, a follow-up can reattach. |
| Anchor rename in `organizations.md` was actually a different rename |
Confirmed via PR #19228 (Aug 2025) which is the exact rename that
produced `## Update template settings by ID`. |
<details>
<summary>Decision log</summary>
**Why drop the anchor on the JFrog `modules.md` links (76 + 206)**:
JFrog's new consolidated page
(`/terraform-opentofu-and-terraform-backend-repositories`) doesn't
expose the original `set-up-a-terraform-module/provider-registry`
section as a fragment-link target. The honest fix is to link the page
root; readers can scroll. The `registry-mirror-artifactory.md:197`
reference uses the same root link for symmetry.
**Why DX `docs.getdx.com` over `help.getdx.com`**: DX's help center at
`help.getdx.com/en/` now returns 404. They moved to a separate
`docs.getdx.com` domain with a different content structure. Linking the
docs root is the closest analog to the original "browse our docs"
intent.
**Why React Router root over `/en/main`**: React Router unified their
docs under the root URL. The `/en/main` prefix is no longer routable.
The root URL is the canonical successor.
</details>
<details>
<summary>CI: <code>audit-docs-paths</code> failure (pre-existing,
unrelated)</summary>
The `audit-docs-paths` job in `.github/workflows/weekly-docs.yaml` fails
on this PR because its `Fetch redirects.json` step issues an
unauthenticated `curl` to a file in private `coder/coder.com` and gets a
404 (exit code 22). Same failure on every recent PR in this repo.
Tracked in [DOCS-409](https://linear.app/codercom/issue/DOCS-409) and
fixed in [#26571](https://github.com/coder/coder/pull/26571), which
authenticates the fetch through the Contents API. My changes are
docs-content only (5 markdown files, 7 line changes) and don't touch the
TS/TSX paths or `redirects.json` that the audit examines, so this is a
pre-existing CI break, not a regression introduced here.
</details>
---
*Generated by Coder Agents on @nickvigilante's behalf.*
Closes [DOCS-351](https://linear.app/codercom/issue/DOCS-351).
> [!WARNING]
> **DO NOT MERGE** until
[DOCS-349](https://linear.app/codercom/issue/DOCS-349)
([coder.com#877](https://github.com/coder/coder.com/pull/877)) has
shipped to production and baked for at least one Vercel cycle.
>
> Without DOCS-349, the relative links in this PR resolve to broken
docs-route URLs (`/docs/helm/coder/values.yaml` -> 404) instead of
GitHub URLs tagged with the displayed docs version. DOCS-349 fixes the
rewriter to classify these as GitHub blob/tree URLs with the page's
resolved ref.
## TL;DR
Converts 121 absolute
`https://github.com/coder/coder/(blob|tree)/main/<path>` links across 39
docs markdown files to relative paths. After this lands AND DOCS-349
deploys, every one of these links will follow the displayed docs version
(mainline tag on bare URLs, explicit tag on `/@vX.Y.Z/`, `main` on
`/@main/`) instead of always pointing to `main`.
## Why
Today a reader on `/docs/@v2.30.0/install/docker` follows a
`compose.yaml` link and arrives at `main`'s `compose.yaml`, which
doesn't necessarily match what the docs page describes. Helm values,
Terraform templates, and source-code references in particular drift
across versions. The fix is to let the coder.com rewriter substitute the
page's resolved ref into the URL; that only works on relative links.
## Example payoff (post-DOCS-349)
| URL | Today (absolute, always `main`) | After (relative + rewriter) |
|---|---|---|
| `/docs/install/docker` |
`https://github.com/coder/coder/blob/main/compose.yaml` |
`https://github.com/coder/coder/blob/v2.34.1/compose.yaml` (today's
mainline) |
| `/docs/@v2.30.0/install/docker` | same as above |
`https://github.com/coder/coder/blob/v2.30.0/compose.yaml` |
| `/docs/@main/install/docker` | same as above |
`https://github.com/coder/coder/blob/main/compose.yaml` |
## Scope
- **121 conversions** across **39 files**.
- Verb breakdown: `tree/main` (directories) and `blob/main` (files),
both flipped to relative paths.
- Line anchors (`#L23-L24`) and query strings preserved verbatim.
- Conversion is mechanical: relative path computed from the doc file's
directory to the target via `os.path.relpath`. Any path starting at the
same directory or below gets a `./` prefix; otherwise `../` chains.
## Rebased on main
The branch was rebased onto `main` after the DOCS-350 hotfix
([#26339](https://github.com/coder/coder/pull/26339)) merged. The hotfix
repointed 3 `docs-backend-contrib-guide` refs in `backend.md` to `main`,
which then needed the same `main` -> relative conversion this PR is
doing for the other 121 links. The conflict was resolved by reapplying
the mechanical conversion to `backend.md` after taking the hotfix's
content. Net result: those 3 links land here as relative, same as
everything else. New HEAD `3f501cb622`.
## Inline fix folded in: dead `nix` link
- `docs/about/contributing/CONTRIBUTING.md:7` -> `../../../nix`
The original absolute URL `https://github.com/coder/coder/tree/main/nix`
already returned 404 today. Repointed to `flake.nix` (modern Nix
entrypoint, what the prose "Nix environment" semantically refers to).
Closes [DOCS-357](https://linear.app/codercom/issue/DOCS-357) here since
the `check-docs` Linkspector job surfaced it during rebase; cheaper to
fix inline than in a separate single-line PR.
## Out of scope (filed separately)
- [DOCS-350](https://linear.app/codercom/issue/DOCS-350): 3 dead
`docs-backend-contrib-guide` branch refs in `backend.md`
([#26339](https://github.com/coder/coder/pull/26339), merged).
- [DOCS-352](https://linear.app/codercom/issue/DOCS-352): 10 SHA-pinned
`(blob|tree)/<sha>` links pending intent review.
- [DOCS-355](https://linear.app/codercom/issue/DOCS-355): code-server
analog (4 absolute `(blob|tree)/main` links in `coder/code-server`).
- [DOCS-356](https://linear.app/codercom/issue/DOCS-356): 2 upstream
content bugs in `coder/code-server/docs/CONTRIBUTING.md` (independent of
this PR).
## Not triggering `/coder-agents-review`
Docs-only edit; per `AGENTS.md` the bot review is reserved for
product/CI changes.
## Pre-mortem
| Concern | Mitigation |
|---|---|
| Merging before DOCS-349 deploys regresses ~120 currently-working links
into 404s on coder.com | Clear DO-NOT-MERGE banner; tracked as blocker
in Linear. |
| Relative path computed incorrectly (off-by-one `..`) | Verified all
114 newly-relative non-md/non-image paths resolve to existing files in
the repo (only exception is the pre-existing dead `nix` link above). |
| Line anchors stripped during conversion | Preserved by the
substitution regex; verified `#L<n>-L<m>` cases in `airgap.md` and
`speed-up-templates.md`. |
| Future code reorgs change file locations | Relative links will start
pointing to nothing. Same failure mode as absolute links pointing to
renamed files; can be caught with a future link-checker job. |
## Validation
```
$ grep -rE 'github\.com/coder/coder/(blob|tree)/main' docs --include="*.md" | wc -l
0
$ git diff --stat origin/main | tail -1
39 files changed, 118 insertions(+), 118 deletions(-)
```
114 newly-relative paths verified to resolve to existing repo files
(Python `os.path.exists` check on each computed target).
<details>
<summary>Decision log + planning context</summary>
**Why relative over `(blob|tree)/{{currentDocsVersion}}/...`
templating**: relative paths require zero markdown-system support and
zero upstream churn beyond this one PR. Templating would require a
preprocessor on `coder.com` side AND a convention upstream authors have
to remember; relative paths just work in a plain editor and
`github.com`'s own renderer too.
**Why `./` prefix on same-directory targets**: makes the conversion
grep-able later (`grep -E '\((\.\./|\./)'`).
**Why preserve `#L<n>-L<m>` anchors verbatim**: the anchor is meaningful
to the linked file's content, not to the URL form; keeping it as-is
preserves authorial intent. If the file later changes such that the line
range drifts, that's a different problem the SHA-pin audit
([DOCS-352](https://linear.app/codercom/issue/DOCS-352)) will surface.
</details>
---
*Generated by Coder Agents on @nickvigilante's behalf.*
## Drive-by external link fix folded in
`docs/about/contributing/CONTRIBUTING.md:296` cited
`https://reflectoring.io/meaningful-commit-messages/` which is returning
HTTP 503 (the host appears to be down site-wide right now). `check-docs`
Linkspector flagged it after the rebase. Replaced with
`https://cbea.ms/git-commit/` (Chris Beams' canonical "If applied, this
commit will..." article, confirmed 200), which is the original source of
the rule the prose recites anyway.
Follow-up to #26443. Documents the new `coder exp sync list` command in
the startup coordination guides.
**troubleshooting.md:**
- New "List All Units" section after "Check Unit Status" with example
output
- Added `coder exp sync list` to the "Workspace startup script hangs"
checklist, since users debugging hanging scripts may not know which unit
to query
**usage.md:**
- New "Inspect Unit State" section covering `list`, `status`, and `ping`
- Updated "Test your changes" checklist to reference `coder exp sync
list`
> Generated by Coder Agents on behalf of @SasSwart
Resolves the issue of `--prompt-ephemeral-parameters` and
`--ephemeral-parameter` not being available for use in the `coder
create` workspace creation command (they are only available in `coder
start` command). Back when they were [added
originally](https://github.com/coder/coder/pull/15030) it seems to have
been an oversight that they were left out.
The problem this solves:
```
coder create --parameter my_ephemeral_parameter=foo
error: prepare build: ephemeral parameter "my_ephemeral_parameter" can be used only with --prompt-ephemeral-parameters or --ephemeral-parameter flag
```
```
coder create my-test-ws -t general --ephemeral-parameter my_ephemeral_parameter=foo
parsing flags ([create my-test-ws -t general --ephemeral-parameter my_ephemeral_parameter=foo]) for "coder create": unknown flag: --ephemeral-parameter
```
Tested on a template with the following:
```
data "coder_parameter" "my_ephemeral_parameter" {
name = "my_ephemeral_parameter"
type = "bool"
description = "true or false?"
mutable = true
default = false
ephemeral = true
}
resource "coder_env" "debug_ephemeral" {
agent_id = coder_agent.main.id
name = "EPHEMERAL_TEST"
value = data.coder_parameter.my_ephemeral_parameter.value
}
```
By running:
```
➜ coder git:(rowan/coder-create-5495) ✗ go run cmd/coder/main.go create --ephemeral-parameter my_ephemeral_parameter=true
> Specify a name for your workspace: ws4
Select a template below to preview the provisioned infrastructure:
? kasmvnc-ubuntu-coder-dev used by 1 active developer
Select a preset below:
? Small (2 CPU / 4 GB)
....
...
The ws4 workspace has been created at Jun 3 12:36:38!
➜ coder git:(rowan/coder-create-5495) ✗ coder ssh ws4
workspace-ws4-5d6994756f-qlwnl% echo $EPHEMERAL_TEST
true
workspace-ws4-5d6994756f-qlwnl% exit
```
The bundled `/icon/rstudio.svg` rendered the R language logo (gray oval,
blue R), not the RStudio IDE logo, so templates using the `rstudio`
`coder_app` and the bundled URL got the wrong artwork
([#26211](https://github.com/coder/coder/issues/26211), PRODUCT-383).
This PR:
- Renames the existing `rstudio.svg` (R language logo) to `rproject.svg`
so the artwork stays available for templates that want it.
- Adds a new `rstudio.svg` containing the actual RStudio R-ball logo,
extracted from the [Wikimedia
source](https://upload.wikimedia.org/wikipedia/commons/d/d0/RStudio_logo_flat.svg)
and normalized to `viewBox="0 0 256 256"` to match the rest of the icon
set.
- Adds `rproject.svg` to `site/src/theme/icons.json` so it appears in
the icon picker and gallery alongside `rstudio.svg`.
- Switches the `coder_app "rstudio"` example in
`docs/admin/templates/extending-templates/web-ides.md` to reference
`/icon/rstudio.svg` (and corrects `display_name` to `"RStudio"`),
matching every other example on that page.
| Path | Before | After |
| --- | --- | --- |
| `/icon/rstudio.svg` | R language logo | RStudio R-ball |
| `/icon/rproject.svg` | (did not exist) | R language logo |
<table>
<tr>
<th>Old <code>rstudio.svg</code> → new
<code>rproject.svg</code></th>
<th>New <code>rstudio.svg</code></th>
</tr>
<tr>
<td align="center"><img
src="https://raw.githubusercontent.com/coder/coder/vigilante/product-383-bundled-iconrstudiosvg-appears-to-show-r-language-logo/site/static/icon/rproject.svg"
width="128" height="128"></td>
<td align="center"><img
src="https://raw.githubusercontent.com/coder/coder/vigilante/product-383-bundled-iconrstudiosvg-appears-to-show-r-language-logo/site/static/icon/rstudio.svg"
width="128" height="128"></td>
</tr>
</table>
**Breaking-change note.** Templates that referenced `/icon/rstudio.svg`
expecting the R language oval will now render the RStudio R-ball.
Templates that want the R language logo should switch to
`/icon/rproject.svg`. The Linear issue acknowledges this tradeoff.
**Client cache caveat.** `site/site.go` serves everything under `/icon/`
with `Cache-Control: public, max-age=31536000, immutable`, so any
browser that already loaded the old artwork at `/icon/rstudio.svg` can
keep displaying it for up to a year before revalidating. A hard refresh
(Ctrl/Cmd+Shift+R) clears it immediately. Cache-busting (hashed icon
URLs) is out of scope for this fix and tracked as a possible follow-up
against PRODUCT-383.
<details>
<summary>Implementation notes</summary>
- Verified geometric fidelity by rendering the new SVG and a
high-resolution crop of the Wikimedia source at 256x256 and computing
the RMS pixel difference: 1.268/255 (~0.5%, essentially antialiasing
noise).
- Picked `viewBox="0 0 256 256"` because 139 of 142 SVGs in
`site/static/icon/` already use that viewBox.
- Searched the repo for `rstudio.svg` references: the only direct one is
`site/src/theme/icons.json`. The docs file references the `rstudio`
`coder_app` slug, not the icon path, so the rename does not break any
callsite.
- R-ball geometry: source circle at (318.7, 312.9) radius 309.8 in the
original `viewBox 0 0 1784.1 625.9`. Translating by (-8.9, -3.1) and
scaling by 256/619.6 maps its bounding box onto `0 0 256 256`. Path
coordinates are pre-computed so the file ships with no transform layer.
- Pre-commit hooks passed locally, including `lint/site-icons`.
</details>
Fixes#26211
Fixes PRODUCT-383
---
_Generated by Coder Agents on behalf of @nickvigilante._
The `multi-select` form type description in the dynamic parameters docs
incorrectly stated it renders checkboxes. The actual UI is a searchable
dropdown combobox (`MultiSelectCombobox`) with selected items shown as
removable chips.
> This PR was authored by Coder Agents on behalf of @uzair-coder07.
#11918 took away advanced settings during template creation however it
did not clean up the documentation of a reference to customising the
template permissions during template creation -
https://coder.com/docs/admin/templates/template-permissions
> By default the Everyone group is assigned to each template meaning any
Coder user can use the template to create a workspace. To prevent this,
disable the Allow everyone to use the template setting when creating a
template.
This setting is no longer present in Coder, so removing it from the
docs.
## Problem
The Sysbox docker-in-workspaces docs examples use `sudo dockerd &` in
`startup_script` to start Docker. This causes workspaces to report as
unhealthy because `dockerd` keeps references to stdout/stderr after the
script exits.
## Fix
Replace `sudo dockerd &` with `sudo service docker start`, which
properly daemonizes Docker through the service manager and returns
cleanly. This matches the pattern used in our [dogfood
template](https://github.com/coder/coder/blob/main/dogfood/coder/main.tf#L614).
## Validation
Created a test template and workspace on dogfood — agent reported `✔
healthy` and `docker info` confirmed the daemon running inside the
workspace.
Fixes#21166
> 🤖 This PR was created with the help of Coder Agents, and has been
reviewed by my human. 🧑💻
## Description
Implements the server-side merge logic for the `merge_strategy`
attribute added to `coder_env` in [terraform-provider-coder
v2.15.0](https://github.com/coder/terraform-provider-coder/pull/489).
This allows template authors to control how duplicate environment
variable names are combined across multiple `coder_env` resources.
Relates to https://github.com/coder/coder/issues/21885
## Supported strategies
| Strategy | Behavior |
|----------|----------|
| `replace` (default) | Last value wins — backward compatible |
| `append` | Joins values with `:` separator (e.g. PATH additions) |
| `prepend` | Prepends value with `:` separator |
| `error` | Fails the build if the variable is already defined |
## Example
```hcl
resource "coder_env" "path_tools" {
agent_id = coder_agent.dev.id
name = "PATH"
value = "/home/coder/tools/bin"
merge_strategy = "append"
}
```
## Changes
- **Proto**: Added `merge_strategy` field to `Env` message in
`provisioner.proto`
- **State reader**: Updated `agentEnvAttributes` struct and proto
construction in `resources.go`
- **Merge logic**: Added `mergeExtraEnvs()` function in
`provisionerdserver.go` with strategy-aware merging for both agent envs
and devcontainer subagent envs
- **Tests**: 15 unit tests covering all strategies, edge cases (empty
values, mixed strategies, multiple appends)
- **Dependency**: Bumped `terraform-provider-coder` v2.14.0 → v2.15.0
- **Fixtures**: Updated `duplicate-env-keys` test fixtures and golden
files
## Ordering
When multiple resources `append` or `prepend` to the same key, they are
processed in alphabetical order by Terraform resource address (per the
determinism fix in #22706).
relates to #21335
Enables the agent socket by default and updates docs to strike references to having to enable it.
The PRs in this stack change the MCP server that Tasks use to update their status to rely on the agent socket, rather than directly dialing Coderd with the agent token.
Default disable was a reasonable default when it was only used for the experimental script ordering features, but now that we want to use it for Tasks, it should be default on.
### Summary
Workspace created via mode=auto links now require explicit user
confirmation before provisioning. A warning dialog shows all prefilled
param.* values from the URL and blocks creation until the user clicks
`Confirm and Create`. Clicking `Cancel` falls back to the standard form
view.
<img width="820" height="475" alt="auto-create-consent-dialog"
src="https://github.com/user-attachments/assets/8339e3bd-434f-4a04-9385-436bf95f49d7"
/>
### Breaking behavior change
Links using `mode=auto` (e.g., "Open in Coder" buttons) will no longer
silently create workspaces. Users will now see a consent dialog and must
explicitly confirm before the workspace is provisioned. Any existing
integrations or automation relying on `mode=auto` for seamless workspace
creation will now require manual user interaction.
---------
Co-authored-by: Jake Howell <jacob@coder.com>
## Description
Fixes an incorrect path in the air-gapped/offline installation
documentation for publishing Coder modules to Artifactory.
The [coder/registry](https://github.com/coder/registry) repo has the
following structure:
```
registry/ # repo root
└── registry/ # subdirectory
└── coder/
└── modules/
```
The documentation previously instructed users to run:
```shell
cd registry/coder/modules
```
But the correct path is:
```shell
cd registry/registry/coder/modules
```
This was causing confusion for users trying to set up Coder modules in
air-gapped environments with Artifactory or similar repository managers.
Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com>
Archiving modules attempts to save as many modules as it can before it hits the limit. Enabling the template as much as it can, rather than a hard failure.
This undeprecates the `allow-workspace-renames` flag. IIUC, the 'danger'
with using this flag is that the workspace name might have been used in
the definition of some other terraform resources within template code,
so a rename could cause problems such as with persistent disks.
for https://github.com/coder/coder/issues/21628
---------
Signed-off-by: Callum Styan <callumstyan@gmail.com>
This Pull request adds documentation and guidance for the Coder script
ordering feature. We:
* explain the use case, benefits, and requirements.
* provide example configuration snippets
* discuss best practices and troubleshooting
---------
Co-authored-by: Cian Johnston <cian@coder.com>
Co-authored-by: DevCats <christofer@coder.com>
Dev container admin docs were scattered across two locations: the Docker-based
integration under extending-templates/ and Envbuilder under managing-templates/.
There was no landing page explaining that two approaches exist or helping admins
choose between them.
This moves everything under admin/integrations/devcontainers/ with a decision
guide at the top. Dev containers are an integration with the dev container
specification, so integrations/ is a natural fit alongside JFrog, Vault, etc.
Stub pages remain at the original locations for discoverability.
New structure:
admin/integrations/devcontainers/
├── index.md # Landing page + decision guide
├── integration.md # Docker-based dev containers
└── envbuilder/
├── index.md
├── add-envbuilder.md
├── envbuilder-security-caching.md
└── envbuilder-releases-known-issues.md
Refs #21080
docs: rewrite dev containers documentation for GA
Corrects inaccuracies in SSH examples (deprecated `--container` flag),
port forwarding (native sub-agent forwarding is primary), and
prerequisites (dev containers are on by default). Fixes template
descriptions: docker-devcontainer uses native Dev Containers while
AWS/Kubernetes templates use Envbuilder.
Renames admin docs folder from `devcontainers/` to `envbuilder/` to
reflect actual content. Adds customization guide documenting agent
naming, display apps, custom apps, and variable interpolation. Documents
multi-repo workspace support and adds note about Terraform module
limitations with sub-agents. Fixes module registry URLs.
Refs #18907
Updates the dev containers documentation to accurately reflect that the
feature is generally available and document all configuration options.
Closes https://github.com/coder/internal/issues/1138
---
🤖 PR was written by Claude Sonnet 4.5 Thinking using [Coder
Mux](https://github.com/coder/cmux) and reviewed by a human 👩
## Description
Follow-up from: https://github.com/coder/coder/pull/20305 to include a
note about `coder_workspace_tags` being cumulative and a new step to
validate the status of the prebuild provisioners.
Fix steps formatting.
## Description
Update the Prebuilds troubleshooting page to include a new section,
“Preventing prebuild queue contention (recommended)”, outlining a
best-practice configuration to prevent prebuild jobs from overwhelming
the provisioner queue.
This setup introduces a dedicated prebuild provisioner pool and has been
successfully tested internally in dogfood:
https://github.com/coder/dogfood/pull/201
Closes: https://github.com/coder/coder/issues/20241
This PR adds troubleshooting steps to guide Coder operators when they
suspect that prebuilds might have overwhelmed their deployments.
Closes https://github.com/coder/coder/issues/19490
---------
Co-authored-by: Susana Ferreira <susana@coder.com>
Dynamic parameters are now GA as of v2.25.0, so this PR updates the
troubleshooting section to remove outdated beta references and clarify
current support.
**Changes:**
- Updated "Template variables not showing up" section to remove beta
references
- Clarified that template variables are fully supported in GA version
- Simplified troubleshooting guidance
Fixes the outdated documentation mentioned in the Slack thread.
---------
Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com>
Co-authored-by: bpmct <22407953+bpmct@users.noreply.github.com>
Co-authored-by: david-fraley <67079030+david-fraley@users.noreply.github.com>
## Description
This PR introduces one counter and two histograms related to workspace
creation and claiming. The goal is to provide clearer observability into
how workspaces are created (regular vs prebuild) and the time cost of
those operations.
### `coderd_workspace_creation_total`
* Metric type: Counter
* Name: `coderd_workspace_creation_total`
* Labels: `organization_name`, `template_name`, `preset_name`
This counter tracks whether a regular workspace (not created from a
prebuild pool) was created using a preset or not.
Currently, we already expose `coderd_prebuilt_workspaces_claimed_total`
for claimed prebuilt workspaces, but we lack a comparable metric for
regular workspace creations. This metric fills that gap, making it
possible to compare regular creations against claims.
Implementation notes:
* Exposed as a `coderd_` metric, consistent with other workspace-related
metrics (e.g. `coderd_api_workspace_latest_build`:
https://github.com/coder/coder/blob/main/coderd/prometheusmetrics/prometheusmetrics.go#L149).
* Every `defaultRefreshRate` (1 minute ), DB query
`GetRegularWorkspaceCreateMetrics` is executed to fetch all regular
workspaces (not created from a prebuild pool).
* The counter is updated with the total from all time (not just since
metric introduction). This differs from the histograms below, which only
accumulate from their introduction forward.
### `coderd_workspace_creation_duration_seconds` &
`coderd_prebuilt_workspace_claim_duration_seconds`
* Metric types: Histogram
* Names:
* `coderd_workspace_creation_duration_seconds`
* Labels: `organization_name`, `template_name`, `preset_name`, `type`
(`regular`, `prebuild`)
* `coderd_prebuilt_workspace_claim_duration_seconds`
* Labels: `organization_name`, `template_name`, `preset_name`
We already have `coderd_provisionerd_workspace_build_timings_seconds`,
which tracks build run times for all workspace builds handled by the
provisioner daemon.
However, in the context of this issue, we are only interested in
creation and claim build times, not all transitions; additionally, this
metric does not include `preset_name`, and adding it there would
significantly increase cardinality. Therefore, separate more focused
metrics are introduced here:
* `coderd_workspace_creation_duration_seconds`: Build time to create a
workspace (either a regular workspace or the build into a prebuild pool,
for prebuild initial provisioning build).
* `coderd_prebuilt_workspace_claim_duration_seconds`: Time to claim a
prebuilt workspace from the pool.
The reason for two separate histograms is that:
* Creation (regular or prebuild): provisioning builds with similar time
magnitude, generally expected to take longer than a claim operation.
* Claim: expected to be a much faster provisioning build.
#### Native histogram usage
Provisioning times vary widely between projects. Using static buckets
risks unbalanced or poorly informative histograms.
To address this, these metrics use [Prometheus native
histograms](https://prometheus.io/docs/specs/native_histograms/):
* First introduced in Prometheus v2.40.0
* Recommended stable usage from v2.45+
* Requires Go client `prometheus/client_golang` v1.15.0+
* Experimental and must be explicitly enabled on the server
(`--enable-feature=native-histograms`)
For compatibility, we also retain a classic bucket definition (aligned
with the existing provisioner metric:
https://github.com/coder/coder/blob/main/provisionerd/provisionerd.go#L182-L189).
* If native histograms are enabled, Prometheus ingests the
high-resolution histogram.
* If not, it falls back to the predefined buckets.
Implementation notes:
* Unlike the counter, these histograms are updated in real-time at
workspace build job completion.
* They reflect data only from the point of introduction forward (no
historical backfill).
## Relates to
Closes: https://github.com/coder/coder/issues/19528
Native histograms tested in observability stack:
https://github.com/coder/observability/pull/50
closes https://github.com/coder/coder/issues/18274
This pull request makes system users visible in various group related
queries so that they can be added to and removed from groups. This
allows system user quotas to be configured. System users are still
ignored in certain queries, such as when license seat consumption is
determined.
This pull request further ensures the existence of a
"coder_prebuilt_workspaces" group in any organization that needs
prebuilt workspaces
---------
Co-authored-by: Susana Ferreira <susana@coder.com>
closes#18806
- [x] scheduling limitation
- [x] dev containers limitation
- [x] edit intro
[preview](https://coder.com/docs/@18806-prebuilds-known-limits/admin/templates/extending-templates/prebuilt-workspaces)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Clarified the introduction and administrator responsibilities for
prebuilt workspaces.
* Integrated compatibility information about DevContainers and workspace
scheduling more contextually.
* Added explicit notes on limitations with dev containers integration
and workspace autostart/autostop features.
* Improved configuration examples and clarified scheduling instructions.
* Enhanced explanations of scheduling behavior and lifecycle steps for
better understanding.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: Sas Swart <sas.swart.cdk@gmail.com>
Co-authored-by: Susana Ferreira <susana@coder.com>
Closes https://github.com/coder/coder/issues/18356.
This change finds and selects a matching preset if one was not chosen
during workspace creation. This solidifies the relationship between
presets and parameters.
When a workspace is created without in explicitly chosen preset, it will
now still be eligible to claim a prebuilt workspace if one is available.