Files
coder/docs/install/docker.md
T
Nick Vigilante c84aa564ba 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.*
2026-07-15 14:07:09 -04:00

5.8 KiB

Install Coder via Docker

You can install and run Coder using the official Docker images published on GitHub Container Registry.

Requirements

Important

This guide is for Linux hosts only. The getent and --group-add Docker socket patterns used below are Linux-specific and do not translate cleanly to macOS Docker runtimes. For macOS, install Coder using the standalone binary instead.

Install Coder via docker compose

Coder publishes a docker compose example which includes a PostgreSQL container and volume.

  1. Make sure you have Docker Compose installed.

  2. Download the docker-compose.yaml file.

  3. Update group_add: in docker-compose.yaml with the gid of docker group. You can get the docker group gid by running the below command:

    getent group docker | cut -d: -f3
    
  4. Start Coder with docker compose up

  5. Visit the web UI via the configured url.

  6. Follow the on-screen instructions log in and create your first template and workspace

Coder configuration is defined via environment variables. Learn more about Coder's configuration options.

Install Coder via docker run

Built-in database (quick)

For proof-of-concept deployments, you can run a complete Coder instance with the following command.

export CODER_DATA=$HOME/.config/coderv2-docker
export DOCKER_GROUP=$(getent group docker | cut -d: -f3)
mkdir -p $CODER_DATA
docker run --rm -it \
  -v $CODER_DATA:/home/coder/.config \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --group-add $DOCKER_GROUP \
  ghcr.io/coder/coder:latest

For production deployments, we recommend using an external PostgreSQL database (version 13 or higher). Set CODER_ACCESS_URL to the external URL that users and workspaces will use to connect to Coder.

export DOCKER_GROUP=$(getent group docker | cut -d: -f3)
docker run --rm -it \
  -e CODER_ACCESS_URL="https://coder.example.com" \
  -e CODER_PG_CONNECTION_URL="postgresql://username:password@database/coder" \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --group-add $DOCKER_GROUP \
  ghcr.io/coder/coder:latest

Install the preview release

Tip

We do not recommend using preview releases in production environments.

You can install and test a preview release of Coder by using the coder-preview:latest image tag. This image is automatically updated with the latest changes from the main branch.

Replace ghcr.io/coder/coder:latest in the docker run command in the steps above with ghcr.io/coder/coder-preview:latest.

Troubleshooting

Cannot connect to the Docker daemon

If you see an error like:

Error: Error pinging Docker server: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Docker is not installed or not running on the host. Install Docker and start the daemon before creating a workspace from a Docker-based template. Refer to the Troubleshooting section of the get started guide for platform-specific steps.

If Docker is installed and running but Coder still cannot connect, the daemon may expose its socket at a path other than /var/run/docker.sock. This can happen on any operating system 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. Point Coder at the right socket with DOCKER_HOST.

Find the socket path first. For example, run colima status for Colima, or docker context inspect to read the endpoint of the active Docker context. Default socket paths vary by tool, so consult your tool's documentation and treat the following as examples only:

# rootless Docker (Linux)
export DOCKER_HOST="unix://${XDG_RUNTIME_DIR}/docker.sock"

# Colima (macOS)
export DOCKER_HOST="unix://${HOME}/.colima/default/docker.sock"

To persist the setting, add the export line to your shell's startup file, such as ~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish. Then restart the Coder server.

Docker-based workspace is stuck in "Connecting..."

Ensure you have an externally-reachable CODER_ACCESS_URL set. See troubleshooting templates for more steps.

Permission denied while trying to connect to the Docker daemon socket

See Docker's official documentation to Manage Docker as a non-root user

I cannot add Docker templates

Coder runs as a non-root user, we use --group-add to ensure Coder has permissions to manage Docker via docker.sock. If the host systems /var/run/docker.sock is not group writable or does not belong to the docker group, the above may not work as-is.

I cannot add cloud-based templates

In order to use cloud-based templates (e.g. Kubernetes, AWS), you must have an external URL that users and workspaces will use to connect to Coder. For proof-of-concept deployments, you can use Coder's tunnel. For production deployments, we recommend setting an access URL

Next steps