Environment variables
Each stack owns a set of key/value variables, rendered to a .env file (mode
0600) next to its compose.yml. Reference them with ${KEY} interpolation,
or hand them all to a service with env_file: .env.
services: db: image: docker.io/library/postgres:${PG_TAG:-16} env_file: .env restart: unless-stoppedTwo behaviours: applied vs pending
Section titled “Two behaviours: applied vs pending”This is the part worth reading twice.
| Where you edit | What happens |
|---|---|
| Web UI (stack dialog) | Deploy writes the .env and recreates the containers in one step, on creation as on edit |
CLI / TUI (stack env set, TUI editor) |
Saved without redeploying. The stack is flagged ENV PENDING until you apply it |
A pending stack shows an ENV PENDING badge in the web UI and ✎ env pending
in the TUI. Apply it from the CLI (stack apply), the TUI (a), or the web
stack menu (✓ Apply changes). Reverting to the deployed values clears the
flag on its own.
Secrets
Section titled “Secrets”Variables whose name looks like a secret (*_PASSWORD, *_TOKEN, *_KEY)
are auto-flagged as secret. The flag can be toggled by hand.
- Secret values are never returned by the API (
nullinGET /api/stacks/{name}/env), masked instack env ls, and shown as•••••• (unchanged)in the web dialog. - Leaving a secret empty on submit keeps the stored value.
Importing an existing .env
Section titled “Importing an existing .env”| Interface | How |
|---|---|
| Web | Paste .env → Import |
| CLI | kaio-cli stack env import my-db .env |
| CLI (at deploy) | kaio-cli stack deploy my-db compose.yml --env-file .env |
CLI workflow
Section titled “CLI workflow”kaio-cli stack env ls my-db # secrets maskedkaio-cli stack env set my-db PG_TAG=16 POSTGRES_USER=appkaio-cli stack env set my-db POSTGRES_PASSWORD=s3cret --secretkaio-cli stack env unset my-db PG_TAGkaio-cli stack apply my-db # redeploy with the pending envTUI workflow
Section titled “TUI workflow”On the Stacks tab, select a stack and press e:
| Key | Action |
|---|---|
a |
Add a variable |
e / Enter |
Edit the selected variable |
d |
Delete |
s |
Toggle the secret flag |
w |
Save (as pending) |
q |
Close |
In the inline editor, Tab switches between key and value, Enter validates,
Esc cancels. Press a on the stack row to apply.
Verifying it worked
Section titled “Verifying it worked”Compose names the container <stack>-<service>-1 and the network
<stack>_default. For a stack my-db with a service db:
# 1. The variables reached the containerdocker exec my-db-db-1 env | grep POSTGRES_
# 2. Postgres answers (local socket connections are trusted, so this does not check the password)docker exec my-db-db-1 psql -U app -c 'select version();'
# 3. The password actually works, from the stack network like a sibling service woulddocker run --rm --network my-db_default docker.io/library/postgres:16 \ psql "postgresql://app:s3cret@db:5432/app" -c 'select current_user, now();'A wrong password fails with password authentication failed for user "app".
The generated file
Section titled “The generated file”The .env starts with a # Managed by kaio header and is overwritten
on every apply or deploy. Edit variables through Kaio, not on disk;
hand edits are lost at the next deploy.
Each stack version snapshots its environment, so a rollback restores the compose file and its variables together.
Kaio, built by Régis Gaidot