Files
trx-rs/container
sjg efd82c6284
CI / lint (pull_request) Failing after 1s
CI / test (pull_request) Failing after 1s
CI / reuse (pull_request) Failing after 4s
[chore](trx-rs): use nested SDK image path trx-rs/sdk
Match the image name that was pushed to the registry
(git.haxx.space/sjg/trx-rs/sdk) across the workflow, devcontainer and
README.

Assisted-By: Claude Code (claude-opus-4)
Claude-Session: https://claude.ai/code/session_01NFpGtGTWUEYXLwZeZs2RAV
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-07-19 13:06:43 +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.