HashiCorp Nomad is a container and general-process orchestrator that teams pick instead of Kubernetes when the cluster is small and the complexity of a K8s control plane isn't worth it. One binary, one config file, declarative job files in HCL. Let's cover the install, the structure of a job file, and a typical cluster built from several VDS instances.
What Nomad is and how it differs from Kubernetes
Nomad solves the same problem as Kubernetes: place containers on suitable servers, watch that they're alive, and restart them on failure. But Nomad doesn't drag along a separate network layer, a built-in DNS, and dozens of CRDs — it's a single static Go binary that runs both as a cluster server and as an agent on a worker machine.
The key difference for VDS infrastructure: Nomad schedules not only Docker containers but also plain binaries, Java applications, and virtual machines equally well through task drivers. For service discovery and networking, Nomad relies on a separate product — Consul — rather than carrying that inside itself.
Installing Nomad on a single server
On Ubuntu, Nomad installs from the official HashiCorp repository with one sequence of commands:
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install nomad
nomad agent -dev -bind=0.0.0.0 -log-level=INFO
The -dev mode runs Nomad as a single node acting as both server and client at once — enough for a test. The web UI comes up on port 4646, showing the cluster's nodes and running jobs.
The job file: describing how to run a container
The unit of work in Nomad is a job, described in HCL. A minimal example for running nginx in a container:
job "web" {
datacenters = ["dc1"]
type = "service"
group "web" {
count = 2
network {
port "http" {
static = 80
}
}
task "nginx" {
driver = "docker"
config {
image = "nginx:1.27"
ports = ["http"]
}
resources {
cpu = 200
memory = 256
}
}
}
}
The command nomad job run web.nomad.hcl starts the job, and count = 2 means two instances of the task, placed by Nomad on the cluster's available servers automatically.
A multi-server cluster: server and client roles
In production, Nomad separates roles: server nodes hold the cluster state and make scheduling decisions, client nodes actually run the tasks. The recommended server count is 3 or 5 for Raft quorum, and clients — as many as the load requires.
| Criterion | Nomad | Kubernetes |
|---|---|---|
| Installation | One binary, a config a few lines long | kubeadm, a control plane of several components |
| Task types | Docker, exec, Java, QEMU virtual machines | Mostly containers |
| Service discovery | Through separate Consul | Built-in DNS and kube-proxy |
| Entry threshold | Low, one YAML-like job file | High, dozens of concepts and API objects |
Integrating with Consul for service discovery
Nomad by itself doesn't know how one task finds another's address. Consul closes that gap: every Nomad task registers in Consul as a service with a health check, and other tasks find it by a DNS name like web.service.consul. The Nomad plus Consul combination covers both scheduling and service discovery without a single line of Kubernetes YAML.
Updating jobs with zero downtime
A rolling update strategy is described right in the job file with an update block: Nomad brings up new task instances gradually, checks their health, and only then shuts down the old ones.
max_parallel = 1— update one instance at a timehealth_check = "checks"— consider an instance healthy based on health-check results, not just on the fact that it startedauto_revert = true— automatically roll back the job if the new version fails its health check
When Nomad is not the right fit
If a team already uses the Kubernetes ecosystem — Helm charts, operators, ready-made CRDs — switching to Nomad means rewriting all of that from scratch, and the payoff doesn't justify the cost. For one or two servers with no need for quorum or complex scheduling, it's simpler to use Docker Swarm or a lightweight cluster based on k3s if the Kubernetes ecosystem is still needed.
Summary: a short checklist
Nomad is worth taking when you need orchestration of mixed workloads — not just Docker — with a minimal entry threshold and without the full weight of Kubernetes.
- One binary instead of dozens of control-plane components
- 3 or 5 servers for Raft quorum in production
- Consul for service discovery when tasks need to find each other
- An
updateblock in the job file for zero-downtime updates