astro is the command-line client for the
Astrolift PaaS. App developers use it to register
apps, deploy, manage secrets, and inspect runtime state. Operators use it to
register clusters and configure providers against an Astrolift control plane.
Status posture. This CLI is early — pre-1.0 and only a handful of commits in. The command tree is structured (every group has its subcommands wired in Cobra) but several command bodies still surface
not yet wired to the APIuntil the matching backend resolvers ship. The wired surfaces today are:astro server *,astro auth *,astro app init,astro ci deploy/astro ci status,astro version-check/astro self-update,astro version,astro docs, andastro cluster bootstrap. Subcommand surface, flag names, and exit codes may shift before 1.0 — pin a tagged release in CI rather than trackingmain.
brew install calliopeai/tap/astro(Tap published by GoReleaser on each tagged release.)
scoop bucket add calliopeai https://github.com/calliopeai/scoop-bucket
scoop install astrocurl -fsSL https://astrolift.app/cli/install.sh | shThe installer detects your OS / arch, fetches the matching tarball from
GitHub Releases,
and drops astro into /usr/local/bin (or ~/.local/bin if the system
dir isn't writable). See scripts/install.sh.
Grab the platform-appropriate archive from
Releases, extract
the astro binary, and place it on your PATH.
docker pull ghcr.io/calliopeai/astro:latest
docker run --rm -v "${HOME}/.config/astrolift:/home/nonroot/.config/astrolift" \
ghcr.io/calliopeai/astro:latest versionThe image is gcr.io/distroless/static-debian12:nonroot; mount your
config directory for stateful commands.
git clone https://github.com/calliopeai/astrolift-cli
cd astrolift-cli
make build # produces ./astro
./astro versionOr, with go install:
go install github.com/calliopeai/astrolift-cli@latest(Note: the Go module path is github.com/calliopeai/astrolift-cli; the
GitHub repo is calliopeai/astrolift-cli. The two are intentional — the
module path will follow the public repo on the next major.)
# 1. Tell the CLI where your platform lives
astro server add prod https://api.astrolift.example.com
astro auth login
# 2. Scaffold an app manifest in your project
cd my-service/
astro app init # writes astrolift.toml
# 3. Register and deploy
astro app register
astro app deploy
# 4. Watch it run
astro app logs # tail logs
astro app events # platform events
astro app exec web -- ps aux # one-shot in a workload# Required env (deploy tokens issued via `astro app tokens`)
export ASTROLIFT_API_URL="https://api.astrolift.example.com"
export ASTROLIFT_DEPLOY_TOKEN="$ASTRO_TOKEN"
export ASTROLIFT_APP_SLUG="my-service"
export ASTROLIFT_IMAGE_TAGS='{"web":"sha-deadbeef"}'
astro ci deploy # enqueues + polls until terminal state
# Exit codes: 0 success, 1 deploy failure, 2 config errorci deploy defaults to polling. Pass --no-wait for fire-and-forget,
or set ASTROLIFT_DEPLOY_TIMEOUT (Go duration) to override the
30-minute polling cap.
Operator commands configure the platform itself rather than tenant apps — cluster CRUD, provider plugin management, federation:
astro operator cluster ...
astro operator provider ...
astro operator federation ... # cross-install federation(Operator subcommands are admin-gated and currently scaffolded — see the status note above.)
| Group | Purpose |
|---|---|
astro server |
Manage Astrolift installs the CLI knows about (add / list / use / remove). One install = one DNS zone + database. |
astro auth |
Browser device-flow login, logout, status, refresh. |
astro app |
App lifecycle (init, register, deploy, rollback, promote) plus sub-resources (secrets, services, domains, tokens, members, jobs, events, audit, logs, exec, previews). |
astro ci |
CI-mode commands (deploy, status, render) — no interactive prompts; reads token + slug from env. |
astro org / astro team / astro project |
Org-scoped resource management. |
astro operator |
Operator (admin) cluster, provider, and federation management. |
astro cluster bootstrap |
One-shot helm install of the astrolift-prereqs chart (cert-manager, ingress, storage, external-dns) against a registered cluster; the bundled chart + per-cloud values are vendored into the binary. |
astro scm / astro alert |
Source-control webhooks and alert rules. |
astro status |
Platform status snapshot. |
astro docs |
Open the platform docs in your browser. |
astro version-check / astro self-update |
Server-aware compatibility check + upgrade pointer. |
astro version |
Print the CLI version (set at build time via -ldflags). |
Every command supports --json for machine-readable output, plus
--api-url, --token, --org, --team, --project, --app,
--no-color, --no-prompt, and --debug as global flags. Errors go
to stderr; data goes to stdout.
Run astro <command> --help for the full flag set; the help text is
the source of truth.
The CLI stores its state under ~/.config/astrolift/:
~/.config/astrolift/
config.yaml servers, current server, output prefs
credentials/
<server-slug>.yaml per-server tokens, mode 0600
The CLI refuses to read credentials files with permissions wider
than 0600. Don't loosen them.
Environment variables take precedence over the config file (CI mode):
| Var | Used by |
|---|---|
ASTROLIFT_API_URL |
overrides current_server's API URL |
ASTROLIFT_DEPLOY_TOKEN |
bypasses stored credentials (CI tokens) |
ASTROLIFT_APP_SLUG |
required by astro ci deploy |
ASTROLIFT_IMAGE_TAGS |
required by astro ci deploy (JSON map workload→tag) |
ASTROLIFT_ENVIRONMENT |
optional, default production |
ASTROLIFT_BRANCH |
optional, default main |
ASTROLIFT_COMMIT_SHA |
optional, falls back to git rev-parse HEAD |
ASTROLIFT_IDEMPOTENCY_KEY |
optional, suppresses duplicate deploys |
ASTROLIFT_DEPLOY_TIMEOUT |
optional, Go duration; default 30m |
Astrolift is split across a handful of repos. This is the client side:
- astrolift-cli (this repo) —
astrodeveloper + operator CLI - astrolift-opscode — Terraform + Helm IaC for installing the platform on a cloud you control (AWS / GCP / Azure / vanilla k8s)
- astrolift platform / API — the control plane the CLI talks to; see astrolift.app and the public docs (once published)
The CLI is a pure client of the platform API — it never re-implements business logic. Backend policy lives behind the GraphQL + REST surface; the CLI's job is to pack arguments, call the API, and render results.
make build # compile ./astro with version ldflag
make test # go test ./... -v -count=1
make fmt # gofmt + goimports
make lint # golangci-lint run ./...
make clean # remove ./astro, clear test cacheThe build injects Version via -ldflags from the nearest git tag
(git describe --tags --always --dirty). For a tagged release build
locally:
goreleaser release --snapshot --cleanCI runs the same on tags, plus produces Homebrew tap + Scoop bucket
updates and a Docker image at ghcr.io/calliopeai/astro.
PRs welcome — see CONTRIBUTING.md for the dev loop, style requirements, and PR conventions.
Issues: please file against github.com/calliopeai/astrolift-cli/issues. For security reports, see SECURITY.md — do not open a public issue for vulnerabilities.
Community standards: CODE_OF_CONDUCT.md.
- bootstrap.md — stack, directory layout, conventions, build commands, config + credentials model
- CONTRIBUTING.md — fork + PR flow + style
- SECURITY.md — vulnerability disclosure
- CLAUDE.md / AGENTS.md /
GEMINI.md / CODEX.md — agent shims
(all point at
bootstrap.md) - CODE_OF_CONDUCT.md — community standards
- LICENSE — MIT
MIT. See LICENSE.
Copyright (c) 2026 Calliope Labs Inc. All Rights Reserved. Calliope AI is a trademark of Calliope Labs Inc.
Portions of the framework underlying this repo are derived from boilerworks (Copyright (c) Conflict LLC, MIT-licensed). Tip of the hat 🎩