Skip to content

Commands

This is the complete Pyahu CLI reference. Every command accepts the global flags from the next section. Most support --output json for use in scripts.

pyahu [command] [flags]

Available on any command:

FlagDefaultDescription
-f, --fileautomatic discoveryPath to the project’s pyahu.yaml. The global config is still applied.
-o, --outputhumanOutput format: human or json.
--no-colorfalseDisable colors in the output.
-q, --quietfalseSuppress non-essential output.
-v, --verbosefalseShow tool output (k3d, etc.).
--no-inputfalseNever prompt interactively.
--version—Show version, commit, and build date.
-h, --help—Command help.

The CLI searches for the stack file from the current directory upward, in this order: pyahu.yaml, pyahu.yml, .pyahu/stack.yaml, .pyahu/stack.yml. Use --file only to point at another path.


Creates a pyahu.yaml from a preset.

FlagDefaultDescription
--presetminimalStarting preset: minimal (PostgreSQL only) or platform (full stack).
--forcefalseOverwrite an existing stack file.
Terminal window
pyahu init --preset platform
pyahu init --preset minimal --force
pyahu init --preset platform -f infra/pyahu.yaml

Creates the k3d cluster when needed and reconciles the Kubernetes resources. It is idempotent: a second pyahu up converges or does nothing. Resources managed by Pyahu that are no longer in the stack are removed; persistent volume claims are retained to protect local data.

FlagDefaultDescription
--skip-waitfalseApply the resources without waiting for the services to become ready.

Flow: preflight (doctor) → create/reuse the cluster → wait for the Kubernetes API → apply the services → wait for readiness → print the summary.

Terminal window
pyahu up
pyahu up --skip-wait
pyahu up --output json

Human output at the end:

Pyahu local stack is ready
cluster: pyahu-local
namespace: pyahu-local-dev
kubeconfig: /home/user/.config/k3d/kubeconfig-pyahu-local.yaml
POSTGRES_URL postgresql://pyahu:hidden@localhost:5432/app?sslmode=disable
POSTGRES_PASSWORD <hidden>
ZITADEL_ISSUER https://zitadel.localhost
...
next: eval "$(pyahu env)"

The up summary redacts passwords, tokens, private keys, and credentials inside URLs in both human and JSON output. Use the explicit pyahu env command when an application needs the real connection values.

Removes the local Pyahu resources.

FlagDefaultDescription
--keep-clusterfalseRemove only the stack namespace and keep the k3d cluster.
--purge-datafalsePermanently delete retained local storage after removing the cluster.
--yesfalseConfirm --purge-data without an interactive prompt.
Terminal window
pyahu down # deletes the entire k3d cluster
pyahu down --keep-cluster # keeps the cluster, removes the namespace
pyahu down --purge-data --yes # also permanently deletes retained local data

By default, cluster data remains under ~/.pyahu/clusters/<cluster>/storage so teardown never silently deletes host files. Pyahu prints the retained path. --purge-data is irreversible, cannot be combined with --keep-cluster, and requires confirmation; scripts and --no-input runs must pass --yes.

Checks dependencies and local ports before bringing up the stack. Works even without a stack file (it uses defaults for the check).

Terminal window
pyahu doctor
pyahu doctor --output json

It checks:

  • k3d installed on the PATH
  • Docker or Podman running
  • Other local clusters (k3d/Kind): warning only, does not fail
  • Availability of the host ports for the enabled services (when the cluster does not exist yet)
k3d ok k3d is installed
container-runtime ok docker is available
local-clusters ok no other local Kubernetes clusters detected
port:postgres ok 127.0.0.1:5432 is available
host ok linux/amd64

Shows the state of the cluster and of each service, including the pods.

Terminal window
pyahu status
pyahu status --output json
cluster: pyahu-local
namespace: pyahu-local-dev
postgres ready 1/1 ready
zitadel ready 1/1 ready
kafka waiting starting

Lists the enabled services, their state, and local endpoints. Aliases: svc, ls.

Terminal window
pyahu services
pyahu svc
pyahu services --output json
cluster: pyahu-local
namespace: pyahu-local-dev
state: running
SERVICE STATUS VERSION ENDPOINTS
postgres ready 18.4 localhost:5432
zitadel ready v4.15.2 https://zitadel.localhost
rabbitmq ready 4.3.2 localhost:5672, https://rabbitmq.localhost
redis ready 8.1-alpine localhost:6379
kafka ready 4.3.0 localhost:9092
kafka-connect ready 3.5.2 http://localhost:8083
kafka-ui ready v1.5.0 https://kafka-ui.localhost

