Why Compose is generated
Onebox does not read a Compose file you wrote. The contract is a declaration of what the application is; the Compose file, the container names and the routing labels are all derived from it.
Why the runtime is not yours to hand over
Section titled “Why the runtime is not yours to hand over”Under the ownership boundary, Onebox owns the runtime. Reading a runtime you wrote inverts that: you own it, and Onebox merely operates something it did not design and cannot fully reason about.
The Compose file and Onebox annotations could disagree, with nothing to arbitrate between them.
Onebox could not choose the container name, the volume name, the router rule or the network, because you already would have. So it could not guarantee they are consistent, collision-free, or stable across releases.
strategy: rolling needs a health check to gate it. Reading a health check from
an authored file would leave Onebox unable to guarantee that the rollout is gated.
What generation buys
Section titled “What generation buys”- Derived, stable names. Workload containers use the uniform
<app>-<component>-<replica>grammar, such asshop-web-1; managed services areonebox-<service>, such asonebox-postgres; persistent and provider resources includeshop_default,onebox_postgres_data,onebox_services, andonebox-ingress. The application and service networks are declared external and created under Onebox’s ownership fence, so Compose cannot remove a live shared network during release teardown. A fullob destroy --volumesremoves them; if an unmanaged endpoint remains attached, destruction stops without deleting Onebox’s recovery state or releasing host ownership. Once a resource exists its name cannot change without migration, and a foreign resource already holding a derived name is refused, not adopted. - Digest binding. The rendered Compose is bound into the plan, so what was reviewed is what executes.
- Refusals that mean something.
strategy_ungated,route_collision,stateful_replicasare all statements about the generated runtime, which is the only thing that will actually run. - Typed routing. Two workloads claiming the same entrypoint, protocol, hostname
and path produce
route_collision. This prevents the proxy from accepting both and routing to one without saying which.
A workload name is its identity
Section titled “A workload name is its identity”Changing a workload’s key is a rename in the declaration but a replacement at runtime. Onebox starts and verifies the new workload, activates the release, and only then drains and removes the old workload. This ordering keeps a route rename from stopping the old endpoint before the new one can serve.
Persistent volumes follow the same identity rule: a renamed workload receives new derived volume names. Onebox does not guess that data should move between them. Move or reattach persistent data explicitly before treating a workload rename as complete.
You can still see it, and still leave
Section titled “You can still see it, and still leave”Generation is only acceptable because the output is inspectable and the exit is a command:
ob preview # print the generated runtime, change nothingob eject # write it out and hand it over, permanentlySee Eject for the output and what remains on the host.
And the escape hatch remains
Section titled “And the escape hatch remains”A container Onebox cannot describe is adopted verbatim:
workloads: legacy: role: Daemon compose: docker-compose.yml#legacyRefusals apply only where the referenced service contradicts something Onebox
owns: extends, a fixed container_name, network_mode, labels in the onebox.
or traefik. namespaces. See Adopt an existing Compose file.
The contract generates by default and defers on request.