Multi-stack deploys
An OwnStack app can deploy to one stack or many. The shape is the same — same Procfile, same buildpack, same release task — but each stack is its own running instance with its own dokku state, scale, logs, and (optionally) its own per-stack config overrides.
Why deploy to multiple stacks
- Staging + production — cheap stack for pre-merge testing, beefier stack for prod.
- Primary + failover — same code, different region; flip DNS if the primary goes down.
- Active-active — multiple regions serving traffic via a global load balancer (the cloud provider's, or your DNS-based one).
- Multi-tenant isolation — one app codebase, many stacks, each holding a different customer's data.
Add or remove stacks
$ ownstack app stacks <app>
$ ownstack app stacks:add <app> <stack-name>
$ ownstack app stacks:remove <app> <stack-name>
Each new target gets its own dokku app on the new stack on the next deploy. Removing a target stops deploys to that stack but leaves the dokku app and data in place — destroy them via ssh dokku@<stack-ip> apps:destroy if you don't need them.
One deploy, many jobs
A single ownstack deploy enqueues one deployment job per stack. They run in parallel. Each has its own status, log, and SHA tracking:
$ ownstack deploy
Triggering deploy for app 47…
✓ Deploy started on prod-east (job 1024)
✓ Deploy started on prod-west (job 1025)
$ ownstack app info
Stack: prod-east — deployed abc1234
Stack: prod-west — deployed abc1234
If one job fails, the others keep going. The dashboard Deployments tab shows mixed status. Re-deploy just the failed stack with --stack=<name>.
Per-stack config
App-level config vars apply to every stack. For values that differ per stack — different external API URL in staging, different region indicator — set them at the stack level:
$ ownstack config:set --app=<app> --stack=prod-east REGION=us-east-1
$ ownstack config:set --app=<app> --stack=prod-west REGION=us-west-2
Stack-level vars override app-level vars on that stack only.
Per-stack scaling
Scale state is per-stack. Larger region runs more workers; a hot-spare runs zero. See Scaling.
Per-stack databases
By default, each stack gets its own postgres/mysql/redis service. Two ways to share data across stacks:
- External DB — point
DATABASE_URLat a managed RDS / Cloud SQL / etc. instance reachable from all stacks. Setneeds_postgres: falseon the app so OwnStack stops auto-creating per-stack services. - Replicate — use
ownstack app replicateto make a sibling app that shares DB and Redis with the source. Useful for blue-green within a stack.
DNS in front of multiple stacks
OwnStack doesn't run a global load balancer. Either:
- Use the cloud provider's LB (AWS ALB/NLB, GCP HTTP LB, Cloudflare Load Balancing) and target each stack as an origin.
- Use weighted DNS records (Route 53, DNSimple, Cloudflare) — split traffic by record weight, fail over with health checks.
Each stack independently terminates SSL with its own Let's Encrypt cert.
Read next
- Pipelines — staging → production promotions.
- Scaling
- Domains & SSL