1. Introduction

Maand is an agentless orchestrator for a fixed pool of Linux workers. You run a single CLI on a control machine (laptop, bastion, or CI runner). That machine holds the bucket — project state on disk. Workers are ordinary hosts you reach with SSH and rsync. Nothing maand-specific is installed on workers until you deploy job files there.

If you have operated a small cluster with shell scripts, Ansible, and Makefiles, maand formalizes that pattern: a catalog of workers and jobs, ordered deploys, rolling restarts, and hooks — without running Kubernetes or a Nomad control plane.


What runs where

┌────────────── CLI host (you run `maand` here) ──────────────┐
│  workspace/     ← you edit (git)                            │
│  data/maand.db  ← catalog (maand build)                     │
│  secrets/       ← SSH key, CA, KV encryption                │
│  tmp/           ← deploy staging                            │
└───────────────────────────┬─────────────────────────────────┘
                            │  deploy: rsync + ssh
        ┌───────────────────┼───────────────────┐
        ▼                   ▼                   ▼
   Worker 10.0.0.1     Worker 10.0.0.2     …
   /opt/worker/<bucket_id>/jobs/<job>/...
Location What happens there
CLI host maand build, maand deploy, hook scripts (Python/Bun), SQLite catalog
Workers Your app files, Makefile targets (start/stop/…), runtime data/ on disk

Maand does not replace your process supervisor or container runtime. You express lifecycle in the job Makefile (often calling docker compose or systemctl). Maand calls those targets during deploy and via maand job.


Core vocabulary (preview)

Term One-line meaning
Bucket One maand project directory (maand init)
Worker A cluster node (SSH target) in workers.json
Job A deployable unit under workspace/jobs/<name>/
Allocation One job running on one worker (auto-created at build)

Full detail: concepts.md. Next chapter maps these to tools you may already know: 02-from-your-background.md.


Typical workflow

edit workspace  →  maand build  →  maand deploy  →  operate / debug  →  gc (after removals)
Step Touches workers? Purpose
build No Sync workspace → maand.db, validate placement, generate TLS, run post_build hooks
deploy Yes Rsync job trees, run make start / restart / reload, deploy hooks
health_check Yes (probes) Verify jobs are healthy after deploy or manually
gc Yes (cleanup) Purge removed allocations and worker data after you dropped jobs/workers from workspace

Common inspect commands (any time after build):

maand info
maand cat workers
maand cat jobs
maand cat allocations

What maand is good at


Intentional limits

Maand is not… Instead…
Highly available control plane One bucket directory on one CLI host is the source of truth
A container scheduler You bring Docker/systemd via Makefile
Dynamic bin-packing Placement is label matching + resource bounds

See overview.md for a full capability map and comparison-orchestrators.md for Kubernetes/Nomad contrast.


Next

02 — From your background · or jump to quickstart if you learn by doing.