# The model

OmniArc runs a Docker Compose project as an **arc**, and copies it, data included, into **branches**. Three words cover it.

## Arc

An arc is your app: one compose project, every service in it, and all of their data. It has a name, the `arc:` at the top of `arc.yaml`, and it belongs to your organization. You never choose a machine for it. OmniArc places it, and `omniarc deploy` creates it the first time.

## Branch

A branch is a full copy of an arc: every service, with a copy of its data, at its own address. Every arc has one branch to start with, `production`, which is where `omniarc deploy` goes unless you name another. Every other branch is copied from production, or from another branch:

```sh
omniarc arc branch create shop production preview
```

A copy takes one command. It starts out sharing its parent's data on disk, so it uses room only for what it changes. From then on the two are independent: nothing you do in a branch reaches its parent. A branch can sleep, which stops its services and keeps its data, and wake again. See [Branches](https://docs.omniarc.eu/guides/branches.md) and [Sleep and wake](https://docs.omniarc.eu/guides/sleep-and-wake.md).

Personal data you declare never reaches a branch as it is. A service that holds it either has rules that rewrite it in every copy, such as made-up email addresses, or starts empty in every branch.

## Service

A service is a compose service. OmniArc runs each one as your compose file says, and `arc.yaml` has one entry for each, matched by name.

## Compose runs as written; arc.yaml says what compose cannot

Your `docker-compose.yml` is not rewritten, converted or imported. It runs as you wrote it, which is why the same file still runs on your laptop. What compose has no words for goes in `arc.yaml`, next to it:

- **Which service answers the public address**, and on which port: [`edge`](https://docs.omniarc.eu/reference/arc-yaml/edge.md).
- **Which services hold personal data**, and how to anonymize it in a branch: [`services`](https://docs.omniarc.eu/reference/arc-yaml/services.md), with `contains_pii` and `anonymize`.
- **What the arc needs**: CPU, memory and disk ([`resources`](https://docs.omniarc.eu/reference/arc-yaml/resources.md)), and how long it may take to start ([`ready_timeout_secs`](https://docs.omniarc.eu/reference/arc-yaml/ready-timeout-secs.md)).

The panel shows the whole `arc.yaml` of the shop from [Get started](https://docs.omniarc.eu/guides/get-started.md). Most are about that size. `omniarc sync` drafts one from your compose file, and [the reference](https://docs.omniarc.eu/reference/arc-yaml.md) lists every key.

A few things compose can say have no meaning in an arc, a privileged container for example, and are refused before anything is uploaded. A few more run with a caveat. Everything else runs the way compose runs it. [Compose support](https://docs.omniarc.eu/reference/compose-support.md) lists both.

## The arc's .env

An arc has one `.env`, set with `omniarc env` and shared by all its branches. Compose reads it the way it reads a `.env` beside your compose file, for `${VARIABLES}`. Its values are write-only: no command prints them. See [Env and secrets](https://docs.omniarc.eu/guides/env-and-secrets.md).

## Your organization and its keys

Arcs belong to an organization, and the CLI acts for it with an API key, `OMNIARC_KEY`, minted on the dashboard's **Keys** page or with `omniarc key create`. A key has a role, and never more than the person who minted it:

| Role | Can |
| --- | --- |
| `member` | See arcs, their usage and their deploys; create, sleep, wake and destroy branches. |
| `admin` | All of that, and deploy, create arcs, set the `.env`, see costs and mint keys. |
| `owner` | All of that, and destroy arcs and bind your own domains. |

How long an arc nobody uses is kept is set per arc in the dashboard. See [Sleep and wake](https://docs.omniarc.eu/guides/sleep-and-wake.md#how-long-an-arc-is-kept).

**Example: shop/arc.yaml**

```yaml
arc: shop
edge: { service: web, port: 3000 }
resources: { cpu: "1", memory: 1Gi, disk: 5Gi }
services:
  web:
    kind: web-service
    contains_pii: false
  db:
    kind: database
    contains_pii: true
    anonymize:
      engine: postgres
      database: shop
      user: shop
      rules:
        - { table: customers, column: email, transform: fake-email }
```
