Ansible Galaxy & Git Mirror Daemon
ORBITRON
Self-hosted mirror for Ansible roles & collections. A single static Go binary that speaks native Galaxy V1 + V3 APIs — so ansible-galaxy just works against it, with zero client changes, even when there is no internet.
[galaxy]
server_list = orbitron
[galaxy_server.orbitron]
url = https://orbitron.internal/api/- 1static binary
- 0runtime deps
- V1+V3Galaxy APIs
- 90ddefault prune
Built for isolated, pinned, repeatable automation
Orbitron caches whatever your pipelines need — roles, collections, git-backed sources — and serves them as an authentic Galaxy endpoint. Everything ships in one dependency-free binary.
Native Galaxy V1 + V3 API
ansible-galaxy role install and collection install.
Point ansible.cfg at it — no client changes, no retraining. Roles stream as
on-the-fly .tar.gz archives; collections serve real Galaxy V3 metadata.
Official Ansible collection
chrisvanmeer.orbitron ships six HTTP
modules (info, token, manifest, sync,
purge, prune) and two roles — orbitron for install &
lifecycle, orbitron_mirror for declarative mirroring. One playbook run, from
empty host to serving cache.
One static binary
CGO_ENABLED=0 for linux/amd64 and
linux/arm64. Zero runtime dependencies — drop it on a bare-metal box, a container,
or a Nomad allocation and it runs.
Parallel background sync
Ansible-compatible version specifiers
latest, all, =1.4.5, >=1.0.0,
~=1.4.5, <2.0 and wildcards — a zero-dependency PEP 440-subset
engine with proper semantic ordering. Never re-downloads what it already has on disk.
Access-based pruning
--prune --days N removes versions never served inside the retention window,
backed by an atomic per-storage access index. Preview candidates with
POST /api/v1/prune with {"dry_run": true}. Never-accessed versions are always kept.
Cyberpunk web dashboard
/ui cache matrix: sortable storage inventory with block-level disk usage,
tail-f log streaming, and system telemetry. Embedded HTMX, no CDN calls — air-gap ready.
Type the mirror's name and see what happens.
Authentication & SSO that fits your stack
require_auth_pull or keep them open.
Observability out of the box
/metrics — uptime, cache counts, version totals,
namespaces, and real block-allocated byte usage at item and version granularity — paired with
a ready-made Grafana dashboard (orbitron_v13_current.json) that tracks multiple
daemons behind one Prometheus via an Orbitron instance template variable.
Ingest once. Sync. Serve forever.
A tightly modelled pipeline — one daemon, three jobs: pull from the upstream world, cache locally, and hand artifacts back over authentic Galaxy endpoints.
- 01
Ingest manifests
POST YAML role & collection requirements to the management API. Each manifest is content-addressed by SHA-256 and deduplicated on identical re-submission.
- 02
Sync in parallel
Concurrent workers resolve versions against Galaxy V1/V3, download collection tarballs and shallow-clone git sources (--depth 1). Versions already on disk are never re-fetched.
- 03
Store on disk
Roles keep unpacked checkout trees; collections are stored as artifacts — both tracked through an atomic access index (.access.json) for pruning and telemetry.
- 04
Serve like Galaxy
Role downloads are streamed as on-the-fly .tar.gz; collections are served with full V3 metadata. ansible-galaxy sees a normal Galaxy server.
Operations on the bridge of a spaceship
Full-screen, zero-dependency, terminal-themed monitoring built into the binary. Keep an eye on your mirror from a login page that looks like it belongs in a cyberpunk film.

