Skip to content

CLI ​

zenavo deploys and operates your projects from a terminal or from CI. It talks to the REST API with an API key, and its commands follow Zeabur's CLI (auth, workspace, context, project, service, deployment), so moving over is easy.

Install ​

Build it from the zenavo-cli repository with Go 1.26 or later:

sh
make build            # ./zenavo for this machine
make dist             # dist/zenavo_<os>_<arch> for macOS, Linux and Windows, with SHA256SUMS

Sign in ​

sh
zenavo auth login                          # shows a code and opens <console>/device
zenavo auth login --with-token < key.txt   # an existing API key, read from stdin
zenavo auth status                         # who you are signed in as

auth login shows a code and opens the console's /device page: sign in, type the code and approve. Check the device name and network the page shows before approving. Over SSH, open the printed address on any device. The CLI then gets its own API key, named "CLI on <computer>" and valid for 90 days.

The key is saved in ~/.config/zenavo/config.json (or $ZENAVO_CONFIG) with mode 0600, and is sent only to the console it was created for. auth logout forgets it locally; delete it under API Keys to revoke it.

For a self-hosted control plane, add --api https://console.example.com.

CI and scripts ​

Set ZENAVO_TOKEN to an API key (and ZENAVO_API_URL when it is not https://zenavo.app) instead of signing in, and pass -i=false so no command prompts. --json prints JSON on stdout for jq; progress goes to stderr. A followed job that fails exits with status 1.

sh
export ZENAVO_TOKEN=zv_pat_…
zenavo deploy web -p blog -i=false

Context ​

zenavo team switch and zenavo context set project|service save the team, project and service that later commands use. --team (or --workspace), --project/-p and --service/-s override them for one command. Without a saved or given project or service, the CLI uses the only one, asks when it can, and otherwise says what to pass.

Quick tour ​

sh
zenavo team ls                                # your teams; * marks the current one
zenavo team switch acme
zenavo project create blog --git https://github.com/acme/blog
zenavo env set PORT=3000 DATABASE_PASSWORD    # a bare KEY asks for the value without echo
zenavo deploy                                 # every service; follows the build log
zenavo deploy web                             # one service; the others stay as deployed
zenavo service ls                             # state, readiness, restarts, CPU and memory
zenavo logs web -f                            # live runtime logs
zenavo logs --build                           # the latest build and deploy log
zenavo domain add blog                        # blog.zenavo.app, or a full domain of your own
zenavo rollback                               # pick an earlier successful deployment
zenavo template deploy -f zeabur.yaml --var DOMAIN=blog

Commands ​

CommandWhat it does
auth login | logout | statusSign in through the browser or with an API key; forget the key; show who you are
team ls | current | switch | clearTeams (alias workspace). Switching clears the saved project and service
context show | set project | set service | clearThe defaults later commands use
server ls | getThe team's servers. Add servers in the console
project ls | get | create | deleteProjects. create --git <url> or --image <image> adds a first service; delete asks you to type the name
service ls | deploy | restart | suspend | resume | execServices. exec -- <command> runs in the container with sh -c, for up to 60 seconds
deploy [service]Deploy the project or one service and follow the build. --detach returns at once
logs [service] [-f] [--build]The last 200 runtime log lines, streamed with -f; --build prints the latest build log
job ls | get | log | waitJobs: deploys, restarts, backups (alias deployment)
rollback [job-id]Roll the project back to an earlier successful deployment
env ls | set | unsetVariables of a service. Values stay hidden unless --reveal; set --file .env; --deploy deploys after saving
domain ls | add | rmA name without dots (blog) gets a generated domain; a full name is your own domain
template deploy -f <file>Create a project from a Zeabur template (YAML) or a Zenavo export (JSON); --var KEY=value, --deploy
backup ls | createBackups. create --engine postgres|mysql|volume:<id>. Download and restore them in the console
versionThe CLI's version

Every command takes --help.

Not in the CLI yet ​

Adding and setting up servers, team management, the GitHub App, and downloading or restoring backups are done in the console.

Not affiliated with Zeabur.