Install

Every release ships static binaries for Linux AMD64 and ARM64, plus a multi-arch container image. Pick whichever fits your fleet โ€” all three end up with the same daemon and the same Galaxy API on top.

Bare metal (systemd)

Fetch a binary from the releases page. Then--install as root bootstraps everything: the orbitron user and group, directories, config files, a systemd unit and a logrotate script โ€” then enables and starts the daemon.

SETUPterminalbash
$ sudo ./bin/orbitron --install
$ sudo systemctl status orbitron        # active (running)

# create an admin token (script-friendly: -q)
$ sudo orbitron --generate-token -q

# hot-reload config.yml, no downtime
$ sudo systemctl reload orbitron

systemctl reload sends a SIGHUP: the daemon re-reads/etc/orbitron/config.yml, re-validates it (including OIDC discovery when enabled) and rebuilds the HTTP server on the same address. If the new config fails to validate, the running daemon is left untouched.

Bundled Ansible collection

Every binary embeds the official chrisvanmeer.orbitron collection at build time, and the cache is seeded with it out of the box. Seeding runs from--install and again on every daemon start โ€” so upgrading is as simple as swapping the binary and restarting: the daemon sees the newer embedded version on boot and seeds it once. The seed follows your configured storage_path (default/var/lib/orbitron/storage, but point it anywhere you like โ€” the cache layout and the seed follow that path). A fresh mirror can therefore install it immediately, without upstream Galaxy:

CLIENTterminalbash
$ ansible-galaxy collection install -s http://127.0.0.1:8080 chrisvanmeer.orbitron
# -> the bundled version is already in the cache and resolves instantly

Seeding only fires when the embedded version is newer than anything the cache already holds. Re-running --install or restarting a machine that already runs Orbitron โ€” newer or older โ€” never overwrites, downgrades, or duplicates existing collection data, so upgrades need no migration. The seeded version is declared through a default requirements manifest, which keeps it safe from pruning.

Docker / Compose

The GHCR image runs non-root with git and openssh-client bundled. Config is rendered entirely from ORBITRON_* environment variables โ€” no file to mount. Persist the cache on a volume. The repo ships a ready-made docker-compose.yml at its root โ€” clone the repo and run it from the clone:

DEPLOYterminalbash
$ git clone https://github.com/chrisvanmeer/orbitron.git
$ cd orbitron
$ docker compose up -d
# uses docker-compose.yml from the repo root
COMPOSEdocker-compose.ymlyaml
services:
  orbitron:
    image: ghcr.io/chrisvanmeer/orbitron:latest
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      ORBITRON_LISTEN_ADDR: "0.0.0.0:8080"
      ORBITRON_STORAGE_PATH: "/var/lib/orbitron/storage"
      ORBITRON_REQUIRE_AUTH_PULL: "false"
    volumes:
      - orbitron-cache:/var/lib/orbitron/storage

volumes:
  orbitron-cache:

On first start the admin token is printed to the container logs:

TOKENterminalbash
$ docker compose logs orbitron | grep "ADMIN TOKEN"
orbitron  | [2026-09-23 08:12:04] ADMIN TOKEN: obt_xxxx...

HashiCorp Nomad

A battle-tested orbitron.nomad.hcl ships in the repo root โ€” service, volume, health check against /healthz and secrets via env already wired up. Clone the repo and run the jobspec from the clone (read the full walk-through in theREADME, including the host volume you register on the client before the first run):

DEPLOYterminalbash
$ git clone https://github.com/chrisvanmeer/orbitron.git
$ cd orbitron
$ nomad run orbitron.nomad.hcl
$ nomad status orbitron

Kubernetes (Helm)

The repo ships a ready-made Helm chart at helm/orbitron โ€” aStatefulSet (one replica by default) with a persistent volume for the cache and admin token, a ClusterIP Service on :8080,/healthz readiness/liveness probes, and an optional NGINXIngress. Clone the repo and install from the clone:

DEPLOYterminalbash
$ git clone https://github.com/chrisvanmeer/orbitron.git
$ cd orbitron
$ helm install orbitron ./helm/orbitron
$ kubectl logs orbitron-0 | grep "ADMIN TOKEN"   # first start only
# custom values: see helm/orbitron/values.yaml
$ helm install orbitron ./helm/orbitron --set ingress.enabled=true   --set ingress.hosts[0].host=mirror.internal

CLI & tokens

CLIterminalbash
# Generate an administrative Bearer token
sudo orbitron --generate-token

# Raw token output for script exports
export ORBITRON_TOKEN=$(sudo orbitron --generate-token -q)

# Revoke a token
sudo orbitron --revoke-token <TOKEN>

# Interactively scan + prune unreferenced versions (window: --days, default 90)
sudo orbitron --prune

# Run with a custom config
orbitron --config /etc/orbitron/config.yml

# Show version
orbitron --version