Guides
Secrets & environment variables
Apps need configuration: API keys, feature flags, the URL of a database. Astrodock keeps the
variable names in your app.json and the values out of
your repo. This guide explains the two kinds of variables, how to set their values safely, and the
one golden rule that keeps secrets out of git.
Two kinds of variables
Every variable an app sees falls into one of two categories.
1. Reserved ASTRODOCK_* variables
These are injected by the platform. Your app only reads them — it never sets them, and
it may not declare them in app.json. Examples you've likely met already:
ASTRODOCK_PORT (the port your server must bind), ASTRODOCK_DATABASE_URL, and the
ASTRODOCK_STORAGE_* set. Astrodock fills these in from the app's resource modes and the stack config.
2. App-declared variables
These are the variables your app needs — say an OPENAI_API_KEY or a
FEATURE_FLAGS string. You list them in app.json by name only, and
supply the values out-of-band (via the CLI or dashboard), never in the repo.
The naming rule
Declared keys are UPPER_SNAKE_CASE and must not start with ASTRODOCK_ —
that prefix is reserved for the platform. Astrodock rejects declared keys that break either rule.
Declaring a variable in app.json
App-declared variables live under the env array. Each entry is metadata about a variable —
not its value:
{
"env": [
{ "key": "OPENAI_API_KEY", "secret": true, "required": true,
"description": "Used for the summarize endpoint" },
{ "key": "GREETING", "secret": false, "required": false, "default": "Hello",
"description": "Shown on the home page" }
]
}
| Field | Meaning |
|---|---|
key | The variable name. UPPER_SNAKE_CASE, not ASTRODOCK_*. |
secret | true = a sensitive value (encrypted at rest, masked on read). false = plain config. |
required | true = the app can't deploy until this has a value (or a default). |
default | A fallback value used when none is set. Non-secret variables only. |
description | A human note, shown in the dashboard's Env tab. |
The required-variable gate
Astrodock will not deploy an app while a required value is missing. The gate blocks a deploy until both of these are satisfied:
- Every
requiredapp-declared variable has a value (or a default), and - Every external-mode resource credential is set —
ASTRODOCK_DATABASE_URLfor an external database, and the fiveASTRODOCK_STORAGE_*keys for external storage.
If anything is missing, the CLI tells you exactly what — it doesn't make you guess:
Deploy blocked — set these first (astrodock set-secret KEY):
- OPENAI_API_KEY (required app variable has no value)
- ASTRODOCK_DATABASE_URL (required for external-mode resource)
Setting values with the CLI
The set-secret command sets a value for one variable. You can pass the value as an argument:
astrodock set-secret GREETING 'Welcome'
For anything sensitive, leave the value off and pipe it via stdin instead — that way the secret never appears in your shell history or process list:
printf '%s' 'sk-…your-key…' | astrodock set-secret OPENAI_API_KEY
Which app?
Run set-secret from your app's folder and it picks up the slug from app.json.
Otherwise pass the slug as the last argument: astrodock set-secret OPENAI_API_KEY 'sk-…' my-app.
Undeclared keys are treated as secret
If you set-secret a key that isn't in app.json, Astrodock stores it as a secret —
encrypted at rest and masked on read — so it can never be echoed back in cleartext.
Setting values in the dashboard
Open an app and go to its Env tab. You'll see every declared variable with its description, which ones are required, and whether each has a value yet. Set or update values there; secret values are masked once saved.
Encryption at rest
Secret values are encrypted at rest when ASTRODOCK_SECRET_KEY is set on the
stack (AES-256-GCM). This is strongly recommended — set it in your .env during
install. If it's unset, secrets are stored in plaintext and the control
plane warns you at boot.
Set ASTRODOCK_SECRET_KEY before storing real secrets
Generate one with openssl rand -hex 32 and put it in your .env. Do it up front —
it protects every secret you save afterward.
The golden rule
Never put secret values in app.json or git
app.json holds variable names and metadata only — never the values. Values
come in out-of-band via set-secret or the Env tab. Keep .env and any credentials
out of your repository.
Next steps
- Point an app at a managed database: External database
- Point an app at external file storage: External object storage
- Let the CLI and AI agents authenticate: API tokens
- All the fields in
app.json: App structure & app.json