{"version":1,"pages":[{"id":"chapter-3","title":"Overview","routePath":"/","sourcePath":"README.md","text":"Run applications, without adopting a platform orch deploys containerized applications to a small Linux cluster. Configure, release, and operate them from one CLI. orch is in early development. Review the current limits before using it in production. Setting up a cluster takes three commands, in the style of Docker Swarm: Your SSH key is the credential. There are no certificate bundles to copy between machines. Start here Set up a controller and join workers. Deploy your first HTTPS application. Learn how rollouts, placement, and recovery behave. The controller stores desired state and computes placement. Agents reconcile workloads through containerd and runc, connect node networks with WireGuard, and route traffic directly through ingress nodes. Application traffic never passes through the controller. Features Area Product behavior Deployments Immutable plans, readiness gates, availability budgets, history, and rollback Runtime OCI services, workers, cron schedules, one-off jobs, hooks, and local volumes Setup orch init and orch join with one-time join tokens, SSH targets, and host checks that name each blocker and its fix Network Private per-node subnets, service DNS, a WireGuard mesh over private or public addresses, HTTPS and TCP ingress, node-local TCP and UDP ports Operations Remembered targets, live logs, events, runtime inventory, a keyboard-first TUI, and the orch web dashboard Recovery Durable agent assignments, controller backups, certificate renewal, and managed upgrades Limits orch targets small teams operating Linux hosts that can reach each other. It does not provide Kubernetes APIs, multi-region control planes, distributed storage, autoscaling, automatic fencing, or control-plane high availability. Those limits keep routine deployment and recovery understandable. Read the product scope or browse the source on GitHub."},{"id":"chapter-5","title":"Installation","routePath":"/installation/","sourcePath":"installation.md","text":"Installation This guide installs a controller and adds workers to the cluster. Requirements Requirement Supported setup Hosts Ubuntu 24.04 LTS or Fedora 44 (any edition except ostree-based ones) on amd64 Network IPv4 connectivity between hosts, over private or public addresses Controller A stable HTTPS address Workstation A machine for running the orch CLI The default workload network is 10.88.0.0/16. Choose a different range if it overlaps an existing network. Allow the controller's TCP port from trusted workers and operators. Allow UDP 51820 between workers. When workers use public addresses, allow UDP 51820 only from the other workers' addresses. Nodes that receive public web traffic also need TCP 80 and 443. The installer does not change UFW, firewalld, cloud firewalls, DNS, routing, or NAT, and it never changes the SELinux mode. On Fedora it installs SELinux file labels whenever SELinux is enabled; doctor warns when SELinux is permissive or disabled. Configure the appropriate firewalld zones and forwarding policy. Controller Copy a trusted Linux amd64 orch binary to the controller and run, as root: orch init checks the host, installs the controller as a systemd service and waits until it answers. If the host cannot be installed, it lists each blocking check with its fix instead. It detects the host's address and listens on port 9443; pass --advertise-address, --port or --name to override them. Use the address workers and your workstation can reach. Rerunning the same command resumes an interrupted installation. On the controller host, root can now run any orch command without further setup, for example sudo orch nodes. The CLI talks to the controller's local administrator socket, which only root can open. To manage the cluster from your workstation, add a target that reaches that socket over SSH. Your SSH key for root on the controller is the credential: orch init keeps a break-glass mTLS administrator context in /etc/orch/admin on the controller. You do not need it for normal use. Use orch cluster install instead when you want to choose where the administrator and recovery directories are written. Workers Create a join token for each worker, on the controller host or from your workstation: It prints a command. Copy the trusted orch binary to the worker and run that command there as root: The token is valid once, for one hour by default (--ttl accepts 1m to 24h), and pins the cluster CA, so the worker refuses a controller that is not yours. orch join checks the host the same way, installs the pinned dependencies and services, and advertises the host's detected address to the other workers. Pass --advertise-address to choose a different one. Machines without a shared private network can use their public address instead. See public advertise addresses for the firewall rule that should go with it. Confirm that it joined: The first node that joins accepts public ingress automatically. Enable ingress on later nodes when you want them to accept external traffic: Join files orch node join create and orch node install --join-file remain available when you prefer to transfer a join file: You can now deploy your first application. Troubleshooting An interrupted installation can be resumed by running the same command with the same binary, addresses, and join token or file. A readiness timeout leaves the installed services in place. On a controller: On a worker: On Fedora, inspect recent SELinux denials with sudo ausearch -m AVC,USER_AVC -ts recent. Upgrades Upgrade the controller before workers. Copy the trusted new binary to each host and inspect the change before applying it: Worker upgrades restart the agent while existing workloads continue under containerd. Keep the recovery path reported by each upgrade until the cluster has been observed under normal traffic."},{"id":"chapter-6","title":"Quickstart","routePath":"/quick-start/","sourcePath":"quick-start.md","text":"Quickstart Set up a cluster and deploy a web service. Complete the installation requirements before you begin. Controller Copy a trusted Linux amd64 orch executable to the controller host and run: Allow TCP 9443 from trusted workers and operators. On your workstation, add a target that reaches the controller over SSH as root: Worker Create a join token on your workstation (or as root on the controller): Copy the orch executable to the worker and run the printed command there: Allow UDP 51820 between workers. For public ingress, route DNS to an ingress-enabled node and allow TCP 80 and 443. Application Create orch.pkl: The image must listen on port 8080 and return success from /healthz. Deployment orch resolves image tags to immutable digests, waits for readiness, and records the deployment result. A failed update automatically returns traffic to the last healthy revision when autoRollback is enabled. Continue with application configuration, learn the runtime and rollout contract, or review deployment history and manual rollback."},{"id":"chapter-8","title":"Applications","routePath":"/configuration/","sourcePath":"configuration.md","text":"Applications Define an application in a typed Pkl file named orch.pkl. Check a file before deploying it: Services Each service requires an OCI image. The most commonly used settings are: Setting Default Purpose image required OCI image tag or digest replicas 1 Number of running instances command image default Replacement entry point args image default Command arguments restart \"always\" \"always\", \"on-failure\", or \"never\" resources.cpu \"100m\" CPU reservation or limit resources.memory \"128Mi\" Memory limit env empty Plain environment variables dependsOn empty Services that must be available before startup constraints empty Required node labels Use http for HTTP traffic and tcp for other TCP services. A service cannot define both. Environment and secrets Plain values can live in the application: Store sensitive values through stdin: Reference the stored name from the application: Secrets can also be projected as files below /run/secrets: For private image registries: Placement Add labels to nodes, then constrain a service to matching nodes: Constraints are required matches. If no node has all requested labels, the service remains blocked instead of running elsewhere. Replicas spread across eligible nodes when capacity permits. Local volumes Local volumes stay on one worker. A service that mounts one must have exactly one replica. If that worker is lost, orch reports volume_node_lost. It does not create an empty replacement volume on another worker. Schedules Schedules use five UTC cron fields: List recent runs and read their logs: Overlapping runs are skipped and missed runs are not replayed. Reading a local volume A cron job can mount a service's local volume read-only, for example to back it up. Each run is placed on the worker that holds the volume: readOnly must be true, and every mounted volume must belong to the same service in the application. The job waits until that service has been placed. The service keeps writing while the job reads, so use a copy method that is safe for the data, such as the database's own snapshot or backup tool. Rollouts maxSurge and maxUnavailable control how much extra capacity and unavailability a rolling update may use. They cannot both be zero. Applications whose services publish node-local ports must use maxSurge = 0 and maxUnavailable = 1; see node-local TCP and UDP. See deployments for update and rollback behavior, or networking to expose a service."},{"id":"chapter-9","title":"Deployments","routePath":"/runtime/","sourcePath":"runtime.md","text":"Deployments Use deployments to apply and track changes to an application. Deploy Validate and inspect the proposed change: Deploy and wait for the rollout: Submitting the same resolved configuration again is a no-op. Submitting an updated image or configuration creates a new revision. Status Typical states are: State Meaning PENDING Accepted and waiting to start DEPLOYING New instances are being created or checked HEALTHY Requested instances and routes are ready BLOCKED Placement or a required resource is unavailable FAILED The rollout could not complete Run orch tui --target production for a live view of applications, workers, deployments, events, and logs. Health checks An HTTP service with healthPath receives an HTTP GET every two seconds. Traffic is sent only to ready instances. Without healthPath, an HTTP or TCP endpoint uses a TCP readiness check. Keep the health endpoint fast and independent of optional downstream services. Updates Change the application file, inspect the plan, and deploy it again: The deploy block controls rollout capacity and deadline. With autoRollback = true, a failed update restores the last healthy revision. Existing instances stay available within the configured availability budget while replacements become ready. Rollbacks List deployment history and compare revisions before restoring one: A rollback creates a new deployment from the selected stored revision and reuses its resolved image digests. Placement orch considers CPU, memory, node labels, and local-volume ownership when placing instances. A service remains BLOCKED when no eligible worker can run it. When a worker disappears, services without local volumes can be placed on other eligible workers. A service with a local volume stays bound to the worker that owns its data and reports volume_node_lost until that worker returns or you restore the data separately. Agents keep their assigned workloads running while the controller is unavailable. New deployments, scheduling decisions, and cluster changes wait for the controller to return. Logs and exec Use the TUI for discovery, or the application commands for scripts: See cluster operations for node maintenance and application removal."},{"id":"chapter-10","title":"Networking","routePath":"/networking/","sourcePath":"networking.md","text":"Networking Services can communicate inside the cluster, be exposed through HTTP, HTTPS, or TCP ingress, or publish TCP and UDP ports on the node they run on. Requirements Workers must reach each other over their advertised IPv4 addresses. These can be private addresses on a shared network or public addresses when the machines have no private network in common. Allow UDP 51820 between workers for the WireGuard mesh. Public advertise addresses The mesh encrypts and authenticates all traffic between workers, so a public advertise address is supported. Workload addresses, cluster DNS, and service endpoints stay inside the private workload network either way; only the WireGuard underlay uses the public address. When workers advertise public addresses, allow UDP 51820 only from the other workers' advertised addresses in the host or provider firewall. orch does not open or restrict it for you. orch node doctor warns when the address is public as a reminder. Traffic between workers in different regions pays the network distance. For example, Frankfurt to US East adds about 90 ms each way. Keep chatty services and their databases in the same region, and use placement constraints to pin them there. The default workload network is 10.88.0.0/16. If it overlaps a host, VPN, or office network, choose another CIDR before deploying applications: The host and provider firewall must allow forwarding between the private interface, WireGuard, and workload network. On Fedora, configure appropriate firewalld zones and policies while keeping SELinux enforcing. HTTPS Enable ingress on at least one worker: Point the domain's A record at every ingress node that should receive traffic, then allow TCP 80 and 443 to those nodes. Configure the service: orch publishes the route after the service becomes healthy. HTTPS certificates are requested automatically. Confirm that public DNS resolves to an ingress node and that ports 80 and 443 are reachable so certificate issuance can succeed. HTTP Set public = true to create a catch-all listener on port 80: Only one service in the cluster can own this catch-all route. Domain routes take precedence when both are configured. TCP port is the container's service port. publicPort opens the listed port on ingress nodes and forwards bytes without HTTP or TLS handling. Allow that port in host and provider firewalls. Node-local TCP and UDP Some workloads, such as game servers, voice relays, or SIP endpoints, need clients to connect straight to the machine that runs them and need to see the client's real address. nodePort publishes a port on the node that runs each replica instead of on ingress nodes: The agent adds a destination NAT rule in its own nftables table, so packets reach the container without a user-space proxy and the container sees the client's source address. Clients connect to the address of the node that runs the replica; orch app status lists each published port with its node. udp requires http or tcp on the same service. The replica is published once that endpoint's health check passes; UDP itself is not probed. A node can run only one replica that publishes a given port, so replicas of the service spread across nodes. When no node has the port free, the replica stays pending with node_port_in_use. A port belongs to the application that first used it. A later application that asks for the same protocol and port is blocked until the first one releases it. Applications that publish node ports must set maxSurge = 0, because the old replica must stop before its replacement can take the port. Expect a short gap during each rollout. TCP ports 53, 80, and 443 and UDP ports 53 and 51820 are reserved for cluster DNS, ingress, and WireGuard. A port that a host process already listens on is reported as node_port_unavailable instead of being taken over. Connections from the node to its own address are not translated. Test from another machine. Allow each published port in host and provider firewalls on every node t..."},{"id":"chapter-12","title":"Cluster operations","routePath":"/operations/","sourcePath":"operations.md","text":"Cluster operations Use the CLI or TUI to inspect applications, manage nodes, run jobs, and maintain the cluster. Select a target before running commands: Pass --target production explicitly in automation. Cluster status The TUI provides a keyboard-driven view of applications, instances, workers, deployments, events, and live logs. orch web opens a browser dashboard for the selected target: cluster health, applications with replicas, routes, cron runs, deployment history, diffs and rollback, runtimes, nodes with cordon, drain and ingress controls, one-off jobs, events, and live logs. Press ⌘K or / to jump anywhere. The dashboard is served from the orch binary on a loopback address. It prints a one-time URL; the page only works on this machine and the administrator credentials stay in the orch process. Pass --no-open to only print the URL, and --port N to choose the port. orch status also shows when the administrator and controller certificates expire. Renew them before then; see certificate renewal. Applications When a service is blocked, its status includes a reason such as missing capacity, a label mismatch, a missing secret, or a lost local-volume worker. Resolve that condition and orch will reconcile the desired state. Node labels Labels let applications request specific workers: Use the same keys in a service's constraints. The orch.* label prefix is reserved. Node maintenance Cordon a worker to stop new placement: Drain movable workloads before maintenance: Services with local volumes remain pinned and are reported instead of being moved. After maintenance: One-off jobs Run a command from a service definition: Use a pre-deploy hook in orch.pkl when a migration must finish before a new revision rolls out: Migration commands should be safe to retry. Scheduled jobs Overlapping occurrences are skipped. Failed and missed occurrences are not automatically replayed. Removing applications Inspect the application and its local data before removal: Removing desired state stops its workloads. Treat local-volume data separately according to your retention policy. Backups Create backups regularly and copy them off the controller: Protect backups like administrator credentials: they contain controller state, PKI, and the secret-encryption key. See security and recovery before restoring a controller. Upgrades Upgrade the controller first, then workers: Keep the recovery path reported by each operation until normal traffic and a test deployment have succeeded. Controller outages Workers continue running their last assigned workloads. New deployments, scheduling, node changes, and secret changes wait. Restore the controller at the same canonical HTTPS address so existing workers and operator contexts can reconnect."},{"id":"chapter-13","title":"Security and recovery","routePath":"/security/","sourcePath":"security.md","text":"Security and recovery Protect access to the cluster, store application secrets, and keep recoverable backups. Administrator access The controller serves its administrator API on two listeners: A local socket, /var/lib/orch-controller/admin.sock, that only root and the controller account can open. orch on the controller host uses it when no target is selected, and orch target add NAME ssh://root@HOST reaches it over SSH. Whoever can log in to the controller as root can administer the cluster, which they could already do by reading its state. The HTTPS port, which requires an mTLS administrator certificate. orch init leaves one in /etc/orch/admin on the controller for break-glass use; orch cluster install --admin-dir ... writes it where you choose. Socket targets store no credentials on your workstation; access follows your SSH keys. For a certificate context, transfer the whole directory through a protected channel, restrict access to it, remove unnecessary copies, and use named targets instead of copying certificate paths into scripts: Anyone with this context can administer the cluster. Certificate renewal The controller and administrator certificates are valid for one year; the cluster CA is valid for ten. Worker certificates renew automatically, but the controller and administrator certificates do not. orch status shows both expiry times, and orch cluster doctor warns 30 days before the controller certificate expires. Renew both on the controller host. This works before or after the certificates expire, as long as the cluster CA is still valid. The CA does not change, so workers and existing backups are unaffected: The controller loads its new certificate only when it restarts. --admin-dir must be a new directory. It receives a fresh administrator context that you handle like the one from installation. Replace the credentials of an existing target and keep its transport settings: SSH targets reach the controller's local socket and need no change after a renewal. Old administrator certificates stay valid until they expire. After renewing, refresh the pki copy in your off-host backups. If a restore finds an expired controller certificate, it reports that and still restores the data. Run the renewal against the restored data directory before starting the controller. Worker enrollment Create one join token per worker: A token admits one node with that name, once, until it expires (one hour by default). It also pins the cluster CA fingerprint, so orch join only enrolls with your controller. A used or expired token is worthless, but an unused one admits a node: send it through a channel you trust. While orch join runs, the token is visible in the worker's process list; pass it on stdin with orch join - if other users share that host. Revoke a token you no longer need with orch node join revoke. Join files from orch node join create carry the same credential. Transfer them privately, keep them mode 0600 and delete copies after the worker has joined. Secrets Send values through stdin: Application files reference secret names and can remain in source control. Secret values are encrypted by the controller and delivered only to assigned workers. Files are projected below /run/secrets; environment values are provided only to the workload that references them. Rotate a secret by setting the same name again and deploying the application revision that should use it. Remove unused values with orch secret delete. Backups orch init --recovery-dir DIR and orch cluster install can write a day-zero recovery directory. It is only a snapshot. Create newer backups after configuration changes and on a schedule: Copy each completed backup off the controller. Protect it like administrator credentials because it includes: the controller database backup; the separately written secret-encryption key. Also preserve the controller's pki directory with an access-controlled system backup. The database backup does not contain private keys, administrator c..."},{"id":"chapter-15","title":"Limitations","routePath":"/product/","sourcePath":"product.md","text":"Limitations Review these limits before choosing orch for a production workload. Suitability orch is a good fit when: you operate Ubuntu 24.04 LTS or Fedora 44 hosts; one team controls the cluster and its applications; workers can reach each other over IPv4, on private or public addresses; applications run as OCI containers; a single durable controller is acceptable; local persistent data can remain tied to one worker. Product limits orch does not provide: Kubernetes APIs or compatibility; a highly available or multi-region control plane; automatic fencing during network partitions; distributed or replicated storage; autoscaling; Windows workers; arbitrary schedulers, plugins, or runtime drivers. The controller stores desired state and makes scheduling decisions. If it is unavailable, agents keep their assigned workloads running, but deployments and cluster changes wait. Local volumes stay on the worker where they were created. orch will not start an empty replacement volume elsewhere after that worker is lost. Back up stateful applications with tools appropriate to the application. Responsibilities orch installs and manages its own services, but you remain responsible for: host and provider firewall policy; DNS and public routing; operating-system security updates; access to the hosts; backup retention outside the controller; monitoring application behavior beyond declared health checks. Start with the installation guide, or review security and recovery before choosing production workloads."}]}