Skip to content

Your first deploy

This is the whole path, once. Every command below either states that it contacts nothing, or is explicit about what it changes.

  1. Scaffold a project from the Compose file you already have.

    Terminal window
    ob init

    This writes ob.yml and puts the published schema reference on its first line, so your editor offers completion, hover documentation and inline errors that match what ob validate will say.

  2. Check the contract. Nothing is contacted.

    Terminal window
    ob validate

    Every failure carries a typed code, the path that produced it, and where possible the line and the command that resolves it:

    ✗ ob: "replicaz" is not a field of this contract (line 10); did you mean "replicas"?
    at: workloads.web.replicaz
    code: unknown_field
  3. Read back what Onebox understood.

    Terminal window
    ob canonical
    ob preview

    ob canonical marks each value with where it came from: # default for one Onebox chose, # shorthand for a top-level key it moved into a workload, # override for one an environment supplied. ob preview prints the Compose runtime it will generate. Read both before the first deploy — the difference between a value someone chose and one that appeared by itself is what a person checking a production configuration needs to see.

  4. Prepare the host. This contacts and changes the server.

    Terminal window
    ob bootstrap
  5. Review production without changing it.

    Terminal window
    ob plan --out ob-plan.json

    The plan is a mode-0600, digest-protected executable envelope containing the typed operation graph and the exact config, Compose, host-state, image, rendered-Compose and payload bindings. It expires after 15 minutes, and any drift or local payload change requires a new plan.

  6. Record a short-lived local confirmation for that exact plan.

    Terminal window
    ob approve --plan ob-plan.json --out ob-approval.json

    The confirmation is mode-0600 and digest-bound to the plan, server, inputs, risk, operator label, and expiry. A changed or expired plan needs a new confirmation. It is tamper-evident local ceremony, not authenticated identity.

  7. Deploy with both artifacts.

    Terminal window
    ob deploy --plan ob-plan.json --approval ob-approval.json
  • Directory/var/lib/ob/shop/
    • Directoryreleases/
      • Directory20260808T101500Z/ the release just deployed
      • Directory20260807T093000Z/ retained for rollback
    • current the symlink the runtime follows
    • journal append-only operation record
    • Directoryservices/ supporting services, outside every release

Container and volume names are derived and stable. Application containers are shop-web-1, shop-web-2, and shop-postgres-1; the host proxy is onebox-proxy. Persistent and provider resources include ob_shop_postgres_data, ob_shop for the service network, and ob-ingress for the host proxy network. Once a volume exists, its name cannot change without moving data.

Why plan and local confirmation are separate

Section titled “Why plan and local confirmation are separate”

The split creates a deliberate review ceremony and binds the answer to one exact sealed plan. ob approve records a short-lived local confirmation whose digest detects modification; it is not authenticated identity or proof that the actor requesting the change was technically unable to create it. Environments that need independent authorization require a future external provider, not a local checksum artifact.

For automation, plan and deploy accept structured output, and ob approve sits between them:

Terminal window
ob plan --output json --out ob-plan.json
echo y | ob approve --plan ob-plan.json --out ob-approval.json
ob deploy --output ndjson --plan ob-plan.json --approval ob-approval.json

ob approve always prompts and there is no flag to skip it. A routine plan asks yes or no; one that touches data — a migration, a destructive job, or an unknown data effect — asks for the release ID to be typed back. It reads the answer from stdin without checking for a terminal, so a pipeline supplies y, or the release ID for the stronger ceremony. Anything else records nothing and exits cancelled.

A JSON deploy buffers ordered operation events and its result into one envelope. NDJSON streams event records and a terminal result or error record. Diagnostics stay on stderr, so the structured stream is never polluted.

Terminal window
ob status # non-zero on divergence
ob resume # finish an interrupted deploy
ob abort # revert an interrupted deploy
ob rollback # activate the previous release

See Roll back a release.