OmniArc docs Menu

Guides

Branches

A branch is a full copy of an arc: every service, a copy of its data, and an address of its own. Use one to review a pull request against real-shaped data, rehearse a migration, or hand someone a demo they cannot break.

# Create one

omniarc arc branch create shop production preview --wait-url

The arguments are the arc, the branch to copy, and the new branch's name. The name takes lowercase letters, digits and hyphens, starting with a letter and ending with a letter or digit, at most 40 characters. The parent can be production or any other branch, so a branch of a branch works the same way.

It prints what it copied, what it anonymized, and the branch's address:

shop/production → shop/preview
anonymized  db: 1 rule(s), 2 row(s)
url  https://<hex>.arc.omniarc.eu (pending)
waiting for the URL to serve (up to 180 s)...
url  https://<hex>.arc.omniarc.eu (ready)

A new address takes a few minutes to serve, while its certificate is issued. --wait-url waits for it, for up to three minutes. Without it the command returns as soon as the branch exists; ask for the address later with:

omniarc arc branch url shop preview

# What a branch gets

  • Every service, run from the same release its parent runs.
  • A copy of every volume. It starts out sharing the parent's data on disk, so a branch of a large database is made in one step and uses room only for what it changes. A writable bind mount inside your project (./data:/var/lib/postgresql/data) is kept with the arc and copied the same way.
  • Anonymized personal data. A service with contains_pii: true has its anonymize rules run against the branch's copy before the branch can be reached. If a rule cannot be applied, the branch is not created.
  • Empty services where you said so. A service with branch: false starts empty, its volumes and writable bind mounts emptied: a cache, or data you never want in a preview. Files your project had at such a path were copied in on the arc's first deploy only, so in the branch the path stays empty until the service writes to it. A service that is not deployed (deploy: false, or a profile that is not active) starts empty too, whatever its branch, and data no service binds any more is not copied.
  • The arc's .env, which every branch shares. See Env and secrets.

From then on the branch and its parent are independent. Nothing you write in preview reaches production.

A service that should flush its writes before it is copied, such as a database checkpoint, gets a quiesce command, which runs before every copy.

# Deploy new code to it

From your working copy, deploy to the branch instead of production:

omniarc deploy --branch preview

Its data stays; only the code and configuration change.

# A branch for every pull request

In CI, with OMNIARC_KEY set from your CI's secrets, when a pull request opens:

omniarc arc branch create shop production pr-42 --wait-url
omniarc deploy --branch pr-42

and when it closes:

omniarc arc branch destroy shop pr-42

Each command exits non-zero when it fails, so the job fails with it. A key with the member role can create and destroy branches; deploying needs admin.

# See them

omniarc arc show shop

Lists every branch with its parent, whether it is awake, and two sizes: USED, what the branch holds on its own, and REFERENCED, all the data it can see, shared data included.

# Sleep, wake and destroy

A branch you are not using can sleep: its services stop and its data stays. See Sleep and wake.

omniarc arc branch destroy shop preview

destroys a branch and its data. It cannot be undone, and it does not ask first.