Cache Matrix
Every cached role and collection with sortable TYPE / NAME / VERSION / LAST ACCESS / DISK USAGE columns, a live search filter, and collapsed multi-version rows that unfold on click.
Tail-f log stream
A sliding ▲ LOG STREAM drawer behaves like tail -f — pinned to new lines, releasing when you scroll up. 500-line tail, 2000-line scrollback.
System telemetry
The ◄ SYS METRICS sidebar reports uplink status, cache activity, cache disk usage, mount free space, OS, architecture and last boot. Auto-refreshing.
Air-gap friendly
HTMX is embedded in memory — no external CDN calls. Cookie-based auth, or SSO via Keycloak. Type the mirror’s name for a surprise.
Up and mirroring in minutes
Three ways to run a mirror — bare metal, container, or fully managed by Ansible. Same superpower underneath: a Galaxy endpoint your playbooks already know how to talk to.
Install as a systemd service
Fetch a static binary from the releases page, then --install bootstraps the orbitron user, directories, systemd unit and logrotate in one shot. systemctl reload = hot SIGHUP re-config.
$ sudo ./bin/orbitron --install
$ sudo systemctl status orbitron
# create an admin token (script-friendly: -q)
$ sudo orbitron --generate-token -q
# hot-reload config.yml, no downtime
$ sudo systemctl reload orbitronRun the GHCR image
Multi-arch image (amd64 + arm64), non-root, git and openssh-client bundled. Config is rendered from ORBITRON_* env vars — no file to mount. Persist your cache on a volume.
$ docker compose up -d
[+] Running 1/1
✔ Container orbitron Started
$ docker compose logs orbitron | grep "ADMIN TOKEN"
orbitron | [2026-09-23 08:12:04] ADMIN TOKEN: obt_xxxx...
# also available via ghcr.io/chrisvanmeer/orbitron:latestDeclarative, with the official collection
chrisvanmeer.orbitron covers the full lifecycle from Ansible: install, configure, bootstrap tokens, mirror wait-for-sync and day-two pruning — six HTTP modules plus two roles.
$ ansible-galaxy collection install chrisvanmeer.orbitron
$ ansible-playbook -i hosts orbitron_daemon.yml
# roles:
# chrisvanmeer.orbitron.orbitron # install + operate daemon
# chrisvanmeer.orbitron.orbitron_mirror # declare roles/collections1 · Feed it
Post a YAML requirements manifest — roles, collections or git-backed sources.
roles:
- name: geerlingguy.nginx
version: ">=2.0.0"
- name: RHEL9-CIS
src: https://github.com/ansible-lockdown/RHEL9-CIS.git
version: 2.0.2curl -X POST https://orbitron.internal/api/v1/requirements/roles \
-H "Authorization: Bearer $ORBITRON_TOKEN" \
-H "Content-Type: text/yaml" \
--data-binary @roles_requirements.yml2 · Consume it
Point ansible-galaxy at the mirror. That is the whole setup.
[galaxy]
server_list = orbitron
[galaxy_server.orbitron]
url = https://orbitron.internal/api/
# token = YOUR_ORBITRON_TOKEN # if require_auth_pull$ ansible-galaxy role install -r roles_requirements.yml
$ ansible-galaxy collection install -r collections_requirements.ymlPut it behind a reverse proxy. Terminate TLS with Nginx,Traefik or HAProxy in front of the daemon — Orbitron honorsX-Forwarded-Proto / X-Forwarded-For, and ansible.cfgabove talks native HTTPS. Point load balancer health checks at the unauthenticatedGET /healthz (200 when storage is writable). This keeps API calls, tokens and any git credentials in mirrored src URLs encrypted in transit.
Management endpoints that play nice
A small, pragmatic API surface — ingest content, watch syncs, inspect storage and run day-two operations. The Galaxy V1 & V3 serving endpoints live on the same tree.
Unauthenticated liveness for load balancers & orchestrators — 200 when the storage path is writable, 503 when degraded.
Ingest role & collection YAML manifests. Content-addressed by SHA-256 and deduplicated; parallel workers mirror on the spot.
Re-run every stored manifest, or poll progress and a bounded history of finished syncs.
Full cached-version inventory. DELETE /storage/{type}/{name}/{version} purges a single cached version.
Access-based cleanup with retention window — preview exactly what would be deleted with {"dry_run": true}.
Token lifecycle: create, list, revoke and rotate admin tokens, with optional per-token TTLs.
Prometheus exposition — uptime, cache counts, version totals and block-level storage bytes.
Every endpoint above except /healthz requires a Bearer token or HTTP Basic auth.
Runs where your fleet runs
One binary, every home. Orchestrate it like the rest of your platform, or let the Ansible collection do the orchestrating for you.
- linux/amd64
- linux/arm64
- GPL-3.0
- Go 1.26
- HTMX 4
- PEP 440
self-host · cache · serve
Keep automation moving, even offline
Grab the binary, feed it a requirements file, and let your fleet install roles and collections at LAN speed — pinned, cached and yours forever.