From 86b8e5164683ceb2e919e67428e16c7c01428557 Mon Sep 17 00:00:00 2001 From: Nic O'Connor Date: Sat, 19 Sep 2026 13:39:59 -0400 Subject: [PATCH] Remove the docker module: dotfiles no longer installs Docker Installing Docker Engine is a host/image decision, not a per-user environment one. In Coder workspaces (unprivileged pods, no systemd) the module ran get.docker.com on every start for a daemon that can never run there. Where Docker is wanted, install it on the host or bake it into the image. Also drops the zshrc newgrp-docker hook that existed only for this module's group change, and the docs/skills references to docker/. docker-rootless-cgroup/ (configures Kasm's existing rootless daemon) and bin/'s kind gate (detects a daemon) stay. Co-Authored-By: Claude Opus 5 (1M context) --- .agents/skills/add-bootstrap-module/SKILL.md | 8 +- .agents/skills/bump-pinned-version/SKILL.md | 2 +- .agents/skills/verify-module/SKILL.md | 4 +- README.md | 10 +- bootstrap.sh | 4 +- docker/install.sh | 114 ------------------- zsh/zshrc | 13 --- 7 files changed, 10 insertions(+), 145 deletions(-) delete mode 100755 docker/install.sh diff --git a/.agents/skills/add-bootstrap-module/SKILL.md b/.agents/skills/add-bootstrap-module/SKILL.md index c11ab75..ad30547 100644 --- a/.agents/skills/add-bootstrap-module/SKILL.md +++ b/.agents/skills/add-bootstrap-module/SKILL.md @@ -44,9 +44,9 @@ Every module's `install.sh` satisfies all of these. Copy the shape from ## Wiring it up **`bootstrap.sh`** — add the call. Order is load-bearing and each existing -out-of-order entry carries a comment explaining why (`docker/` before `bin/` -so kind's gate sees the daemon; `docker-rootless-cgroup/` last because it -needs the rootless daemon already up). If your module has an ordering +out-of-order entry carries a comment explaining why (`secrets/` after `bin/` +because it needs `op`; `docker-rootless-cgroup/` last because it needs the +rootless daemon already up). If your module has an ordering constraint, add it *with* a comment; if it doesn't, append it near related modules. @@ -61,7 +61,7 @@ Never commit the value itself. ## Non-systemd hosts Kasm has no systemd. Anything that would `systemctl enable` must degrade -gracefully — see `docker/install.sh`, which detects the situation and no-ops +gracefully — see `docker-rootless-cgroup/install.sh`, which detects the situation and no-ops rather than failing the whole bootstrap run. ## Before you're done diff --git a/.agents/skills/bump-pinned-version/SKILL.md b/.agents/skills/bump-pinned-version/SKILL.md index 3f395b4..3ae5302 100644 --- a/.agents/skills/bump-pinned-version/SKILL.md +++ b/.agents/skills/bump-pinned-version/SKILL.md @@ -14,7 +14,7 @@ Everything in this repo is version-pinned on purpose. Nothing floats. | CLI tools | `bin/install.sh` | `ver=v1.2.3` inside each `install_()` | | Node.js | `node/install.sh` | `NODE_VERSION="v24.18.0"` | | MCP servers | `mcp-config/opencode.gateway.json` | `["npx", "-y", "pkg@0.0.10"]` | -| oh-my-zsh, Docker | `zsh/`, `docker/` | installed from upstream scripts — not pinned | +| oh-my-zsh | `zsh/` | installed from upstream script — not pinned | Grep before assuming: `grep -rnE 'ver=|_VERSION=|@[0-9]+\.[0-9]+' --include='*.sh' --include='*.json'` diff --git a/.agents/skills/verify-module/SKILL.md b/.agents/skills/verify-module/SKILL.md index 3bfba75..5e3afe4 100644 --- a/.agents/skills/verify-module/SKILL.md +++ b/.agents/skills/verify-module/SKILL.md @@ -63,8 +63,8 @@ faithful rehearsal. Kasm has no systemd and no rootful Docker. Anything that would `systemctl` must no-op rather than abort — you can't fully rehearse this in a container, so read -the code path and confirm the guard exists (`docker/install.sh` and -`docker-rootless-cgroup/install.sh` are the references). +the code path and confirm the guard exists (`docker-rootless-cgroup/install.sh` +is the reference). ## Full run diff --git a/README.md b/README.md index cb719c2..3811e57 100644 --- a/README.md +++ b/README.md @@ -32,14 +32,6 @@ Already have a clone? Just run it directly: - `git/` — sets git `user.name`/`user.email` and configures `credential.helper store` (plaintext `~/.git-credentials`, 0600) for HTTPS auth. -- `docker/` — installs full (rootful) Docker Engine from Docker's upstream - package repo (get.docker.com on Debian-family; the docker-ce repo wired up - directly on RHEL-family, since the convenience script rejects EL rebuilds - like Oracle Linux by name), enables the service (systemd hosts), and adds - the invoking user to the - `docker` group (takes effect at next login). No-ops where a rootless - Docker daemon is already running (e.g. Kasm) so it never fights that - setup. Uses sudo. - `bin/` — installs userland devops CLIs as self-contained, statically linked release binaries into `~/.local/bin`: jq, kubectl, kubelogin (the `kubectl oidc-login` plugin, for OIDC auth to Omni clusters), helm, k9s, @@ -50,6 +42,8 @@ Already have a clone? Just run it directly: coder CLI for Coder workspaces. kind is installed only when full (non-rootless) Docker is available — it doesn't work against rootless Docker, so it is skipped on Kasm. + Dotfiles does not install Docker itself; install it on the host (or bake + it into the image) where you want it. No sudo, nothing outside `$HOME`, so tools persist across Kasm redeploys with no reinstall. Idempotent: each tool records its version under `~/.local/bin/.versions` and is skipped when the pinned version diff --git a/bootstrap.sh b/bootstrap.sh index f5bdb50..1a43d57 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -66,7 +66,7 @@ fi # # WHY: these used to be bare calls, so under `set -eu` the FIRST failing module # aborted bootstrap and every later module silently never ran — one unsupported -# distro in docker/ was enough to leave a box with no CLIs, no npx and no +# distro in one module was enough to leave a box with no CLIs, no npx and no # ansible. The modules are independent, so a failure in one is not a reason to # skip the rest. (bin/install.sh does the same for individual tools; this is # that guard one level up.) @@ -79,8 +79,6 @@ run_module() { run_module zsh run_module git -# Runs before bin/ so the kind install gate can see the rootful daemon. -run_module docker run_module bin # Needs op and jq from bin/. Runs before everything that consumes a secret, and # its output is loaded into THIS process so later modules see the vault's diff --git a/docker/install.sh b/docker/install.sh deleted file mode 100755 index 461df0b..0000000 --- a/docker/install.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env sh -# docker/install.sh — install full (rootful) Docker Engine and let the -# invoking user talk to it without sudo. -# -# What it does: -# 1. Installs Docker Engine from Docker's upstream package repo. Skipped when -# `docker` is already installed. Debian-family hosts go through Docker's -# convenience script (get.docker.com); RHEL-family hosts wire up the -# docker-ce repo directly — see install_rhel() for why. -# 2. Enables and starts the service (systemd hosts only). -# 3. Adds the invoking user to the `docker` group so the daemon socket is -# usable without sudo. Takes effect at next login. -# -# Deliberately no-ops when a rootless Docker daemon is detected (e.g. Kasm -# ships its own rootless setup) — installing rootful Docker there would fight -# the existing runtime. See docker-rootless-cgroup/ for the Kasm-side config. -# -# Idempotent and safe to re-run. Uses sudo. -set -eu - -SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" -REPO_ROOT="$(dirname -- "$SCRIPT_DIR")" - -# shellcheck source=../lib/os-detect.sh -. "$REPO_ROOT/lib/os-detect.sh" - -say() { printf '%s\n' "$*" >&2; } - -DOCKER_PKGS="docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin" - -# install_rhel — install docker-ce from Docker's EL repo. -# -# WHY NOT get.docker.com: the convenience script allowlists distros by -# /etc/os-release ID and aborts on anything it does not recognize — -# "ERROR: Unsupported distribution 'ol'" on Oracle Linux, and the same for -# other EL rebuilds it has not enumerated. On a match it does nothing more -# than what this function does: add the repo, then install the packages. -# Wiring the repo up directly drops the allowlist, so every EL rebuild -# (Oracle, Rocky, Alma, CentOS, RHEL) installs from one code path. -# -# The repo URL is keyed on $releasever/$basearch, which dnf expands per host, -# so EL9 and EL10 both resolve without a version table here. -install_rhel() { - say "docker: adding Docker CE repo (EL \$releasever/\$basearch)..." - sudo tee /etc/yum.repos.d/docker-ce.repo >/dev/null <<'REPO' -[docker-ce-stable] -name=Docker CE Stable - $basearch -baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/stable -enabled=1 -gpgcheck=1 -gpgkey=https://download.docker.com/linux/centos/gpg -REPO - # --allowerasing: containerd.io conflicts with the distro's own runc/containerd - # on EL rebuilds that ship them (Oracle Linux does). Let dnf swap them out - # rather than dead-end on the conflict. - if command -v dnf >/dev/null 2>&1; then - # shellcheck disable=SC2086 - sudo dnf install -y --allowerasing $DOCKER_PKGS - else - # shellcheck disable=SC2086 - sudo yum install -y --allowerasing $DOCKER_PKGS - fi -} - -# install_debian — Docker's convenience script; it supports every Debian-family -# distro this repo targets and sets up the apt repo and keyring. -install_debian() { - say "docker: installing Docker Engine via get.docker.com..." - tmp="$(mktemp)" - if command -v curl >/dev/null 2>&1; then - curl -fsSL https://get.docker.com -o "$tmp" - elif command -v wget >/dev/null 2>&1; then - wget -qO "$tmp" https://get.docker.com - else - say "docker: need curl or wget"; rm -f "$tmp"; return 1 - fi - sudo sh "$tmp" - rm -f "$tmp" -} - -# --- skip on rootless-Docker hosts ------------------------------------------- -if command -v docker >/dev/null 2>&1 && - docker info -f '{{println .SecurityOptions}}' 2>/dev/null | grep -q 'name=rootless'; then - say "docker: rootless Docker daemon detected; leaving it alone." - exit 0 -fi - -# --- 1. install engine ------------------------------------------------------- -if command -v docker >/dev/null 2>&1; then - say "docker: engine already installed ($(docker --version 2>/dev/null || echo 'version unknown'))." -else - case "$(detect_pkg_family)" in - rhel) install_rhel ;; - debian) install_debian ;; - *) say "docker: unsupported/undetected OS family; install Docker manually."; exit 1 ;; - esac -fi - -# --- 2. enable + start the service (systemd only) ---------------------------- -if [ -d /run/systemd/system ] && command -v systemctl >/dev/null 2>&1; then - sudo systemctl enable --now docker -else - say "docker: no systemd; not managing the service (start dockerd yourself)." -fi - -# --- 3. group membership for the invoking user ------------------------------- -user="$(id -un)" -if id -nG "$user" | tr ' ' '\n' | grep -qx docker; then - say "docker: $user already in the docker group." -else - sudo usermod -aG docker "$user" - say "docker: added $user to the docker group." - say " Log out and back in (or run 'newgrp docker') for it to take effect." -fi diff --git a/zsh/zshrc b/zsh/zshrc index d5422ff..bb39a02 100644 --- a/zsh/zshrc +++ b/zsh/zshrc @@ -2,19 +2,6 @@ # overwritten on the next bootstrap run. Edit zsh/zshrc in the dotfiles repo # instead. -# If this account was added to the docker group (dotfiles/docker/install.sh) -# but this shell's session predates that, re-exec via newgrp so docker works -# without a full logout. Guarded: fires only when the group is on the account -# yet missing from the running shell's groups, so the newgrp'd shell (which -# has the group) cannot loop. -# Only for real terminals ([ -t 0 ]): newgrp replaces the shell and would -# swallow the command in scripted `zsh -i -c ...` invocations. -if [ -t 0 ] && [ -S /var/run/docker.sock ] \ - && id -nG "${USER:-$(id -un)}" 2>/dev/null | grep -qw docker \ - && ! id -Gn 2>/dev/null | grep -qw docker; then - exec newgrp docker -fi - # Userland tools installed by dotfiles/bin/install.sh live here. case ":$PATH:" in *":$HOME/.local/bin:"*) ;;