2. From your background

This chapter maps familiar tools to maand so later chapters feel like extensions of what you already do, not a new religion.


If you know Linux and SSH

You already have most prerequisites.

What you do today Maand equivalent
ssh user@host Same — all worker access uses secrets/<ssh_key> and ssh_user from maand.conf
Copy files with rsync maand deploy rsyncs staged trees to /opt/worker/<bucket_id>/
make start in a service directory Job Makefile; deploy calls start / restart / reload on the worker
cron or manual ops scripts maand run_command for ad-hoc remote shell; hooks for repeatable hooks

Maand adds a catalog (who runs what) and orchestrated rollouts on top of SSH + Make.


If you know Ansible (or similar config management)

Ansible Maand
Inventory (hosts) workspace/workers.json
Play per host / role Job + allocation (job × worker)
ansible-playbook push maand deploy (rsync + lifecycle)
Variables per host KV namespaces + Go templates (.tpl) rendered at deploy
Handlers / rolling serial max_concurrent_upgrades, rollout_order, health between batches
Vault for secrets secrets/job/<job> in KV (encrypted); put_job_secret in hooks

Maand is not a general-purpose CM tool. It optimizes for declared jobs on a fixed worker pool with versioned deploys and hash-based skip, not arbitrary ad-hoc playbooks.


If you know systemd and Docker Compose

Maand does not manage units or containers directly. Your job Makefile does:

# common pattern
start:
	docker compose up -d

stop:
	docker compose down

Or systemd:

start:
	sudo systemctl start myapp.service

stop:
	sudo systemctl stop myapp.service

Deploy runs make start once per new allocation and make restart or make reload on upgrades (depending on restart_policy in the manifest). See 05-jobs-and-lifecycle.md.


If you know Kubernetes

Kubernetes Maand
Cluster API server CLI host + maand.db (local SQLite)
Node Worker (fixed IP/hostname)
Deployment / StatefulSet Job (many allocations = one per matching worker)
Pod Your process/container on the worker — outside maand's object model
kubectl apply maand build then maand deploy
ConfigMap / Secret KV + templates; encrypted secrets namespace
RollingUpdate max_concurrent_upgrades + maand health_check between batches
PodDisruptionBudget / drain disabled.json + build + deploy

Maand has no pod abstraction. Identity is (job, worker IP, alloc_id). Good fit when you want K8s-like rolling deploys without running a cluster control plane.

Deeper comparison: comparison-orchestrators.md.


If you know Nomad

Nomad Maand
Nomad server + client agents No agents — SSH from CLI host
Job spec (HCL) manifest.json + files in workspace/jobs/<job>/
Allocation Same word: job instance on one worker
nomad job run maand deploy
Consul KV Maand embedded KV (scoped namespaces)
Update stanza (parallel, canary) max_concurrent_starts / max_concurrent_upgrades, job_control hooks

Nomad scales to dynamic scheduling; maand assumes you named the workers in advance.


One diagram, three tools

         Ansible              Kubernetes           Maand
         ───────              ──────────           ─────
Inventory / vars      →      API + etcd        →   workspace + maand.db
Play / role           →      Deployment        →   job
Host in group         →      Pod on node       →   allocation (job @ worker)
Push + handlers       →      reconcile loop    →   build + deploy (explicit CLI)

Next

03 — Bucket and workspace — where files live and what you edit in git.