Files
trx-rs/container
sjg 7022f20b76 [chore](trx-rs): shared SDK image for CI and developers
Rework container/ from a host-executor act_runner image into a single
"SDK" build image used everywhere: as the CI job container (Docker
executor) and by developers locally / via .devcontainer. It bakes in a
pinned Rust toolchain and all build dependencies, so CI and every
developer share the exact same rustc/clippy.

- container/Containerfile: SDK image (Debian + deps + pinned Rust + Node).
- rust-toolchain.toml: pin the toolchain to match the image; also ends the
  "CI clippy newer than local" version skew.
- .gitea/workflows/ci.yml: lint/test run inside the SDK image via
  `container:`; reuse returns to fsfe/reuse-action (Docker executor runs
  it as a sibling container, so nothing REUSE-related is baked in).
- .devcontainer/devcontainer.json: dev use of the same image.
- container/runner-config.example.yaml: Docker-executor runner config for
  the CI VM, capped for a 2-thread budget.
- Drop the obsolete host-executor entrypoint/config/Quadlet units.

Assisted-By: Claude Code (claude-opus-4)
Claude-Session: https://claude.ai/code/session_01NFpGtGTWUEYXLwZeZs2RAV
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-08-02 11:27:42 +02:00
..

trx-rs SDK image

A single container image that is the canonical build environment for trx-rs, used both by CI and by developers. It bakes in the pinned Rust toolchain (matching rust-toolchain.toml) and every build dependency, so the compiler and clippy are identical everywhere — no "works on my machine".

File Purpose
Containerfile The SDK image (Debian + build deps + pinned Rust + Node + git).
runner-config.example.yaml Example act_runner config for the CI VM (Docker executor).

Build and publish

# from the repo root
podman build -t git.haxx.space/sjg/trx-rs-sdk:latest container
podman login git.haxx.space
podman push git.haxx.space/sjg/trx-rs-sdk:latest

Tag with the Rust version too (e.g. :1.97.1) if you want reproducible pins. Make the package public (Gitea → Packages → the image → Settings) so the CI runner and developers can pull it without credentials. If you keep it private, add credentials: under the workflow's container: and log the runner into the registry.

Developer use

Reproducible one-off build, no local toolchain needed:

podman run --rm -it -v "$PWD":/work -w /work \
  git.haxx.space/sjg/trx-rs-sdk:latest \
  cargo build --release

Or open the repo in the image via VS Code / JetBrains "Reopen in Container" (.devcontainer/devcontainer.json points at the same image).

Building outside the container? rust-toolchain.toml pins the same rustc, so rustup installs the matching toolchain automatically.

CI use

.gitea/workflows/ci.yml runs the lint and test jobs inside this image via the container: key, so they skip all setup and go straight to cargo. The reuse job stays on the upstream fsfe/reuse-action (a Docker action the Docker executor launches as a sibling container) — nothing REUSE-related is baked into the SDK.

CI runner (VM)

The runner runs in a small VM using the Docker executor (not the host executor). This gives per-job container isolation and standard ubuntu-latest semantics, and caps CI resources at the VM boundary.

  1. Size the VM to your thread budget. 2 vCPUs = a hard 2-thread ceiling. Pin them to specific host threads so CI never touches the rest (libvirt/KVM):

    <vcpu placement='static'>2</vcpu>
    <cputune>
      <vcpupin vcpu='0' cpuset='4'/>
      <vcpupin vcpu='1' cpuset='5'/>
    </cputune>
    
  2. Inside the VM: install Docker (moby) and act_runner.

  3. Register one runner per project (separate tokens from each repo's Settings → Actions → Runners; scope keeps their jobs apart).

  4. Configure with runner-config.example.yamlcapacity: 1 and container.options: "--cpus=2" keep usage inside the 2-thread budget.