Variables
Project, service, and env-group keys; per-environment overlays; matrix; references; and Share to project — not deployment stages.
Scopes
| Scope | Where | Use for |
|---|---|---|
| Project | Project → Variables | Shared defaults inherited by every service in the active environment |
| Env group | Project → Env groups | Named bundles (e.g. backend) attached to selected services |
| Service | Service → Variables | Overrides and service-only secrets for that service instance |
Sensitive values are encrypted at rest. Prefer service or group scope for credentials that must not leak across unrelated services.
Naming: A Bytstack workspace is billing/team membership — not an env scope. Do not say “workspace env” when you mean Variables. Named stages (testing / staging / production) are deployment environments — Values overlay per environment.
Per-environment overlays
When deployment environments are enabled, the same key names exist across stages, but values are stored per environment (?environment= on project/group APIs). The header switcher (or CLI bytstack environment select) picks which overlay you edit.
Matrix
Project → Variables shows a matrix: rows = keys in the selected scope (project or a group), columns = persistent environments. Cells show masked secrets, value previews, or empty (needs a value). Click a cell to edit that environment only.
After Duplicate, a banner lists blank secrets on the new stage — fill them before expecting the app to boot.
Merge precedence
At deploy / runtime merge (lowest → highest wins):
- Platform inject (
PORT,DATABASE_URL,BYTSTACK_*, …) - Project variables (for the current environment)
- Attached env groups (oldest attachment first when keys collide across groups)
- Service variables
- Resolved references
${{…}}(fail closed if unresolved)
Changing project, group, or service env that requires a new process typically queues an env_change redeploy for affected services only.
Draft editor (batch apply)
With env_draft_editor enabled, Project / Service / Group Variables pages use a draft:
- Edit rows in place (click to edit; secrets support Reveal or write-only set).
- Paste .env → preview add/update/unchanged → Add to draft.
- Save N changes once → one redeploy confirm → one deploy per affected service.
If a deploy is already running, env is still saved and redeploy is queued until that deployment finishes (you will not see a false “redeployed” toast).
CLI equivalent: bytstack env push --dry-run then bytstack env push --overwrite.
Env groups
Attachable groups (flag: env_groups) let api + worker share STRIPE_SECRET without putting it on web.
Typical flow:
- Create group
backendon the project. - Set keys on the group for the active environment.
- Attach to api and worker.
- Edit a group var → only attached services redeploy.
Dashboard: Project → Env groups. CLI: bytstack env groups … (CLI).
Plan caps
| Plan | Max groups per project |
|---|---|
| Free | 1 |
| Starter | 5 |
| Pro | 25 |
See Pricing & limits.
References
When env_references is enabled, values may reference other scopes in the same project and same deployment environment:
| Syntax | Resolves to |
|---|---|
${{project.KEY}} | Project env (this environment) |
${{group.name.KEY}} | Env group variable (this environment) |
${{service.name.URL}} | Service public URL in this environment (and similar bindables) |
${{database.name.URL}} | Managed database URL in this environment |
${{self.URL}} | Current service URL |
Rules:
- Project-scoped only — no cross-project refs.
- In-environment —
${{service.api.URL}}never resolves to another stage’s host. - Cycles and missing targets fail the deploy (
env_reference_unresolved/env_reference_cycle). - Prefer public prefixes (
NEXT_PUBLIC_*,VITE_*) when the browser must see a URL.
Share to project
Share to project copies a service key up to the project overlay (optional delete of the service copy). Use when a value started as service-local and should become the stack default for that environment. Redeploys all services in the project for that environment.
POST /v1/services/:id/env/:key/promoteThis is not environment Promote (image digest between stages). CLI:
bytstack env promotevsbytstack environment promote.
Build-time vs runtime
| Service type | When vars are applied |
|---|---|
| Static | Build time — baked into the asset bundle. Changing env triggers a rebuild. |
| Web / worker / cron | Runtime injection (and during image build when a build step runs) |
Services with bake env at build may rebuild on Promote so the target environment’s values are applied.
Public / client prefixes
Values that must ship to the browser are available at build time for frameworks that inline them. Treat public prefixes as non-secret.
Platform-injected vars
Do not set these yourself unless you know why:
| Variable | Meaning |
|---|---|
PORT | HTTP listen port for web services |
NODE_ENV | Typically production |
DATABASE_URL | Internal DB URL when a managed database is attached |
BYTSTACK_SERVICE_ID | Current service id |
BYTSTACK_DEPLOYMENT_ID | Current deployment id |
BYTSTACK_APEX_HOST | Apex host for path-based SaaS routing |
BYTSTACK_API_PATH | API path prefix when using path split |
BYTSTACK_EDGE_TARGET | Edge routing target metadata |
See Platform reference.
Compose secrets
Monorepo import may detect Postgres in docker-compose.yml and offer managed Postgres. Compose passwords, Redis URLs, and other compose secrets are never written to the env store or audit payloads. Use platform DATABASE_URL after accepting the offer — see Monorepos.
CLI
bytstack environment select staging # which overlay for project-scoped env
bytstack env list --scope project
bytstack env set KEY=value
bytstack env pull --scope project --file .env.staging
bytstack env push --scope project --overwrite --yes
bytstack env groups list
bytstack env groups create backend
bytstack env groups set backend STRIPE_KEY=sk_…
bytstack env groups attach backend apiNaming tips
- Use conventional names (
DATABASE_URL,REDIS_URL) so frameworks pick them up. - Managed Redis injects the first instance as
REDIS_URL(per environment). Extra instances useREDIS_URL_<LOGICAL_KEY>unless you set a customenvKey. Prefer${{redis.<logicalKey>.REDIS_URL}}when a service should pin a specific instance. Guide: Redis. - PR preview environments do not get a dedicated Redis. If preview services still reference staging Redis /
REDIS_URL, treat keys as non-secret or omit Redis for previews. - Never commit secrets to git — store them in Bytstack Variables.
- For cross-service URLs prefer
${{service.api.URL}}over hard-coded hosts (same environment only).
Deployment environments
Testing → staging → production stages under a project — Duplicate, Promote, protected production, and how they differ from Variables.
Monorepos
Detect deployable packages, bulk-import a stack into one project, choose build modes, and use path filters — without running docker-compose on the platform.