Publish multi-arch homelab-fabric container image #1
Loading…
Reference in a new issue
No description provided.
Delete branch "container-image"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Builds and publishes the Fabric dashboard as a container image, so homelab's Ansible can pull it (like astr and comfy-gallery) instead of running
docker compose buildon channel66.Image
git.scruffydude.net/scruffydude/homelab-fabric, a multi-arch manifest list (linux/amd64,linux/arm64):<short-sha>:latestmain:vX.Y.Zv*tag (this is how releases are cut):latestis gated ongithub.ref == refs/heads/main, notref_type == branch, so aworkflow_dispatchon another branch can't movelatest. Otherwise the tagging, login and logout steps are the same as astr and comfy-gallery.Changes
Dockerfile(root, not templated):python:3.12-slim-bookworm+openssh-client. Everyfabric/*.pygoes in/app, soai_fabric_dispatch.pysits besideai_fabric.py.ENTRYPOINT python3 /app/ai_fabric.py,CMD serve,EXPOSE 8765. TheHEALTHCHECKis written in Python and requests/api/summarywithRemote-Groups: admins, because the endpoint returns 403 without it. No secrets, hostnames or IPs.fabric/ai_fabric.py: everyserveflag now defaults from an env var, and explicit flags still override.--import-before-servebecame--[no-]import-before-serveso the CLI can turn off an env-enabled value. Bad env values fail with an argparse error. Defaults with no env set are unchanged (covered by tests)..dockerignore(tests, docs, .git, .forgejo, caches)..forgejo/workflows/build.ymlreplacesci.yml. Thetestjob (pytest + sample-job contract check) runs on PRs and pushes.build-and-push(needs: test, push/workflow_dispatch only) runs these steps in order:tonistiigi/binfmt:qemu-v10.2.3 --install arm64docker-containerbuildx builder--loadand run the smoke testbuildx build --platform linux/amd64,linux/arm64 --pushwith all tagsimagetools inspecteach tagif: always()cleanup of the builder and smoke image, then logouttests/smoke_image.sh IMAGE: starts the image with its default ENV/CMD, a temp/dataand a minimal/repobuilt fromtests/fixtures. It waits for healthhealthy, then asserts 200 from/api/summaryand/api/jobsand that the fixture worker and job were loaded. Fixtures go in withdocker cprather than bind mounts, because the CI job container drives the host daemon through the socket and its paths don't exist on the host.Env vars (image defaults = today's deployment)
AI_FABRIC_HOST--host0.0.0.0AI_FABRIC_PORT--port8765AI_FABRIC_DB--db/data/fabric.sqlite3AI_FABRIC_ARTIFACT_ROOT--artifact-root/data/agent-runsAI_FABRIC_HOST_CONFIG--host-config/data/worker-registry.jsonAI_FABRIC_JOB_DIR--job-dir/repo/examples/agent-jobsAI_FABRIC_REPO_ROOT--repo-root/repoAI_FABRIC_IMPORT_BEFORE_SERVE--[no-]import-before-servetrueAI_FABRIC_IMPORT_INTERVAL--import-interval15AI_FABRIC_COST_PER_MILLION_TOKENS--cost-per-million-tokens10Mounts
/dataagent-runs/,worker-registry.json(must be seeded; the server exits if it's missing, same as today)/reposcripts/agents/agent_runner.py,examples/agent-jobs,examples/agent-hosts/root/.sshknown_hostsUnchanged contract: dispatch still runs
<repo-root>/scripts/agents/agent_runner.pywithcwd=<repo-root>from the mounted consumer checkout.Multi-arch approach and runner changes
The build cross-builds on the x86_64 runner with buildx (
docker-containerdriver) and QEMU. Both run on the host daemon through the mounted socket, so the job container itself doesn't need to be privileged. binfmt registration is kernel-wide on optibcc and persists until reboot. Re-running the registration each build is idempotent.I checked the runner on optibcc:
act-runner-docker-cliships Debian bookwormdocker.io20.10.24 with no CLI plugins, anddocker buildx versionfails with "'buildx' is not a docker command". Neitherdocker-buildxnordocker-buildx-pluginexists in its apt sources (bookworm main only). The optibcc host itself has buildx v0.36.1, but jobs can't see it.Needed in homelab
ansible/roles/act_runner(pick one):buildx-vX.Y.Z.linux-amd64from github.com/docker/buildx releases to/usr/libexec/docker/cli-plugins/docker-buildxandchmod +xit, ordocker.ioto Docker's apt repo (docker-ce-cli+docker-buildx-plugin).Then rebuild
act-runner-docker-cli. No change to the runner's privileged or socket config is needed.Verification
pytest tests/: 27 passed, including 4 new tests: env defaults, no-env defaults unchanged, flags override env, bad env rejected.tests/smoke_image.shpassed natively on both arches: amd64 on optibcc, arm64 on deskpi (aarch64, same arch as channel66). Results:health: healthy,GET /api/summary: 200,GET /api/jobs: 200, fixture worker registry and job spec loaded. A negative run with a corruptworker-registry.jsonmade the script fail as expected. Temp images and dirs were removed afterwards.actionlint(with shellcheck) is clean onbuild.yml, apart from the expected unknown-label notice for the customdockerlabel.shellcheckis clean onsmoke_image.sh.Required before the first build
REGISTRY_TOKENrepo Actions secret. I couldn't check whether it exists, because listing secrets needs repo-owner access. If it's missing, add ascruffydudeaccess token withwrite:package, the same as astr and comfy-gallery.Homelab follow-ups (not done here; homelab untouched)
ai_fabricrole: pull, don't build.templates/Dockerfile.j2, the "Copy AI Fabric application files" task,base_dir/app, the composebuild:block and the "Build AI Fabric image" task.ai_fabric.image: git.scruffydude.net/scruffydude/homelab-fabric:vX.Y.Z(pin a release tag rather thanlatest) and pull it, e.g.docker_compose_v2withpull: always/missing.environment:in compose where values differ, e.g.AI_FABRIC_COST_PER_MILLION_TOKENS(the old template defaulted to0.0; this image defaults to10per the spec) andAI_FABRIC_IMPORT_INTERVAL. Keepai_fabric.internal_portat 8765 or setAI_FABRIC_PORTto match. Mounts are unchanged; keepinit: true./api/summarywith noRemote-Groupsheader. Since non-admins were restricted (af94603) that endpoint returns 403, so the task can't reach 200. Addheaders: {Remote-Groups: admins}or probe/jobs. Alternatively, wait on the container's health status, which the image now provides.act_runner: add buildx toact-runner-docker-cli(above).scripts/sync_fabric.sh vX.Y.Z, also bump the image tag.🤖 Generated with Claude Code