Skip to content

Build & Package Cache Topology (Nexus)

FractalOps runs a single cache plane: Nexus. The standalone registry-cache LXC (CT113 @ 10.10.10.150) was decommissioned 2026-06-18 and folded into Nexus — there is no separate cache VM/LXC anymore.

Nexus serves every cache role:

  • npm: Nexus npm-group
  • pip: Nexus pypi-group
  • apt: Nexus apt-debian (add apt-ubuntu before pulling from ubuntu mirrors)
  • docker.io pull-through: Nexus docker-group
  • ghcr.io pull-through: Nexus docker-group
  • OCI build cache registry (platform CI image builds): Nexus docker-internal (hosted)
  • Service: nexus in namespace nexus (nexus.nexus.svc); public https://nexus.yamon.io
  • npm / pypi / web API: :8081 (/repository/<repo>/)
  • docker-group (docker.io + ghcr.io pull-through, V2): :8083
  • docker-internal (hosted; CI image buildcache push/pull): :8082
  • Node-reachable docker mirror: NodePort 30083 -> 8083 (preferred), or the Nexus Service ClusterIP :8083 via kube-proxy.

Topology models this under the registry_cache key (historical name; the values now point at Nexus — host_ip is the Nexus ClusterIP, buildcache_ref: nexus.nexus.svc:8082/fractalops/buildcache, docker_proxy_port/ghcr_proxy_port: 8083). render_env emits the corresponding FRACTALOPS_* env from it.

Every K3s node’s /etc/rancher/k3s/registries.yaml mirrors docker.io + ghcr.io to the Nexus docker-group:

mirrors:
docker.io:
endpoint: ["http://127.0.0.1:30083"]
ghcr.io:
endpoint: ["http://127.0.0.1:30083"]
configs:
"127.0.0.1:30083":
auth:
username: "shim-puller"
password: "<FRACTALOPS_NEXUS_PULL_PASSWORD from OpenBao runtime scope>"

The mirror credential is sourced from OpenBao (runtime scope), not hand-edited. For the node-by-node cutover procedure + rollback, see Nexus Docker Mirror Cutover.

Private GHCR images: the Nexus docker-group proxies ghcr.io, and Nexus itself holds the upstream GHCR credential (from OpenBao via ExternalSecrets) — Pods do not each need an imagePullSecret for the cache path.

The cache plane serves two distinct consumers: developer workspaces (pull-through mirrors) and the platform’s own CI image release pipeline (runtime image build cache). There is no per-project build pipeline and no in-sandbox build/ship plane — that whole surface was deleted. Dev previews are bare processes; see Dev Preview Plane.

The FractalOps API/worker/portal images are CI-built and GitOps-pinned. CI pushes build cache through the Nexus docker-internal buildcache (nexus.nexus.svc:8082/fractalops/buildcache) and pulls base layers through the Nexus pull-through mirrors. Build duration, cache availability, and failure-rate signals are Build Plane Event records — see Build Plane Observability. Temporal schedules and runs jobs; it does not become the metrics warehouse.

Portal image release lives in yamonco/fractalops-frontend; run the frontend release there, not from this control-plane repo:

Terminal window
gh workflow run "Portal GitOps Release" --repo yamonco/fractalops-frontend

For FractalOps API/worker runtime smoke builds, keep GitOps immutable unless you are intentionally promoting one final image:

Terminal window
FRACTALOPS_ALLOW_LOCAL_RUNTIME_RELEASE=1 \
FRACTALOPS_RUNTIME_RELEASE_UPDATE_GITOPS=0 \
./ops/containers/fractalops/release.sh

Use the printed image_ref=... for an explicit smoke. Only the final promotion should update platform/k8s/apps/fractalops-api/values.yaml and platform/k8s/apps/fractalops-worker/values.yaml.

Developer Workspaces (no container runtime)

Section titled “Developer Workspaces (no container runtime)”

For developer workspaces, the default Daytona template exports topology-derived cache values such as:

  • FRACTALOPS_GHCR_REGISTRY_CACHE=<nexus-docker-group-url>
  • FRACTALOPS_DOCKER_IO_MIRROR_ENDPOINT=<nexus-docker-group-url>
  • FRACTALOPS_GHCR_IO_MIRROR_ENDPOINT=<nexus-docker-group-url>
  • FRACTALOPS_APT_CACHE_URL=<nexus-apt-debian-url>

The sandbox has no container runtime:

  • docker is hard-walled as a baked exit-127 stub (it stays a stub even in-session). There is no in-sandbox compose/build plane.
  • Live preview is the bare dev server (vite / next / uvicorn bound to 0.0.0.0), exposed through the daytona-proxy signed preview URL via the dev-preview MCP (dev_preview_start / dev_preview_url / dev_preview_stop). See Dev Preview Plane.
  • Per-project persistent hosting (databases, static-site, big-facility compose) is the project’s Dokploy plane — not the sandbox.
  • gh is a launcher whose GitHub App proxy routes agent issue/PR writes through the FractalOps GitHub App broker instead of storing GitHub tokens in the workspace.
  • There is one cache plane: Nexus. Do not reintroduce a standalone registry-cache VM/LXC; model cache endpoints in topology (the registry_cache key -> Nexus values), never bake addresses into project code.
  • Platform CI image builds use the Nexus buildcache (nexus.nexus.svc:8082/fractalops/buildcache); cache_to/from carry ignore-error=true, so a buildcache misconfig degrades to a cache miss, never a build failure.
  • Daytona workspace images must not install or require a Docker daemon. There is no in-sandbox build/ship plane; dev previews are bare processes.
  • Developers must not write per-project DevSpace/watch/sync rules for the default loop. Daytona hides the Kubernetes runtime shape.
  • Prefer pve-worker0 for fast Daytona workspaces and local scratch; pve-worker3 for memory-heavy work.
  • Nexus owns its own blob store + scheduled cleanup/compaction (no external registry-gc.timer).