Skip to content

Plan a single service

Validate and plan are read-only. The optional apply at the end is mutating and requires its own explicit gates.

examples/single-service/hostwright.yaml in the core repository:

version: 2
project: single-service
services:
web:
image: docker.io/library/nginx:1.27
ports:
- "8080:80"
health:
command: ["curl", "-f", "http://localhost:8080/"]
interval: 30s
restart:
policy: on-failure
Terminal window
hostwright validate examples/single-service/hostwright.yaml

Validation checks the restricted manifest shape only. It does not contact registries, does not contact Apple container, and does not check whether the image exists anywhere.

Terminal window
hostwright plan examples/single-service/hostwright.yaml --output json

The output contains a deterministic planHash, typed issues, typed actions, and observationConnected: false. By default plan works from the manifest alone and reports declared state only. Running it twice on the same manifest produces the same hash.

Terminal window
hostwright up examples/single-service/hostwright.yaml \
--state-db /tmp/hostwright.sqlite --dry-run
hostwright up examples/single-service/hostwright.yaml \
--state-db /tmp/hostwright.sqlite \
--confirm-plan <hash-from-the-dry-run>

up validates the manifest, observes the runtime, recomputes the plan, and refuses if your hash does not match the observed plan. It persists desired state, observed state, operation intent, and a start event before mutation, then creates the missing web service with its port published to 127.0.0.1:8080. Success or failure lands in the event ledger. hostwright apply --confirm-plan <hash> runs the identical gate under its earlier name.

If the local image is missing, up refuses before mutation; pulling the image stays with you. Fetch it first (hostwright image pull docker.io/library/nginx:1.27 --runtime-provider apple-cli) and re-plan. To take the service back down, run hostwright down and then hostwright rm, each with its own --dry-run first.