Skip to main content
Docs navigation

Nomad

On Nomad, a system job places one runner on every client node — the same "operate the node" shape as a Kubernetes DaemonSet. This page is the worked job; the two mechanics it relies on (a service-less binary and a persistent state volume) are on Containers.

The system job#

The job fetches the release binary in an artifact stanza, passes EMISAR_URL and a reusable enrollment key through the environment, and persists /var/lib/emisar on a host volume so each node's runner keeps a stable identity across reschedules — the shared mechanics again, in Nomad's shape.

emisar-runner.nomad.hcl
job "emisar-runner" {
  type = "system"            # one instance on every client node

  group "runner" {
    volume "state" {
      type   = "host"
      source = "emisar-state"   # a host volume registered on each Nomad client
    }

    task "runner" {
      # raw_exec runs on the node with no isolation — the runner sees the node,
      # like a host install. Enable it in the client's plugin config. (Use the
      # "docker" driver instead for a container-scoped runner + explicit mounts.)
      driver = "raw_exec"

      artifact {
        source = "https://github.com/andrewdryga/emisar/releases/download/v<version>/emisar-<version>-linux-amd64.tar.gz"
      }

      config {
        command = "local/emisar"
        args    = ["--config", "/etc/emisar/config.yaml"]
      }

      env {
        EMISAR_URL            = "https://emisar.dev"
        EMISAR_ENROLLMENT_KEY = "emkey-enroll-…"   # template from Vault in production
      }

      volume_mount {
        volume      = "state"
        destination = "/var/lib/emisar"
      }

      resources {
        cpu    = 100
        memory = 128
      }
    }
  }
}

Register the host volume on each client (client { host_volume "emisar-state" { path = "/var/lib/emisar" } }), then nomad job run emisar-runner.nomad.hcl.

Driver and visibility#

The driver decides what the runner can reach — the same namespace question as any container shape. raw_exec runs the binary directly on the client, so it sees the node exactly as a host install does — right when you want packs to inspect and act on the node itself. It's disabled by default, so enable it deliberately on the clients that should run node-level actions. Prefer the docker driver for a container-scoped runner: it sees only what you mount into it, so a runner that should only watch one service can't reach the rest of the node.

Keys and pack credentials#

Mint a reusable enrollment key for the job — a single-use key is spent by the first node and the rest fail to enroll. If the packs on these runners talk to Nomad, Consul, or Vault, hand those credentials to the runner through allow-listed environment variables (Nomad's template + Vault integration is the clean source), never through action arguments — the pack-credentials pattern applies unchanged.