> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orcra.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Deployment manifest: run containers with orun

> All Deployment manifest fields: image vs. build mode, port bindings, health probes, volume mounts, environment variables, and SOPS-encrypted secrets.

A Deployment manifest is a YAML file stored at `deployments/<name>.yaml` in your manifest repository. It describes a containerized workload that orun runs and reconciles on each node. You can either pull a pre-built image from a container registry or instruct orun to build the image from source code on the node. Every time the node detects a new commit on the tracked branch, it reconciles all Deployment manifests and restarts containers whose configuration has changed.

## Modes

Deployments support two mutually exclusive modes: **image-based** and **build-based**. Set either `spec.image` or `spec.build`, never both.

<Tabs>
  <Tab title="Image-based">
    Pull a container image from a registry and run it directly.

    ```yaml theme={null}
    apiVersion: run.orcra.dev/v0alpha
    kind: Deployment
    metadata:
      name: hello-world
    spec:
      image: traefik/whoami
      ports:
        - containerPort: 80
          port: 8080
      health:
        readiness:
          http: localhost:80/health
        liveness:
          http: localhost:80/health
      volumes:
        - hostPath: /var/storage/db
          containerPath: /db
      env:
        LOG_FORMAT: json
    ```
  </Tab>

  <Tab title="Build-based">
    Build the container image from source code checked out on the node at `codeDir`.

    ```yaml theme={null}
    apiVersion: run.orcra.dev/v0alpha
    kind: Deployment
    metadata:
      name: my-app
    spec:
      build:
        context: my-app
        dockerfile: Dockerfile
        buildMode: watch
      ports:
        - containerPort: 3000
          port: 3000
    ```
  </Tab>
</Tabs>

## Fields

### Image

<ParamField path="image" type="string">
  Container image to pull and run, in standard Docker image reference format (e.g. `nginx:alpine`, `ghcr.io/org/app:latest`). Mutually exclusive with `build`. One of `image` or `build` is required.
</ParamField>

### Build

<ParamField path="build" type="object">
  Configuration for building the container image from source on the node. Mutually exclusive with `image`. One of `image` or `build` is required.
</ParamField>

<ParamField path="build.context" type="string" required>
  Path to the build context directory, relative to `codeDir` on the node. For example, `my-app` resolves to `<codeDir>/my-app`.
</ParamField>

<ParamField path="build.dockerfile" type="string">
  Path to the Dockerfile, relative to the build context. Defaults to `Dockerfile` in the context directory when omitted.
</ParamField>

<ParamField path="build.args" type="object">
  Map of build-time arguments passed to Docker as `--build-arg` flags. Values are plain strings.

  ```yaml theme={null}
  build:
    context: my-app
    args:
      NODE_ENV: production
      APP_VERSION: "1.2.3"
  ```
</ParamField>

<ParamField path="build.buildMode" type="string" default="build-once">
  Controls when orun rebuilds the image. Accepted values:

  * `build-once` — Build the image once when the Deployment is first applied, then reuse it.
  * `watch` — Rebuild the image whenever orun detects file changes in the build context.
</ParamField>

<Tip>
  Use `buildMode: watch` during active development so that pushing source code changes to the node triggers an automatic rebuild and container restart.
</Tip>

### Ports

<ParamField path="ports" type="object[]">
  List of port bindings that map container ports to host ports on the Docker network.
</ParamField>

<ParamField path="ports[].containerPort" type="number" required>
  Port the container listens on. Must be between 1 and 65535.
</ParamField>

<ParamField path="ports[].port" type="number" required>
  Host port to bind to. Must be between 1 and 65535. The container is reachable at `<host-ip>:<port>` from outside the node.
</ParamField>

### Health checks

<ParamField path="health" type="object">
  Configures liveness and readiness probes for the container. Both probes are optional and independent of one another.
</ParamField>

<ParamField path="health.readiness.http" type="string">
  HTTP endpoint polled to determine whether the container is ready to serve traffic. Specify as `<host>:<port><path>`, for example `localhost:80/health`. orun polls this endpoint after startup.
</ParamField>

<ParamField path="health.liveness.http" type="string">
  HTTP endpoint polled continuously to determine whether the container is still healthy. Use the same or a different endpoint from readiness. If the liveness check fails, orun will restart the container.
</ParamField>

### Volumes

<ParamField path="volumes" type="object[]">
  List of bind mounts between host paths and container paths.
</ParamField>

<ParamField path="volumes[].hostPath" type="string">
  Absolute path on the node host to mount into the container. The directory must exist on the node before the container starts.
</ParamField>

<ParamField path="volumes[].containerPath" type="string">
  Absolute path inside the container where the host directory is mounted.
</ParamField>

### Environment variables

<ParamField path="env" type="object">
  Map of environment variable names to values injected into the container at startup. Values are plain strings. To use secrets, see the [secrets documentation](/configuration/secrets).

  ```yaml theme={null}
  env:
    LOG_FORMAT: json
    PORT: "8080"
    DATABASE_URL: postgres://localhost/mydb
  ```
</ParamField>

<Note>
  Environment variable values that match the pattern `ENC[AES256_GCM,...]` are automatically decrypted by orun at apply time when a valid age key is present on the node. See [Encrypting secrets](/configuration/secrets) for details.
</Note>
