Operational guidance
Container Execution
How container mode and Dockerfiles fit together in ota.
referenceautomation buildersintermediatestable2026-05-30
Recommended next
When to use this page
Use this page when a repo already has a Dockerfile and you need to decide how ota fits around it.
Choose this when you want the image build and the readiness contract to stay in separate layers so each one stays honest.
- Dockerfile builds the image
- ota.yaml declares what the repo needs
ota runandota upexecute against the declared environment- when legacy
execution.preferred: containeris set, or when a selected execution context usesbackend: container, ota runs inside that image instead of on the host - if the image comes from a Dockerfile, the Dockerfile is what made the container runnable
- the contract still matters even when the image already exists
Boundary note
- Docker is optional, not a universal prerequisite for ota
- use container mode when the repo or org already allows it
- host bootstrap for Docker is a separate concern and should not be assumed by default
containermode primarily governs workload execution; topology-aware service reachability now comes from execution contexts plusservices.endpointsandservices.readiness, not from assuming host and container see the same service surface.- use
tasks.<name>.runtime.listenerswhen the app itself should stay in the container but still publish a deterministic host URL for browsers, curl, or local tooling
How they differ
- Dockerfile handles OS packages, runtimes, and reproducible image setup
- ota handles tasks, checks, safe AI-agent guidance, provisioning policy, and execution mode
- container mode gives ota a repeatable runtime boundary for
runandup - workload listeners let ota report the resolved published URL for long-running app tasks instead of making users guess the host port
- doctor still explains whether the repo is ready inside that boundary
ota doctor --mode containerandota up --mode containertarget the container image directly- explicit container mode stops before any host provisioning fallback when the image cannot satisfy declared pins or no supported container engine is available
- if the selected image cannot be pulled or started,
ota doctor --containerreports that image acquisition blocker before reporting runtime or tool probes inside the image - use both when the repo already ships a Dockerfile and still needs explicit readiness rules
Simple model
Flowtext
Dockerfile -> builds the imageota.yaml -> declares what the repo needsota run/up -> executes against the declared environmentExample
Dockerfiledockerfile
FROM eclipse-temurin:21-jdkWORKDIR /workspaceCOPY . .RUN ./mvnw -q dependency:go-offlineota.yamlyaml
version: 1project: name: sample-java-servicetoolchains: java: version: "21"tools: maven: "*"tasks: setup: internal: true prepare: kind: dependency_hydration medium: package_dependencies source: kind: maven cwd: . mode: go_offline requirements: toolchains: - java tools: maven: "*" effects: writes: - .m2 network: true network_kind: dependency_hydration test: run: mvn testexecution: preferred: container lifecycle: persistent backends: container: image: eclipse-temurin:21-jdkRule of thumb
- use the Dockerfile to make the image runnable
- use the ota contract to make the repo explainable, diagnosable, and safe
- use container mode when you want ota to run against the image instead of the host
- use
ota up --dry-run --mode containerwhen you want the exact container preparation plan before ota mutates anything - use
ota up --mode containerwhen you want ota to prepare the repo inside that image before running tasks - do not replace the contract with the Dockerfile, because the Dockerfile does not tell ota what is safe to run or what should be provisioned
- do not make Docker the default adoption requirement unless the repo or org already uses it
Preview example
The preview should read like a real operator plan, not a second generic explanation layer.
Container previewtext
๐ฆฆ UP PREVIEW ./ota.yamlย โค NOT READYย โ Mode: dry-run (no write)ย Executionโ Backend: containerโ Lifecycle: persistentโ Image: `eclipse-temurin:21-jdk`โ Task: `setup`ย Contractโ Project: java-serviceโ Version: 1โ Execution: preferred=container, lifecycle=persistent, image=eclipse-temurin:21-jdkโ Counts: runtimes=1, tools=1, env=0, services=0, checks=0, tasks=2ย Planโ provision `java` `21` via `sdkman`โ run task `setup`โ re-check repo readinessย โค Primary BlockerMissing runtime: javaWhy: java is declared in the contract but is not available inside the configured ยป Image: `eclipse-temurin:21-jdk`Next: update `execution.backends.container.image` so `java` is available, then rerun `ota up --dry-run --mode container`