Operate
Environment and secrets.
Environment and secrets
Each app has one server-side environment store. Deploys inject its values into the app container. Values never live in the repository, the image, or shibumi-server.json.
Set values from the project#
bun ship:env set APP_ORIGIN=https://example.com [email protected]
bun ship:env import .env.production
bun ship:env list
bun ship:env rm OLD_KEY
set takes KEY=VALUE pairs. import reads a local .env file and sends its entries; the file itself stays local and uncommitted. list prints variable names only. Values are never printed after they are set.
Changes apply at the next deploy:
bun ship
Set values on the server#
printf 'RESEND_API_KEY=re_xxx\n' | shis env set example-com
shis env list example-com
shis env rm example-com OLD_KEY
shis env set reads KEY=VALUE lines from stdin, so values stay out of shell history and the process list. Input is capped at 1 MiB.
Storage and injection#
Values live in one file per app, ~/.config/shibumi-server/env/<app-id>.env, mode 0600 in a mode-0700 directory. Writes go through a temp file and rename, so a reader never sees a partial file.
At deploy, the server merges the store into the Compose override as literal environment values. The same injection runs on rollback and on the automatic restore after a failed health check, so a restored container keeps its configuration.
Rules#
- Keys match
[A-Z_][A-Z0-9_]*. - Values cannot contain newlines.
SHIBUMI_COMMITandSHIBUMI_DEPLOYED_ATare reserved. The server sets them at deploy andenv setrejects them.listshows names, never values.
What belongs here#
App configuration and secrets read by the app at runtime: origins, admin allowlists, API keys. Compose-level settings such as ports and volumes stay in the committed compose.yaml. Webhook secrets have their own store; see the security model.