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

166 lines
5.8 KiB
Markdown

# Install Coder via Docker
You can install and run Coder using the official Docker images published on
[GitHub Container Registry](https://github.com/coder/coder/pkgs/container/coder).
## Requirements
- Docker. See the
[official installation documentation](https://docs.docker.com/install/).
- A Linux host.
- 2 CPU cores and 4 GB memory free on your machine.
> [!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](./cli.md) instead.
<div class="tabs">
## Install Coder via `docker compose`
Coder publishes a
[docker compose example](../../compose.yaml)
which includes a PostgreSQL container and volume.
1. Make sure you have [Docker Compose](https://docs.docker.com/compose/install/)
installed.
1. Download the
[`docker-compose.yaml`](../../compose.yaml)
file.
1. 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:
```sh
getent group docker | cut -d: -f3
```
1. Start Coder with `docker compose up`
1. Visit the web UI via the configured url.
1. 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](../admin/setup/index.md).
## 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.
```sh
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
```
### External database (recommended)
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.
```sh
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
```
</div>
## 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](https://github.com/coder/coder/pkgs/container/coder-preview)
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](#install-coder-via-docker-run) with `ghcr.io/coder/coder-preview:latest`.
## Troubleshooting
### Cannot connect to the Docker daemon
If you see an error like:
```txt
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](../get-started/index.md#cannot-connect-to-the-docker-daemon)
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:
```sh
# 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](../admin/templates/troubleshooting.md) 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](https://docs.docker.com/engine/install/linux-postinstall/#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](../admin/setup/index.md#tunnel). For production deployments, we
recommend setting an [access URL](../admin/setup/index.md#access-url)
## Next steps
- [Create your first template](../tutorials/template-from-scratch.md)
- [Control plane configuration](../admin/setup/index.md#configure-control-plane-access)