|
2 | 2 |
|
3 | 3 | <p align=center> |
4 | 4 | Docker images for <a href="https://coder.com">Coder</a> workspaces. Built on Coder’s enterprise base |
5 | | - and extended with PHP, Node tooling, and a few AI CLIs we use day to day. |
| 5 | + and extended with language runtimes, developer tooling, and the AI CLIs we use day to day. |
6 | 6 | </p> |
7 | 7 |
|
8 | 8 | <p align=center> |
|
16 | 16 |
|
17 | 17 | ## Motivation |
18 | 18 |
|
19 | | -`dockette/coder` is meant to drop into a Coder Terraform template so new workspaces already have a sane dev stack. |
| 19 | +`dockette/coder` is meant to drop into a [Coder](https://coder.com) Terraform template so new |
| 20 | +workspaces come up with a sane dev stack already in place — no per-workspace provisioning scripts. |
| 21 | + |
| 22 | +Every image builds on `codercom/enterprise-base:ubuntu` (Ubuntu, `coder` user, the usual Coder |
| 23 | +expectations) and adds a shared baseline of developer and AI tooling. On top of that baseline, each |
| 24 | +tag targets a specific stack: an all-in-one image (`fx`) plus focused, lighter images for PHP, |
| 25 | +Node.js, Go, and Python. |
| 26 | + |
| 27 | +## Images |
| 28 | + |
| 29 | +All images are published to Docker Hub as [`dockette/coder`](https://hub.docker.com/r/dockette/coder), |
| 30 | +one tag per template: |
| 31 | + |
| 32 | +| Tag | Focus | Node.js | pnpm | Deno / Bun | PHP 8.5 + Composer | Python 3 | Go | Rootless Docker | |
| 33 | +| ---------------------- | ------------------ | :-----: | :--: | :--------: | :----------------: | :------: | :--: | :-------------: | |
| 34 | +| **`fx`** | Everything | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
| 35 | +| **`php`** | PHP | ✅ | | | ✅ | | | | |
| 36 | +| **`nodejs`** | JavaScript runtime | ✅ | | ✅ | | | | | |
| 37 | +| **`golang`** | Go | ✅ | | | | | ✅ | | |
| 38 | +| **`python`** | Python | ✅ | | | | ✅ | | | |
| 39 | + |
| 40 | +> Node.js (with `npm`) ships in every image because the shared AI CLIs are installed from npm. |
| 41 | +> The `nodejs` tag additionally provides Deno and Bun; only the `fx` tag adds `pnpm`. |
| 42 | +
|
| 43 | +### Shared baseline |
| 44 | + |
| 45 | +Every image includes: |
| 46 | + |
| 47 | +- **Base tooling:** `git`, `jq`, `ripgrep`. |
| 48 | +- **Node.js 24** with `npm` (via NodeSource). |
| 49 | +- **VCS CLIs:** GitHub CLI (`gh`) and GitLab CLI (`glab`). |
| 50 | +- **AI CLIs:** `claude` (Claude Code), `opencode`, `codex` (`@openai/codex`), and `copilot` (`@github/copilot`). |
| 51 | +- **Browser automation:** `agent-browser` plus the Chrome shared libraries it needs (Chromium is |
| 52 | + installed on first `agent-browser install`). |
| 53 | + |
| 54 | +The AI CLIs are installed into a location that survives Coder’s persistent `/home/coder` volume, |
| 55 | +so they remain available after the home directory is mounted over at runtime. |
| 56 | + |
| 57 | +### `dockette/coder:fx` |
| 58 | + |
| 59 | +The all-in-one image — the shared baseline plus every language runtime and Docker-in-Docker. |
| 60 | +Choose this when a workspace is polyglot or you don’t want to commit to one stack. |
| 61 | + |
| 62 | +- **Node.js 24** (`npm`, `pnpm`), **Deno**, and **Bun** (Deno/Bun under `/usr/local`, with PATH set for login shells). |
| 63 | +- **PHP 8.5** (Ondřej PPA): CLI plus common extensions (`curl`, `intl`, `mbstring`, `mysql`, `pgsql`, |
| 64 | + `redis`, `xml`, `zip`, `imagick`, `bcmath`, `apcu`, `gmp`, `ldap`, `amqp`, `memcached`, `soap`, |
| 65 | + `xsl`, `yaml`, …) and both coverage drivers (`xdebug`, `pcov`). |
| 66 | +- **Composer**. |
| 67 | +- **Python 3** with `pip` and `venv`. |
| 68 | +- **Go 1.26.5** (installed to `/usr/local/go`; `GOROOT`/`GOPATH`/PATH set for login shells). |
| 69 | +- **Rootless Docker** (docker-in-docker) — see [Rootless Docker](#rootless-docker) below. |
| 70 | + |
| 71 | +### `dockette/coder:php` |
| 72 | + |
| 73 | +PHP-focused image for backend and web projects. |
| 74 | + |
| 75 | +- **PHP 8.5** (Ondřej PPA): CLI plus the same extension set as `fx`, including `xdebug` and `pcov`. |
| 76 | +- **Composer**. |
| 77 | +- **Node.js 24** with `npm` (for asset builds and the shared AI CLIs). |
| 78 | + |
| 79 | +### `dockette/coder:nodejs` |
| 80 | + |
| 81 | +JavaScript/TypeScript image with multiple runtimes. |
| 82 | + |
| 83 | +- **Node.js 24** with `npm`. |
| 84 | +- **Deno** and **Bun** (installed under `/usr/local`, with PATH set for login shells). |
| 85 | + |
| 86 | +### `dockette/coder:golang` |
| 87 | + |
| 88 | +Go-focused image. |
| 89 | + |
| 90 | +- **Go 1.26.5** (installed to `/usr/local/go`; `GOROOT`/`GOPATH`/PATH set for login shells). |
| 91 | +- **Node.js 24** with `npm` (for the shared AI CLIs). |
| 92 | + |
| 93 | +### `dockette/coder:python` |
| 94 | + |
| 95 | +Python-focused image. |
| 96 | + |
| 97 | +- **Python 3** with `pip` and `venv`. |
| 98 | +- **Node.js 24** with `npm` (for the shared AI CLIs). |
20 | 99 |
|
21 | 100 | ## Usage |
22 | 101 |
|
23 | | -Point your workspace image at this tag (or build from `fx/Dockerfile` if you fork): |
| 102 | +Point your Coder workspace image at the tag that fits your stack (or build from the matching |
| 103 | +`<template>/Dockerfile` if you fork): |
24 | 104 |
|
25 | 105 | ```diff |
26 | 106 | resource "docker_container" "workspace" { |
27 | 107 | count = data.coder_workspace.me.start_count |
28 | | - -image = "codercom/enterprise-base:ubuntu" |
29 | | - +image = "dockette/coder:fx" |
| 108 | +- image = "codercom/enterprise-base:ubuntu" |
| 109 | ++ image = "dockette/coder:fx" |
30 | 110 | ... |
31 | 111 | } |
32 | 112 | ``` |
33 | 113 |
|
34 | | -## Images |
35 | | - |
36 | | -### `dockette/coder:fx` |
37 | | - |
38 | | -So you’re replacing the plain enterprise base with the same foundation plus our layers: Node/npm, PHP 8.5, Composer, Deno, Bun, browser automation, and the CLIs listed below. |
| 114 | +Swap `fx` for `php`, `nodejs`, `golang`, or `python` to use a lighter, stack-specific image. |
39 | 115 |
|
40 | | -**Base:** `codercom/enterprise-base:ubuntu` (Ubuntu, `coder` user, usual Coder expectations). |
| 116 | +## Rootless Docker |
41 | 117 |
|
42 | | -- **Node.js** (includes **npm**) via Nodesource (**Node 24** in this image), plus **pnpm**. |
43 | | -- **Shell:** `mc`, `nano`, `tmux`. |
44 | | -- **PHP 8.5** (Ondrej PPA): CLI + common extensions (curl, intl, mbstring, mysql, pgsql, redis, xml, zip, imagick, etc.). |
45 | | -- **Composer**, **GitHub CLI (`gh`)**, **GitLab CLI (`glab`)**. |
46 | | -- **Deno** and **Bun** under `/usr/local`. `/etc/profile` sets `DENO_INSTALL`, `BUN_INSTALL`, and PATH for login shells. |
47 | | -- **Claude** and **OpenCode** installers (best-effort copy to `/usr/local/bin` when present). |
48 | | -- **npm globals:** `@openai/codex`, `@github/copilot`. |
49 | | -- **Chrome libraries** plus **agent-browser** (installs its Chromium). |
50 | | -- **Rootless Docker** (docker-in-docker): Docker CE from the base plus rootless extras (`uidmap`, `fuse-overlayfs`, `slirp4netns`). Run `dockerd-rootless-start` to bring up the daemon as the `coder` user. |
51 | | - |
52 | | -### Rootless Docker |
53 | | - |
54 | | -The image can run Docker-in-Docker without privileged root. Start the daemon inside the workspace: |
| 118 | +The `fx` image can run Docker-in-Docker without privileged root. Start the daemon inside the workspace: |
55 | 119 |
|
56 | 120 | ```bash |
57 | 121 | dockerd-rootless-start |
58 | 122 | docker run --rm hello-world |
59 | 123 | ``` |
60 | 124 |
|
61 | | -`DOCKER_HOST` and `XDG_RUNTIME_DIR` are preset for login shells, so the CLI talks to the rootless daemon automatically. The host must permit nested user namespaces — in a Coder Terraform template, run the workspace container with `privileged = true` (or the equivalent `--userns` setup), and call `dockerd-rootless-start` from `startup_script` to have Docker ready on boot. |
| 125 | +`DOCKER_HOST` and `XDG_RUNTIME_DIR` are preset for login shells, so the CLI talks to the rootless |
| 126 | +daemon automatically. The host must permit nested user namespaces — in a Coder Terraform template, |
| 127 | +run the workspace container with `privileged = true` (or the equivalent `--userns` setup), and call |
| 128 | +`dockerd-rootless-start` from `startup_script` so Docker is ready on boot. |
62 | 129 |
|
63 | 130 | ## Development |
64 | 131 |
|
| 132 | +Images are built and tested per template with the provided `Makefile`. `DOCKER_VARIANT` selects the |
| 133 | +template (default `fx`): |
| 134 | + |
65 | 135 | ```bash |
66 | | -make build |
67 | | -make test |
68 | | -make run |
| 136 | +# Build and test a single template |
| 137 | +make build DOCKER_VARIANT=nodejs |
| 138 | +make test DOCKER_VARIANT=nodejs |
| 139 | +make run DOCKER_VARIANT=nodejs |
| 140 | + |
| 141 | +# Build and test every template |
| 142 | +make build-all |
| 143 | +make test-all |
69 | 144 | ``` |
70 | 145 |
|
| 146 | +Each template is smoke-tested in CI (build, then version checks for its runtimes and the shared |
| 147 | +CLIs) and, on `master`, built and pushed to Docker Hub across all five tags. |
| 148 | + |
71 | 149 | ## Maintenance |
72 | 150 |
|
73 | 151 | See [how to contribute](https://github.com/dockette/.github/blob/master/CONTRIBUTING.md) to this package. Consider to [support](https://github.com/sponsors/f3l1x) **f3l1x**. Thank you for using this package. |
0 commit comments