Details for a service: status, endpoints (host + in-cluster), environment variables, config details, and pods.

Valid services: postgres, zitadel, rabbitmq, redis, kafka, kafka-connect, kafka-ui.

FlagDefaultDescription
--show-secretsfalseShow secret values in the human output (masked by default).
Terminal window
pyahu describe postgres
pyahu describe zitadel --show-secrets
pyahu describe kafka-connect --output json

Streams a service’s logs.

FlagDefaultDescription
--followfalseFollow the logs in real time.
--tail100Number of initial lines to show.
Terminal window
pyahu logs postgres --tail 50
pyahu logs zitadel --follow
pyahu logs kafka-connect --tail 200

Prints the connection variables for local apps.

FlagDefaultDescription
--formatshellshell (with export), dotenv, or json.
Terminal window
pyahu env # export VAR='value'
pyahu env --format dotenv # VAR=value
pyahu env --format json
eval "$(pyahu env)" # loads into the current shell

The variables cover each enabled service, for example POSTGRES_URL, RABBITMQ_URL, REDIS_URL, KAFKA_BOOTSTRAP_SERVERS, KAFKA_CONNECT_URL, ZITADEL_ISSUER.

Prints the path of the local cluster’s kubeconfig.

FlagDefaultDescription
--rawfalseWrite the kubeconfig content to stdout instead of the path.
Terminal window
pyahu kubeconfig
pyahu kubeconfig --raw > kubeconfig.yaml
export KUBECONFIG="$(pyahu kubeconfig)"

Runs a real PostgreSQL dump on the primary pod straight into a file on the host (pg_dump --format=custom). Without [database], it uses the first configured database.

FlagDefaultDescription
--dir.pyahu/backupsHost directory for the .dump file.
Terminal window
pyahu backup postgres app --dir ./backups
pyahu backup postgres # uses the first configured database

The file is named <stack>-<database>-<YYYYMMDD-HHMMSS>.dump (UTC).

Restores a custom PostgreSQL dump from a local file or from s3://.

FlagDefaultDescription
--source— (required)Path to the .dump file or s3:// URI.
--s3-endpoint-url—S3-compatible endpoint for s3:// sources.
--cleantrueRemove matching objects before restoring.
--yesfalseConfirm the destructive restore without a prompt.
Terminal window
pyahu restore postgres app --source ./backups/pyahu-local-app-20260622-131500.dump
pyahu restore postgres app --source s3://my-bucket/dev/app.dump --yes
pyahu restore postgres app \
--source s3://bucket/app.dump \
--s3-endpoint-url http://localhost:9000 \
--yes

Registers the connectors declared under services.kafkaConnect.connectors and waits for their tasks to reach RUNNING.

Run it after the application that owns a connector’s source has booted at least once: an outbox connector reads a table, publication, or stream that does not exist on a fresh cluster. The command is idempotent — it re-applies the Secret and recreates the registration Job.

FlagDefaultDescription
--name(all)Apply only the connector with this name.
Terminal window
pyahu connectors apply
pyahu connectors apply --name checkout-outbox

A successful, waiting pyahu up also reconciles connector ownership. It records the connector names managed by this stack and deletes a previously managed registration after its name is removed from pyahu.yaml. Connectors created manually against the same worker are not in that inventory and are left alone. The inventory is kept if Kafka Connect is temporarily disabled, so it can be used safely when the service is enabled again.

Shows the state of each connector and of each task.

FlagDefaultDescription
--formathumanhuman or json.
Terminal window
pyahu connectors status
pyahu connectors status --format json
CONNECTOR TASK STATE DETAIL
allpick-core-outbox - RUNNING source
0 RUNNING -
checkout-outbox - RUNNING source
0 FAILED ERR no such key

The command exits non-zero when any task is not RUNNING, or when a connector has no tasks at all.

A connector whose source only exists after the application boots carries optional: true:

services:
kafkaConnect:
connectors:
- name: checkout-outbox
kind: custom
optional: true
config:
connector.class: com.redis.kafka.connect.RedisStreamSourceConnector

With optional: true, a registration that does not become healthy during pyahu up is reported as a warning in the summary instead of an error — up stays green and you run pyahu connectors apply after the first boot. Without optional, the failure fails up, which is the right behavior for a connector whose source should already exist.


Shows the state of the local CA, the wildcard certificate, and the host trust.

