Git deploys

The default deploy path. ownstack deploy hands your repo to the control plane, which pushes it to the stack via SSH, and dokku builds the image using a buildpack (or your Dockerfile) on the stack itself.

Trigger a deploy

$ ownstack deploy                          # linked app, all its stacks
$ ownstack deploy <app>                     # a specific app
$ ownstack deploy --stack=<stack>           # one stack only
$ ownstack deploy --wait                    # stream the build log

Without --wait, the CLI returns once the deploy is queued; check status with ownstack remote deploy-log or in the dashboard.

What happens on the stack

  1. The control-plane worker connects to the stack as dokku@<stack-ip> via the stack's stored SSH key.
  2. It runs dokku apps:create if the app doesn't exist yet (idempotent).
  3. It pushes your repo (specifically the configured branch — usually main) to the stack's dokku git endpoint.
  4. Dokku triggers the build: detects Procfile, runs the buildpack, builds a docker image.
  5. Release task runs (release: bundle exec rails db:migrate, etc.).
  6. Healthchecks run on the new container; on success, traffic rotates.

What's on the wire

The control-plane worker uses git push --force-with-lease to the stack — your branch tip becomes the stack's main ref. The stack does not pull from GitHub; the control plane is the bridge. This means:

  • Private repos work without giving the stack any GitHub credentials.
  • Submodules need to be reachable from the control plane (not the stack).
  • Local commits work as long as you've pushed them to your origin first — the control plane reads from your origin.

Submodules

Submodules are fetched by the control plane during the deploy. They must be reachable using the configured deploy credentials. SSH submodule URLs (git@github.com:org/private.git) require an SSH key registered with the control plane account; HTTPS URLs work without extra config.

The Procfile is required

Every git-deployed app needs a Procfile at the repo root with at least a web entry. Without it, the build succeeds but no process runs and healthchecks fail. See Procfile.

Build log

$ ownstack remote deploy-log                      # latest deploy
$ ownstack remote deploy-log --deployment=412     # a specific one
$ ownstack remote deploy-log --follow             # live-stream

Common gotchas

SymptomLikely cause
Failure during app buildBuildpack mismatch, missing dependency, version pinning. More.
Execution of release task failedRelease task ran but exited non-zero. db:migrate against a missing or unreachable DB is the most common cause.
port listening check: unable to enterWeb process doesn't bind to $PORT.
Name is already taken on apps:createHarmless — dokku saying the app exists. Deploy continues.