Every deployment on Ownkube keeps its own set of environment variables, and any value you mark Secret is encrypted before it hits disk and masked in the dashboard the moment you save it. This guide covers adding variables, the difference between a runtime variable and a build-time argument, updating a value without triggering a rebuild, and wiring a database connection string into your app.
TL;DR
- Environment variables are set per deployment on the Settings tab:
KEY=valuepairs, each with a Secret toggle. - Plain values are stored as-is. Secret values are encrypted in Ownkube’s database and masked in the UI after you save, so you can rotate them but never read them back.
- Runtime variables are injected into the container when it starts. Saving triggers a rolling update, not a rebuild, so old containers drain once new ones pass health checks.
- Docker build arguments are a separate, build-time input on the deployment’s Builder tab. They apply on the next build, not the running container.
- Attach a database and Ownkube injects
DATABASE_URLand the individualPG*credentials as environment variables automatically. You never type them in by hand.
How variables are scoped
Variables belong to the deployment, not the environment. api @ Development and api @ Production keep independent sets, so a value you set on one has no effect on the other. That is deliberate: it keeps a staging API key from ever leaking into production by accident.
Ownkube does not yet have environment-level shared variables that every deployment in an environment inherits automatically. If you run three workers that all need the same LOG_LEVEL, you set it on each one today.
Step 1: open the deployment’s Settings tab
Go to the deployment in your dashboard and scroll to Environment variables. Every resource type that runs a container (web, worker, job, function) has this section.
Step 2: add a key and decide plain or secret
Click Add variable. Each row has a Key, a Value, and a Secret toggle.
NODE_ENV=production
LOG_LEVEL=info
STRIPE_API_KEY=sk_live_... # flip Secret on this one
Use plain text for anything you would not mind seeing in a screenshot: log levels, feature flags, region names. Flip Secret on anything else: API keys, tokens, third-party credentials, signing secrets.
If you are creating a fresh deployment rather than editing an existing one, the CLI takes plain variables inline:
okctl deploy create \
--name api \
--image ghcr.io/acme/api \
--tag v1.4.2 \
--port 3000 \
--env NODE_ENV=production \
--env LOG_LEVEL=info
Secret values are best set from the dashboard, where the Secret toggle handles encryption for you.
Step 3: save
Saving triggers a rolling update. New containers start with the updated environment, and old ones keep serving traffic until the new ones pass their health checks, then drain. There is no separate “apply” step and no downtime window to schedule.
Step 4: confirm it landed
Open the Logs tab and check that your process picked up the new value (a log line at boot, a /health response that echoes the version, whatever your app already reports). Secret values are redacted in the log stream regardless of how your app logs them, so you will not see the raw value there either way.
Build-time arguments versus runtime variables
These are two different inputs and it is worth being precise about which one you need.
A runtime environment variable (the ones from Step 2) is injected into the container when it starts. Your process reads it with process.env, os.environ, or the equivalent. Change it and the next rolling update picks it up, no rebuild required.
A Docker build argument is a separate, build-time-only input on the deployment’s Builder tab, alongside builder size and the root directory. It feeds an ARG in your Dockerfile and only affects the image while it is being built:
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
Set SENTRY_RELEASE=v1.4.2 as a build argument, and it bakes into that build’s image. Changing a build argument does not touch the running container. It applies on the deployment’s next build, triggered by a new push or by clicking Rebuild on the deployment page.
The rule of thumb: if a running process needs to read the value, it is a runtime variable. If only the build step needs it (a version string baked into a bundle, a flag that changes which dependencies get compiled in), it is a build argument.
Updating a value without a rebuild
This is the common case: rotating a third-party API key. Rotate it at the provider first, then paste the new value into the existing Secret entry on Ownkube and save. That save triggers a rolling update, not a rebuild, so it typically lands in under a minute and the image never changes. Nothing about your container image, your build pipeline, or your deploy history is touched, only the environment the next set of containers starts with.
Pulling in a database connection string
Attach a database deployment to a web or worker deployment, and Ownkube generates the connection string and injects it as environment variables on that deployment automatically:
DATABASE_URL=postgresql://user:pass@host:5432/dbname
PGHOST=...
PGPORT=5432
PGUSER=...
PGPASSWORD=...
PGDATABASE=...
You do not create these entries yourself and you do not paste a password anywhere. If the database’s credentials rotate, the new values are picked up automatically on the next rollout, the same rolling-update path as any other variable change.
How secrets are actually protected
- At rest: encrypted in Ownkube’s database and held in the runtime secret store, not in the deployment’s plain config.
- In transit: only ever travel over TLS.
- In the UI: masked after save. A short prefix stays visible so you can tell which value is which without exposing the rest.
- In logs: the structured logger redacts any variable with the Secret flag set, so a stray
console.logofprocess.envwill not print it back to you.
Ownkube never shows a saved secret value in plain text again. If you lose track of what you entered, rotate it rather than trying to recover it.
FAQ
Can I see a secret value again after I save it?
No. Once saved, a Secret entry is masked permanently in the UI. If you need to confirm a value or hand it to a teammate, rotate it and share the new value out of band.
Do I need to redeploy manually after changing an environment variable?
No. Saving a runtime variable triggers the rolling update automatically. There is nothing else to trigger.
If I change a build argument, when does it take effect?
On the deployment’s next build, not immediately. Trigger one with a new push, or click Rebuild on the deployment page if you want it to apply without waiting for a commit.
Can I set a variable once and have every deployment in an environment inherit it?
Not yet. Environment-level shared variables are not available today; each deployment keeps its own independent set.
Are database credentials rotated automatically?
Yes. Ownkube manages database credential rotation, and the new values reach your app as environment variables on the next rollout, with no manual copy-pasting.
Where Ownkube fits
If you have spent time reconciling a .env file against three different dashboards, per-deployment variables with a real Secret flag are a small thing that removes a surprising amount of friction: one place to set a value, one save that rolls out safely, and a database URL you never type by hand. The same deployment, secrets and all, can later move into your own AWS account with no rewrite if you outgrow Ownkube-managed compute; see our comparison of Railway, Render, and Northflank for how that portability compares across platforms, or our breakdown of self-hosted PaaS options if you are weighing the tradeoffs more broadly. Deploy your first app.