Terminal window
pyahu certs status
pyahu certs status --output json
local CA: ~/.config/pyahu/certs/ca.crt
CA status: valid until 2036-06-19
host trust: trusted
certificate: .pyahu/local/certs/localhost.crt
cert status: valid until 2027-07-24
domains: *.localhost, localhost, zitadel.localhost

Installs the local Pyahu CA into the host’s trust store. On macOS it may prompt for a password. After that, curl and browsers accept https://zitadel.localhost (and the other *.localhost UIs) without warnings.

Terminal window
pyahu certs trust

Regenerates the local CA and the wildcard certificate. Run pyahu certs trust and pyahu up afterward to re-trust the CA and update the TLS Secret in the cluster.

Terminal window
pyahu certs rotate
pyahu certs trust
pyahu up

More context in Local certificates.


Generates the autocomplete script. Supported shells: bash, zsh, fish, powershell.

Terminal window
pyahu completion zsh > "${fpath[1]}/_pyahu"
pyahu completion bash | sudo tee /etc/bash_completion.d/pyahu > /dev/null
pyahu completion fish > ~/.config/fish/completions/pyahu.fish

Almost all read commands support --output json:

Terminal window
pyahu doctor --output json
pyahu status --output json
pyahu services --output json
pyahu describe postgres --output json
pyahu env --format json
pyahu certs status --output json

When a newer release exists, the CLI prints a notice at the end of any command:

⚠ pyahu x.y.z is out of date — a.b.c is available
pyahu upgrade
curl -fsSL https://cli.pyahu.io/install.sh | sh
https://github.com/pyahu/cli/releases/tag/va.b.c
silence this with PYAHU_NO_UPDATE_CHECK=1

The suggested command follows how you installed it — the CLI reads its own binary path: under the mise install tree it becomes mise use github:pyahu/cli@<version>, under GOBIN/GOPATH it becomes go install, and otherwise the install script.

The notice goes to stderr, never stdout: eval "$(pyahu env)" and --output json consume stdout, and a banner there would be evaluated as shell or break the JSON.

It stays silent when:

SituationWhy
--output json or --quietthe output is read by a script
Locally built binary (version dev)there is no version to compare
PYAHU_NO_UPDATE_CHECK is setexplicit opt-out; it does not even reach the network
Offline, behind a proxy, or GitHub API rate limitedthe check fails silently

The lookup runs alongside the command and the answer is cached for 24h in <config dir>/pyahu/version-check.json, so it costs no wall-clock time: the command never waits more than 700ms for it, and the next day the answer is already on disk.

Asks the releases endpoint directly — it does not go through the 24h cache behind the passive notice.

FlagDefaultDescription
--exit-codefalseExit 1 when a newer release is available (for scripts/CI).
Terminal window
pyahu check-update
pyahu check-update --output json # {"current":"x.y.z","latest":"a.b.c","outdated":true}
pyahu check-update --exit-code # 0 = up to date, 1 = a newer release exists

It exits 0 by default even when behind: being out of date is not a command failure. Anyone who wants to fail a pipeline over it asks for --exit-code, in the spirit of git diff --exit-code.

Downloads the release, verifies its SHA-256 against the published checksums.txt, and swaps this binary for the one inside the archive.

FlagDefaultDescription
--yesfalseReplace without prompting.
--version(latest)Install a specific version — this is also how you roll back.
Terminal window
pyahu upgrade
pyahu upgrade --yes
pyahu upgrade --yes --version v0.10.0 # install or roll back to a specific release

The new binary is written next to the current one and renamed over it: the swap is atomic on the same filesystem, and an interrupted download never leaves a half-written binary. On Unix the running process stays on the old inode, so upgrade itself finishes normally.

The other refusals, all before downloading anything: a locally built binary (version dev), Windows (a running executable cannot be replaced under it), and an install directory that is not writable — there the message already carries both ways out (sudo, or reinstall into ~/.local/bin).

Terminal window
pyahu init --preset platform
pyahu doctor
pyahu up
pyahu certs trust
pyahu services
eval "$(pyahu env)"
CommandBehavior
pyahu loginBrowser device authorization; saves the local session.
pyahu logoutDeletes the saved session.
pyahu kube listLists environments with enabled kubectl access.
pyahu kube config --env <name>Backs up kubeconfig, adds the Cloud context and selects it.
pyahu kube doctorReports session and environment access configuration.

See Pyahu Cloud access for the complete workflow.