build: add Dockerfile.azkaban with the site's tools #83

Merged
claudiomaradonna merged 2 commits from feat/dockerfile-azkaban into master 2026-11-11 16:30:04 +01:00
Collaborator

Why

This repository builds the company website with Jekyll, and contributors
often work on it through coding agents run in azkaban, a launcher that
keeps each agent in a rootless Podman container. azkaban's stock image
has no Ruby and ships Node 22, so an agent there could not run the
project's Setup command (bundle install && npm install -g terser) nor
its Verify command (make build && .agents/hooks/shellcheck.sh repo):
every check had to be repeated on the host before merging an agent's
branch. CONTRIBUTING.md described a git-ignored Dockerfile.claude-jail
that each contributor built and selected by hand, and its example
installed neither Ruby nor Node 24.

azkaban now builds a workspace Dockerfile.azkaban itself, on top of
the client image, once the user approves its content, so the tools can
live in a tracked file. Set aside: Ubuntu's ruby-full (not Ruby
4.0.7), compiling Ruby with ruby-build (minutes on every rebuild), and
copying the client's home onto a separate tools image (tied to Claude
and to azkaban's internals).

What changed

Before, an agent in azkaban had no Ruby and the wrong Node. Now, after
the user approves Dockerfile.azkaban at the first launch, the agent's
image carries Ruby 4.0.7 with the bundle already installed and Node 24
with terser; Python 3, Git, jq, and ShellCheck already come with
azkaban's image.

Ruby with the bundle and Node with terser are built in stages
independent of the client image, so a refresh of azkaban's client
image rebuilds only the final copies. The bundle installs as UID 1000,
since a change to Gemfile, which the agent can edit, rebuilds that
stage at the next launch without a new approval. Global npm packages
go to the client's ~/.local, the place the agent's Bash sandbox may
write.

CONTRIBUTING.md § Running agents in azkaban now describes the tracked
file in place of Dockerfile.claude-jail and AZKABAN_CLAUDE_IMAGE;
.gitignore and .dockerignore drop Dockerfile.claude-jail, and
.dockerignore keeps Dockerfile.azkaban out of the production build
context.

How to verify

  1. Have azkaban installed with its Claude client (./install.sh claude)
    and a clone of this repository.
  2. The problem, on master: from the clone, run claude ., then in the
    session ! ruby -v; it prints ruby: command not found, and
    ! node -v prints v22.x.
  3. The solution: git switch --detach feat/dockerfile-azkaban, then
    claude .; approve Dockerfile.azkaban when asked and wait for the
    build. In the session:
    • ! ruby -v && node -v && which terser prints ruby 4.0.7…,
      v24.x, and /home/claude/.local/bin/terser;
    • ! bundle install && npm install -g terser ends with
      Bundle complete! and no error;
    • ! make build && .agents/hooks/shellcheck.sh repo builds _site/
      and prints shell check: … files clean.
  4. Return with git switch master.

Checks run: step 2 matches the stock azkaban container (no ruby, Node
v22.23.4); step 3 in azkaban on this branch's tree, which
passed; .agents/hooks/shellcheck.sh repo on each commit, clean; the
repository has no test suite.

Considerations

The final image carries no compiler: after a Gemfile.lock change, the
next launch rebuilds the bundle, and until then bundle install in the
container installs only gems that need no compiling. The ruby and
node image tags are one more place to bump with .ruby-version and
.nvmrc; the stage comments say so.

## Why This repository builds the company website with Jekyll, and contributors often work on it through coding agents run in azkaban, a launcher that keeps each agent in a rootless Podman container. azkaban's stock image has no Ruby and ships Node 22, so an agent there could not run the project's Setup command (`bundle install && npm install -g terser`) nor its Verify command (`make build && .agents/hooks/shellcheck.sh repo`): every check had to be repeated on the host before merging an agent's branch. CONTRIBUTING.md described a git-ignored `Dockerfile.claude-jail` that each contributor built and selected by hand, and its example installed neither Ruby nor Node 24. azkaban now builds a workspace `Dockerfile.azkaban` itself, on top of the client image, once the user approves its content, so the tools can live in a tracked file. Set aside: Ubuntu's `ruby-full` (not Ruby 4.0.7), compiling Ruby with ruby-build (minutes on every rebuild), and copying the client's home onto a separate tools image (tied to Claude and to azkaban's internals). ## What changed Before, an agent in azkaban had no Ruby and the wrong Node. Now, after the user approves `Dockerfile.azkaban` at the first launch, the agent's image carries Ruby 4.0.7 with the bundle already installed and Node 24 with terser; Python 3, Git, jq, and ShellCheck already come with azkaban's image. Ruby with the bundle and Node with terser are built in stages independent of the client image, so a refresh of azkaban's client image rebuilds only the final copies. The bundle installs as UID 1000, since a change to `Gemfile`, which the agent can edit, rebuilds that stage at the next launch without a new approval. Global npm packages go to the client's `~/.local`, the place the agent's Bash sandbox may write. CONTRIBUTING.md § Running agents in azkaban now describes the tracked file in place of `Dockerfile.claude-jail` and `AZKABAN_CLAUDE_IMAGE`; `.gitignore` and `.dockerignore` drop `Dockerfile.claude-jail`, and `.dockerignore` keeps `Dockerfile.azkaban` out of the production build context. ## How to verify 1. Have azkaban installed with its Claude client (`./install.sh claude`) and a clone of this repository. 2. The problem, on `master`: from the clone, run `claude .`, then in the session `! ruby -v`; it prints `ruby: command not found`, and `! node -v` prints `v22.x`. 3. The solution: `git switch --detach feat/dockerfile-azkaban`, then `claude .`; approve `Dockerfile.azkaban` when asked and wait for the build. In the session: - `! ruby -v && node -v && which terser` prints `ruby 4.0.7…`, `v24.x`, and `/home/claude/.local/bin/terser`; - `! bundle install && npm install -g terser` ends with `Bundle complete!` and no error; - `! make build && .agents/hooks/shellcheck.sh repo` builds `_site/` and prints `shell check: … files clean`. 4. Return with `git switch master`. Checks run: step 2 matches the stock azkaban container (no `ruby`, Node v22.23.4); step 3 in azkaban on this branch's tree, which passed; `.agents/hooks/shellcheck.sh repo` on each commit, clean; the repository has no test suite. ## Considerations The final image carries no compiler: after a `Gemfile.lock` change, the next launch rebuilds the bundle, and until then `bundle install` in the container installs only gems that need no compiling. The `ruby` and `node` image tags are one more place to bump with `.ruby-version` and `.nvmrc`; the stage comments say so.
azkaban builds a workspace Dockerfile.azkaban on top of its client
image after the user approves it. Ruby 4.0.7, the bundle, and Node 24
with terser come from stages independent of the client, so the nightly
client refresh rebuilds only the final copies.
docs(contributing): describe the tracked Dockerfile.azkaban
All checks were successful
Build image / build (push) Successful in 5m2s
a35d34b481
azkaban now builds a workspace Dockerfile.azkaban itself after the
user approves it, so the git-ignored Dockerfile.claude-jail and the
AZKABAN_CLAUDE_IMAGE step are gone, and the Verify command runs in
the jail.
claudiomaradonna deleted branch feat/dockerfile-azkaban 2026-11-11 16:30:09 +01:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
unitoo/website!83
No description provided.