Directory layout
orun expects three top-level directories in your manifest repository. Each directory holds one kind of resource:nodes/
nodes/
Node manifests describe a single host: its address, the Git repository and branch it should track, and runtime parameters such as poll interval and data directory. orun reads these files during
orun bootstrap to provision new hosts. Committing node manifests to the repository means adding a new node is as simple as running orun bootstrap nodes/<name>.yaml — no manual configuration on the host.deployments/
deployments/
Deployment manifests describe a containerized workload: the image to run, port bindings, health check endpoints, volume mounts, and environment variables. Each file corresponds to one container managed by orun on every node that tracks this repository.
services/
services/
Service manifests wire a Deployment to the built-in Caddy ingress: they specify which Deployment to expose, the public domain name, and whether to enable automatic SSL/TLS. The
ingress.domain.environment field uses $ENV as a placeholder that orun replaces with the environment suffix at runtime.Resource kinds
All resources share the sameapiVersion. The kind field tells orun how to interpret the file.
Node
| Field | Required | Default | Description |
|---|---|---|---|
host | Yes | — | SSH host or IP address of the target node |
user | No | root | SSH user for the bootstrap connection |
sshKeyPath | No | ~/.ssh/id_ed25519 | Path to SSH private key on the machine running orun bootstrap |
gitRepo | Yes | — | URL of the manifest Git repository |
gitBranch | No | main | Branch the node tracks after bootstrap |
pollInterval | No | 5s | How often the node polls for manifest changes |
dataDir | No | /opt/orun/ | Local state directory on the node |
Deployment
| Field | Required | Default | Description |
|---|---|---|---|
image | Yes* | — | Container image to run. Mutually exclusive with build. |
build.context | Yes* | — | Build context path. Required when using build instead of image. |
build.dockerfile | No | — | Path to Dockerfile within the build context |
build.buildMode | No | build-once | build-once or watch |
ports[].containerPort | Yes | — | Port exposed by the container (1–65535) |
ports[].port | Yes | — | Host port to bind to (1–65535) |
health.readiness.http | No | — | HTTP endpoint polled for readiness |
health.liveness.http | No | — | HTTP endpoint polled for liveness |
volumes[].hostPath | No | — | Path on the host to mount |
volumes[].containerPath | No | — | Path inside the container |
env | No | — | Environment variables passed to the container |
image or build is required.
Service
| Field | Required | Default | Description |
|---|---|---|---|
deployment | Yes | — | Name of the Deployment to expose |
ingress.domain.default | Yes | — | Domain used when no environment suffix applies |
ingress.domain.environment | No | — | Domain template for environment-specific routing; $ENV is replaced with the environment suffix |
ingress.ssl | No | false | Enable automatic SSL/TLS via Caddy |
Git authentication
The node fetches from theorigin remote of the manifest repository. Ensure the node has read access before running orun bootstrap.
- SSH deploy key (recommended)
- HTTPS token
Poll interval and change propagation
The node polls theorigin remote every pollInterval seconds (default: 5s). After you push a commit, the node picks it up within one poll cycle. Reduce pollInterval for faster convergence, or increase it to reduce Git API load on shared hosts.
