OmniArc docs Menu

Referencearc.yaml reference

services

Generated from the code · as of CLI 0.6.0

One entry for each service in your compose project.

The keys are the compose service names, and compose and arc.yaml are matched by that name. Every service compose defines needs an entry, because OmniArc will not guess whether a service holds personal data. omniarc sync writes the missing entries for you, as guesses for you to review. A service that keeps data (a named volume, a writable bind inside the project, a database or cache image) gets contains_pii: true and branch: false, so branches start it empty; add anonymize rules, or set contains_pii: false for test data, to branch its data. A service that keeps nothing gets contains_pii: false.

An entry for a service compose does not define is refused too, which usually means a misspelling. A service name uses lowercase letters, digits, hyphens and underscores, starts with a letter, ends with a letter or digit, and is 40 characters or fewer, so compose's affine_migration is fine as it is. A service named My_DB has to be renamed in compose and in arc.yaml.

The file as a whole can be at most 64 KiB when you deploy. A real arc.yaml is a few KiB, so you meet this limit only if something has gone wrong.

services:
  web:
    kind: web-service
    contains_pii: false
  db:
    kind: database
    contains_pii: true
    quiesce: { exec: [psql, -U, shop, -c, CHECKPOINT], timeout_secs: 30 }
    anonymize:
      engine: postgres
      database: shop
      user: shop
      rules:
        - { table: users, column: email, transform: fake-email }
        - { table: users, column: ssn, transform: redact }
  cache:
    contains_pii: true
    branch: false
  mailhog:
    deploy: false

# Keys that no longer exist

These per-service keys were removed. Each is refused with a message that says where the setting went.

Old keyUse instead
routethe arc-level edge
resourcesthe arc-level resources. Per-container limits stay in compose
scaledormancy is set per arc in the dashboard. max is compose's deploy.replicas. quiesce is the per-service quiesce
datasetthe arc-level recordsize. Volumes need no declaration, because the whole arc is branched
ready_timeout_secsthe arc-level ready_timeout_secs
redact, or anonymize written as a listanonymize as a block with engine, database, user and rules

# services.*

What OmniArc needs to know about one compose service.

Only the keys on this page are accepted. Anything else is refused as an unknown key.

A service with deploy: false owes nothing else. Every other service must say whether it holds personal data with contains_pii.

# services.*.kind

What kind of service this is, which decides how its storage is tuned.

  • Type: string, one of the kinds below
  • Required: no
  • Errors: overlay-parse
KindFor
databaseA relational database such as Postgres or MySQL
documentA document store such as MongoDB
forgeA Git forge
cacheA cache such as Redis
objectS3-style object storage
web-serviceBackend code. Most compose services are this
frontendFrontend code

database, document and forge put the arc on a 16KiB block size unless you set recordsize yourself. With no kind, a service gets no class. If a service runs a database image, set kind: database: leaving it out keeps the 128KiB default, which makes a write-heavy Postgres noticeably slower.

# services.*.deploy

Whether OmniArc runs this service at all.

deploy: false means the service never runs on OmniArc. Use it for things that only make sense on a laptop, such as a mail catcher.

A deployed service that lists it under depends_on is refused, and so is an edge that points at it. A service with deploy: false cannot also set contains_pii, anonymize or quiesce, since none of them would ever apply.

# services.*.branch

Whether a branch of the arc gets a copy of this service's data.

With branch: false the service starts empty in every branch: its named volumes are emptied before it first starts there. Use it for a cache, or for data you never want in a preview.

A service that holds personal data and has branch: false needs no anonymize rules, because its data is never copied.

Two services that share a volume must agree on branch. Otherwise emptying the volume for one would empty it for the other too, and the file is refused. Give each its own volume.

# services.*.contains_pii

Whether this service holds personal data.

There is no default, and it is required for every deployed service. A service with no volume can still hold personal data, for example an app that writes uploads into its own filesystem, and a branch copies that too.

Write true or false. The YAML words yes, no, on and off, and a quoted "true", are not booleans here.

A service with contains_pii: true that branches must have anonymize rules. Otherwise real personal data would be copied into branches that developers and CI can reach.

# services.*.anonymize

How to remove personal data from this service's database when a branch is made.

Needed when contains_pii is true and the service branches. There is one database per service. The rules run against the branch's copy, and the original is never touched.

Only Postgres is supported. A service that holds personal data in anything else needs branch: false.

# services.*.anonymize.engine

The database engine of the service.

postgres is the only value. A service with another engine is refused unless it has branch: false, in which case the engine is not looked at.

# services.*.anonymize.database

The name of the database to anonymize.

Start with a letter or _, then use letters, digits, _, $ or -, up to 63 characters. It cannot be empty.

# services.*.anonymize.user

The database role OmniArc connects as.

Written the same way as database: a letter or _ first, then letters, digits, _, $ or -, up to 63 characters. OmniArc runs psql inside the service's container as this role.

# services.*.anonymize.rules

The columns to change and what to change them to.

At least one rule. Each rule names a table, a column and a transform. List every column that holds personal data. If a rule cannot be applied, the branch is not created, so no half-anonymized copy is ever reachable.

# services.*.anonymize.rules[].table

The table to change.

Letters, digits and _, starting with a letter or _. You may write schema.table.

# services.*.anonymize.rules[].column

The column to change.

Letters, digits and _, starting with a letter or _. A column name has no schema part.

# services.*.anonymize.rules[].transform

What to do to the values in the column.

  • Type: string, one of the transforms below
  • Required: yes
  • Errors: overlay-parse
TransformResult
redactEvery value becomes a fixed marker
hashEvery value becomes a stable hash, so joins across tables still line up
"null"Every value becomes SQL NULL. The branch fails if the column is NOT NULL
fake-emailA made-up email address
fake-nameA made-up name
fake-phoneA made-up phone number. Refused on a column that a unique index depends on, since made-up numbers can collide

Write the SQL NULL transform in quotes, as transform: "null". A bare null (or ~, or Null) is YAML's "no value", not the word, so the file is refused.

# services.*.quiesce

A command that makes the service safe to snapshot.

OmniArc runs the command inside the service's container, as docker compose exec -T <service> <exec...>, before it takes a branch and freezes the parent. Use it for a database checkpoint or a cache save, so the snapshot holds everything that was written.

A command that exits with an error, or runs longer than timeout_secs, fails the branch before any snapshot is taken.

# services.*.quiesce.exec

The command and its arguments, one list item for each.

There is no shell, so write [sh, -c, "..."] if you need one. The list cannot be empty and no item in it can be empty.

# services.*.quiesce.timeout_secs

How many seconds the command may run before the branch fails.