Key concepts
How the Portabase CLI works — component folders, generated compose, interactive mode, secrets and exit codes.
Component folders
Every create command produces a folder. All the other commands take that folder as their first argument (use . if you are already inside it).
my-agent/
├── .env # EDGE_KEY, TZ, POLLING, LOG_LEVEL, credentials of managed databases…
├── databases.json # Databases the agent backs up (mounted as /config/config.json)
├── docker-compose.yml # Generated by the CLI — do not edit
├── docker-compose.override.yml # Optional — your own customisations (never touched by the CLI)
└── docker-compose.legacy.yml # Only if you upgraded: backup of the hand-made composeThe CLI recognises the kind of folder automatically: a folder with a databases.json is an agent, a folder whose .env contains PROJECT_SECRET is a dashboard.
docker-compose.yml is generated
The source of truth is .env (plus databases.json for an agent). docker-compose.yml is re-rendered from it by:
agent create,agent set,agent unset,agent db add,agent db removedashboard create,dashboard set,dashboard unset,dashboard auth add,dashboard auth removebuild
A generated file starts with the header # Generated by Portabase CLI <version>. Do not edit.
Never edit docker-compose.yml by hand
Any change you make directly in docker-compose.yml is lost the next time one of the commands above runs. Put your customisations (extra labels, networks, resource limits, ports…) in a docker-compose.override.yml next to it — Docker Compose merges it automatically, and the CLI never touches it.
If the CLI finds a docker-compose.yml it did not generate (an installation made with an older CLI, or a hand-written file), it first copies it to docker-compose.legacy.yml and warns you. Use portabase build <PATH> --diff to preview the change without writing anything.
Values in the compose file are ${VAR} references resolved from .env, so secrets stay in .env only (unless you explicitly use build --inline-env).
Interactive and non-interactive modes
By default the CLI asks for anything you did not pass as a flag. It switches to non-interactive mode when:
- the global
--non-interactiveoption is set, or - the environment variable
PORTABASE_NON_INTERACTIVEis1,trueoryes, or - standard input is not a terminal (CI job, pipe,
ssh host 'portabase …'without-t, cron…).
Passing secrets safely
Every secret flag has a -stdin twin that reads the value from the first line of standard input, so it never appears in your shell history or in ps:
| Secret | Visible flag (discouraged) | Safe flag |
|---|---|---|
| Agent Edge Key | --key | --key-stdin |
| Password of an existing database | --password | --password-stdin |
| Dashboard custom DB password | — | --db-password-stdin |
| Dashboard initial user password | --admin-password | --admin-password-stdin |
| OIDC / OAuth client secret | --secret | --secret-stdin |
printf '%s\n' "$EDGE_KEY" | portabase agent create my-agent --key-stdin --yesEach -stdin flag consumes one line of standard input. Use a single -stdin flag per command to avoid mixing up values.
Non-interactive examples
Complete, prompt-free commands for CI jobs and scripts.
printf '%s\n' "$EDGE_KEY" | portabase agent create my-agent \
--key-stdin --tz Europe/Paris --polling 10 --log-level info \
--no-host-gateway --yes --start
portabase agent db add my-agent --engine postgresql --mode new
portabase restart my-agentApplying changes
Commands that change a component (set, unset, db add, db remove, auth add, auth remove) only write files. Apply them with portabase restart <PATH>, which also creates any container added since the last start.
Exit codes
| Code | Meaning |
|---|---|
0 | Success. |
1 | Generic or unexpected error (re-run with --verbose to get the traceback). |
2 | Invalid input: unknown command, bad flag, missing value, validation failure. |
3 | Configuration error: not a Portabase folder, invalid databases.json, missing file. |
4 | Docker error: Docker missing, daemon not running, docker compose failed. |
5 | Template error (broken build or wrong PORTABASE_TEMPLATES_DIR). |
6 | Network error. |
7 | Update error (download, checksum, installation). |
130 | Canceled by the user (answered "no", Ctrl+C, or a refused confirmation). |
Last updated on