services
Generated from the code · as of CLI 0.6.0
One entry for each service in your compose project.
- Type: map of service name to entry
- Required: yes
- Errors:
unbound-service,orphan-entry,service-name-invalid,removed-key,overlay-parse
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 key | Use instead |
|---|---|
route | the arc-level edge |
resources | the arc-level resources. Per-container limits stay in compose |
scale | dormancy is set per arc in the dashboard. max is compose's deploy.replicas. quiesce is the per-service quiesce |
dataset | the arc-level recordsize. Volumes need no declaration, because the whole arc is branched |
ready_timeout_secs | the arc-level ready_timeout_secs |
redact, or anonymize written as a list | anonymize as a block with engine, database, user and rules |
#
services.*
What OmniArc needs to know about one compose service.
- Type: map
- Required: yes
- Errors:
pii-undeclared,removed-key,deploy-false-with-config,depends-on-undeployed,volume-shared-across-branch,overlay-parse
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
| Kind | For |
|---|---|
database | A relational database such as Postgres or MySQL |
document | A document store such as MongoDB |
forge | A Git forge |
cache | A cache such as Redis |
object | S3-style object storage |
web-service | Backend code. Most compose services are this |
frontend | Frontend 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.
- Type: boolean
- Required: no
- Default: true
- Errors:
deploy-false-with-config,depends-on-undeployed,edge-service-not-deployed,overlay-parse
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.
- Type: boolean
- Required: no
- Default: true
- Errors:
volume-shared-across-branch,overlay-parse
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.
- Type: boolean
- Required: yes
- Errors:
pii-undeclared,pii-without-anonymize,deploy-false-with-config,overlay-parse
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.
- Type: map
- Required: no
- Errors:
pii-without-anonymize,anonymize-engine-unsupported,anonymize-empty-rules,anonymize-shape,deploy-false-with-config,removed-key,overlay-parse
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.
- Type: string,
postgres - Required: yes
- Errors:
anonymize-engine-unsupported
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.
- Type: string
- Required: yes
- Errors:
anonymize-shape,anonymize-name
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.
- Type: string
- Required: yes
- Errors:
anonymize-shape,anonymize-name
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.
- Type: list of rules
- Required: yes
- Errors:
anonymize-empty-rules,anonymize-identifier,overlay-parse
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.
- Type: string
- Required: yes
- Errors:
anonymize-identifier
Letters, digits and _, starting with a letter or _. You may write schema.table.
#
services.*.anonymize.rules[].column
The column to change.
- Type: string
- Required: yes
- Errors:
anonymize-identifier
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
| Transform | Result |
|---|---|
redact | Every value becomes a fixed marker |
hash | Every 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-email | A made-up email address |
fake-name | A made-up name |
fake-phone | A 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.
- Type: map
- Required: no
- Errors:
quiesce-empty,quiesce-arg-empty,quiesce-timeout-zero,deploy-false-with-config,overlay-parse
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.
- Type: list of strings
- Required: yes
- Errors:
quiesce-empty,quiesce-arg-empty,overlay-parse
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.
- Type: integer, greater than 0
- Required: no
- Default: 30
- Errors:
quiesce-timeout-zero,overlay-parse