Skip to content

Install

macOS, Linux, Windows, Dev Containers, Codespaces and Coder workspaces, CI runners and Kubernetes. macOS, Linux, Windows, Dev Containers, Codespaces and Coder workspaces, CI runners and Kubernetes.

halo is the CLI you run in CI and on your workstation. halod is the fleet agent; it runs as root on each machine and applies the ring’s signed release. Every channel below installs the same checksummed archives from a GitHub release. Always pin a version in automation; v0.3.0 below is the current release.

Terminal window
brew install dshakes/tap/halo # formula in github.com/dshakes/homebrew-tap

Or the script, which works on macOS and Linux and needs no sudo:

Terminal window
curl -fsSLO https://raw.githubusercontent.com/dshakes/halos/v0.3.0/install/install.sh
sh install.sh --version v0.3.0 # halo into ~/.local/bin; tells you if that is not on PATH

install.sh verifies checksums.txt against its cosign signature when cosign is on PATH. Without cosign it warns loudly and trusts only the sha256 checksums. It then verifies each archive. --prefix DIR changes the install location; --with-agent adds halod.

Terminal window
curl -fsSLO https://github.com/dshakes/halos/releases/download/v0.3.0/halo_0.3.0_linux_amd64.deb
sudo apt install ./halo_0.3.0_linux_amd64.deb # also .rpm / .apk, arm64, and the halod_* packages

The halo and halod packages (deb, rpm, apk) install to /usr/bin. halod ships a systemd unit and /etc/halos/, but is never enabled or enrolled by the package. You write /etc/halos/halod.yaml, then run systemctl enable --now halod. install.sh works on Linux too.

Terminal window
scoop bucket add dshakes https://github.com/dshakes/scoop-bucket
scoop install halo

Or install.ps1 from the release tag, from an elevated PowerShell:

Terminal window
.\install.ps1 -Version v0.3.0 -WithAgent # to $env:ProgramFiles\Halos

install.ps1 restricts the directory to SYSTEM and Administrators (write) and Users (read/execute), matching halod’s owner check. The binaries are not Authenticode-signed. A winget manifest (Halos.Halo) is built with each release but is not submitted to winget-pkgs.

Terminal window
sudo halod service install --start # print the unit first: halod service print
OS Registers halod binary (default --exe)
macOS launchd daemon /Library/LaunchDaemons/dev.halos.halod.plist /Library/Halos/bin/halod
Linux systemd unit /etc/systemd/system/halod.service /usr/bin/halod
Windows SYSTEM scheduled task Halos, at startup C:\Program Files\Halos\halod.exe

halod refuses to start unless its binary directory, config and state are root-owned and not writable by group or others. Install it into a root-owned path; ~/.local is fine for halo but not for halod. Enroll a machine through the self-service portal, or push the config with your MDM: see laptops and MDM.

GitHub Actions:

- uses: dshakes/halos@v0.3.0
with:
version: v0.3.0 # required; there is no "latest"
# apply: "true" # run `halod once` for a fixed ring (Linux/macOS, uses sudo)
# registry: ghcr.io/acme/halos-releases
# org: acme
# ring: ci
# pubkey: ${{ secrets.HALOS_RELEASE_PUBKEY }}
- run: halo validate

GitLab CI:

include:
- remote: https://raw.githubusercontent.com/dshakes/halos/v0.3.0/deploy/ci/gitlab/halos.gitlab-ci.yml
variables: {HALOS_VERSION: v0.3.0}
policy-check:
extends: .halos
script: [halo validate]
Terminal window
helm install halos deploy/helm/halos --namespace halos --create-namespace

The chart runs halo-server, halo-proxy and halo-shadow, with an optional OTel collector and a Kong plugin resource. Images default to ghcr.io/dshakes/halo-*:<chart appVersion> (currently 0.3.0); to run a different release, set each component’s image.tag (for example --set server.image.tag=0.1.1). See production deployment.

Terminal window
$ halo version
halo 0.3.0 (commit <sha>, built <date>)
$ halo --help # lists validate, release, rollout, toggle, eval, upgrade, gateway, mcp ...

Then go back to Start here and pick a path: halo quickstart to see the whole thing on Docker, or halo doctor to put your own machine under policy.