Skip to content

ubuntu-builder

Recipe card from the charly-distros plugin (Images — the deployable catalog).

Ubuntu 24.04 (noble) counterpart of /charly-distros:fedora-builder and /charly-distros:debian-builder. Same role — pixi/npm/cargo multi-stage builder — with one important difference: the builder runs as ubuntu (uid 1000) because the upstream ubuntu:24.04 base image ships a pre-existing ubuntu:ubuntu account at uid 1000, and the embedded distro.ubuntu.base_user vocabulary adopts it.

Lives in the opencharly/distro-ubuntu repo (git submodule at box/ubuntu). Build it from the submodule: charly -C box/ubuntu box build ubuntu-builder (normally builds implicitly as a dependency of ubuntu-coder). Its pixi/nodejs/build-toolchain candies are pulled by github reference from the main repo.

Property Value
Base ubuntu (which = ubuntu:24.04 + our bootstrap)
Layers pixi, nodejs, build-toolchain
Platforms linux/amd64
Registry ghcr.io/opencharly
User ubuntu / uid 1000 (adopt mode — see /charly-image:image “user_policy”)
Home /home/ubuntu
  1. /charly-distros:ubuntu — Ubuntu 24.04 + bootstrap. Inherits Debian’s apt-get update && apt-get install -y --no-install-recommends curl ca-certificates gnupg pattern because the embedded distro.ubuntu vocabulary declares inherits: debian. Ubuntu-specific: base_user: { name: ubuntu, uid: 1000, gid: 1000, home: /home/ubuntu } — no useradd step emitted.
  2. /charly-languages:pixi — pixi package manager + env paths (/home/ubuntu/.pixi).
  3. /charly-coder:nodejs — Node.js + npm (generic nodejs).
  4. /charly-coder:build-toolchain — same Debian -dev packages as /charly-distros:debian-builder.

When the generator emits the Containerfile for this image, the bootstrap section contains:

# User ubuntu (uid=1000) adopted from base image (declared in the embedded distro.base_user vocabulary) — no useradd needed
WORKDIR /home/ubuntu
USER 1000

No useradd, no groupadd, no usermod -l rename. The upstream ubuntu:ubuntu account is honored verbatim — HOME, npm prefix, pixi env, cargo home, sudoers all derive from resolved.User = "ubuntu". See /charly-image:image “user_policy” and /charly-internals:generate-source “writeBootstrap”.

Declares builds: [pixi, npm, cargo] and is referenced from ubuntu: as:

ubuntu:
builder:
pixi: ubuntu-builder
npm: ubuntu-builder
cargo: ubuntu-builder

During charly box build ubuntu-coder, cargo/npm/pixi-owning candies get their FROM ubuntu-builder AS <layer>-<type>-build stages from this image, then COPY --from=<stage> --chown=1000:1000 /home/ubuntu /home/ubuntu into the final ubuntu-coder. (The --chown=1000:1000 numeric form works uniformly regardless of user name — see /charly-coder:build-toolchain for the builder-artifact COPY pattern.)

The three builders have near-identical candy stacks (pixi + nodejs + build-toolchain). The only meaningful divergence is this box’s adopt-mode ubuntu:ubuntu identity.

Terminal window
charly -C box/ubuntu box build ubuntu-builder
charly shell ubuntu-builder # drops you into /home/ubuntu as uid 1000
id # uid=1000(ubuntu) gid=1000(ubuntu)

Typically not invoked directly — it’s a build-time dependency of /charly-coder:ubuntu-coder.

  • charly -C box/ubuntu box list | grep ubuntu-builder
  • charly shell ubuntu-builder -- iduid=1000(ubuntu) gid=1000(ubuntu)
  • charly shell ubuntu-builder -- pixi --version && node --version && gcc --version

MUST be invoked when:

  • Building or troubleshooting ubuntu-builder itself.
  • Debugging multi-stage COPY-from errors or permission issues in a ubuntu-coder build (this is the source stage; uid 1000 = ubuntu by adoption).
  • Understanding why ${HOME} = /home/ubuntu (not /home/user) inside builder stages.