Universal deploy framework with a beautiful TUI. Pure bash, zero dependencies, fully modular.
muster gives any project a polished deploy experience — interactive dashboard, health checks, rollback, log streaming — regardless of stack. It doesn't know how to deploy your app. It knows how to run your scripts beautifully and verify everything works.
curl -fsSL https://getmuster.dev/install.sh | bashOr clone manually:
git clone https://github.com/Muster-dev/muster.git ~/.muster/repo
ln -s ~/.muster/repo/bin/muster ~/.local/bin/muster
ln -s ~/.muster/repo/bin/muster-mcp ~/.local/bin/muster-mcpOr add to your shell profile (.zshrc / .bashrc):
export PATH="$PATH:/path/to/muster/bin"cd your-project
muster setup # guided wizard — scans project, creates deploy.json + hook scripts
muster # open the dashboardOr skip the wizard entirely with flags:
muster setup --scan # auto-detect everything
muster setup --stack k8s --services api,redis,worker # explicit
muster setup --scan --health api=http:/health:3000 # scan + custom health
muster setup --scan --namespace production # set k8s namespace
muster setup --scan --remote api=deploy@prod:/opt/app # remote SSH deploy
muster setup --help # see all flags| Command | Description |
|---|---|
muster |
Dashboard — live health/status view (auto-refreshes every 20s) with action menu + installed skills |
muster setup |
Guided setup wizard, or use flags for non-interactive (--help) |
muster setup --force |
Overwrite existing deploy.json |
muster deploy |
Deploy all services (respects deploy order) |
muster deploy api |
Deploy a specific service |
muster deploy --dry-run |
Preview deploy plan without executing |
muster status |
Check health of all services |
muster logs |
Stream logs (interactive service picker) |
muster rollback |
Rollback a service |
muster doctor |
Run project diagnostics (13 checks) |
muster doctor --fix |
Auto-fix what it can (permissions, stale PIDs, old logs, .dockerignore) |
muster cleanup |
Clean up stuck processes and old logs |
muster settings |
Project settings + global muster preferences |
muster settings --global |
View/edit global settings (color, log retention, etc.) |
muster uninstall |
Remove muster from project |
muster skill add <url> |
Install a skill addon |
muster skill list |
List installed skills |
muster skill remove <name> |
Remove a skill |
muster is an orchestrator, not a deployment tool. Your project provides hook scripts that do the actual work — muster runs them in order, shows beautiful output, and verifies health.
muster setup scans your project first — detects Dockerfiles, docker-compose configs, Kubernetes manifests, language files, and config references. It checks subdirectories too (docker/, k8s/, deploy/, infra/). It identifies your stack (k8s, compose, docker, or bare metal) and discovers services automatically. Infrastructure services (redis, postgres, etc.) get pull-only templates instead of build templates.
On k8s clusters, the scanner goes further — it queries kubectl get deployments to read real deployment names, container ports, and liveness/readiness probes directly from the cluster. Health checks are auto-configured from probe data (HTTP endpoints, TCP ports, or kubectl rollout status for deployments without probes). Deploy order is smart: infra services (redis, postgres, meilisearch) are sorted before app services. Services detected from files but not running as k8s deployments are automatically marked skip_deploy: true.
You confirm what it found, set deploy order, configure health checks and credentials per service, and muster generates real working hook scripts from stack-specific templates — not empty stubs.
If nothing is detected (empty project), it falls back to a conversational question flow.
your-project/
├── deploy.json ← config (generated by setup wizard)
└── .muster/
└── hooks/
├── api/
│ ├── deploy.sh ← real deploy commands for your stack
│ ├── health.sh ← real health check
│ ├── rollback.sh ← real rollback logic
│ ├── logs.sh ← log streaming
│ └── cleanup.sh ← cleanup stale resources
└── redis/
├── deploy.sh
├── health.sh
└── ...
Clean, human-readable config:
{
"project": "myapp",
"version": "1",
"services": {
"api": {
"name": "API Server",
"health": {
"type": "http",
"endpoint": "/health",
"port": 8080,
"timeout": 10,
"enabled": true
},
"credentials": { "mode": "off" },
"k8s": {
"deployment": "myapp-api",
"namespace": "production"
}
},
"redis": {
"name": "Redis",
"health": {
"type": "tcp",
"port": 6379,
"timeout": 5,
"enabled": true
},
"k8s": {
"deployment": "myapp-redis",
"namespace": "production"
}
}
},
"deploy_order": ["redis", "api"]
}The k8s block is config-driven — change deployment or namespace in deploy.json and all hooks update automatically (hooks read MUSTER_K8S_* env vars at runtime). Service keys with underscores are auto-converted to hyphens for k8s names (e.g., api_v1 → MUSTER_K8S_SERVICE=api-v1). deploy_order controls sequencing — infra services are auto-sorted first by the scanner.
Operations without hooks are silently skipped — no errors, no empty menu items.
Preview what a deploy would do — without executing anything:
muster deploy --dry-run # all services
muster deploy --dry-run api # single serviceShows the hook script content, credential keys (not values), health check status, remote target, and deploy order. Useful for building confidence before first deploys.
Deploy to remote servers via SSH. Hook scripts are piped to the remote host and executed there — output streams back for live display.
# Setup with remote targets
muster setup --scan --remote api=deploy@prod.example.com:/opt/myapp
# Or configure per-service in deploy.json{
"services": {
"api": {
"remote": {
"enabled": true,
"host": "prod.example.com",
"user": "deploy",
"port": 22,
"identity_file": "~/.ssh/deploy_key",
"project_dir": "/opt/myapp"
}
}
}
}Remote services use ssh user@host "bash -s" < hook.sh — credentials are exported on the remote side, never sent over the wire as arguments. Health checks and rollbacks also run remotely. Toggle remote on/off in muster settings.
Off by default. Three modes per service:
- Save always — stored in macOS Keychain (via
securitycommand). Persists across sessions. - Once per session — prompted once, kept in memory for the session.
- Every time — prompted on every deploy/rollback.
Never in deploy.json. Never in your project directory. Never in git.
Services with stored credentials are flagged with ! KEY in the dashboard.
muster settings has two sections:
Per-service toggles saved to deploy.json:
- Skip deploy — health-check only, don't deploy
- Health check — enable/disable health verification
- Credentials — cycle through Off / Save always / Once per session / Every time
- Remote — toggle SSH remote deployment on/off per service
Muster-wide preferences stored in ~/.muster/settings.json:
| Setting | Default | Description |
|---|---|---|
color_mode |
auto |
Color output: auto, always, never |
log_retention_days |
7 |
Days to keep deploy logs |
default_stack |
bare |
Default stack for new projects |
default_health_timeout |
10 |
Health check timeout (seconds) |
scanner_exclude |
[] |
Patterns to exclude from project scanning |
update_check |
on |
Check for muster updates |
Edit interactively via the TUI, or from the command line:
muster settings --global # dump all settings
muster settings --global color_mode never # set a value
muster settings --global scanner_exclude add old # add exclude patternCommunity addons that extend muster:
muster skill add https://github.com/someone/muster-skill-ssl
muster skill add https://github.com/someone/muster-skill-notifySkills are bash scripts with a skill.json manifest. Install from git URLs or local paths — muster reads the name field from skill.json. Installed skills appear automatically in the dashboard Actions menu. See docs/skills.md for how to create one.
muster includes an MCP (Model Context Protocol) tool so LLMs can deploy, check status, rollback, and manage your services directly. Pure bash, runs locally over stdio.
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"muster": {
"command": "muster-mcp"
}
}
}Add to .claude/settings.json:
{
"mcpServers": {
"muster": {
"command": "muster-mcp"
}
}
}| Tool | Description |
|---|---|
muster_scan_project |
Detect project files and suggest services |
muster_init_project |
Create deploy.json and hook directories |
muster_write_hook |
Write a hook script (deploy, health, rollback, etc.) |
muster_read_hook |
Read an existing hook script |
muster_status |
Health check all services |
muster_deploy |
Deploy all or a specific service |
muster_rollback |
Rollback a service |
muster_logs |
Get recent deploy logs |
muster_cleanup |
Clean up old logs and run cleanup hooks |
muster_list_services |
List services with hook availability |
muster_config |
Get the full deploy.json |
An LLM can scan your project, create the config, write all the hook scripts, then deploy — all through conversation. Requires jq.
| Platform | Status | Notes |
|---|---|---|
| macOS (Intel & Apple Silicon) | Fully supported | Primary development platform. Uses built-in bash 3.2. Keychain integration via security command. |
| Linux (x86_64, arm64, armv7) | Fully supported | Any distro with bash 3.2+. Keychain via secret-tool or pass. |
| FreeBSD | Supported | Requires bash 3.2+ installed. |
| Windows (WSL) | Fully supported | Runs natively in WSL1/WSL2 — same as Linux. |
| Windows (Git Bash / MSYS2) | Partial | Core commands work. TUI features (menu, checklist, spinners) may render incorrectly. No keychain. |
| Windows (native) | Not supported | Requires a Unix shell — use WSL instead. |
- bash 3.2+ — no newer features required (works with macOS default bash)
- jq or python3 — for reading deploy.json (jq preferred, python3 as fallback)
- curl — for HTTP health checks and skill installs
Optional tools (detected automatically, features degrade gracefully without them):
| Tool | Used for |
|---|---|
docker |
Docker/Compose stack deploys, dev stack infra services |
kubectl |
Kubernetes deploys, health checks, diagnostics |
ssh |
Remote deployment over SSH |
jq |
Config read/write (required for muster settings --global writes) |
security (macOS) |
Keychain credential storage |
secret-tool / pass (Linux) |
Keychain credential storage |
muster runs in bash but is invoked from any shell — zsh, fish, dash, etc. The entry point (bin/muster) has a bash shebang and does not depend on the user's login shell.
For local development. App services run as PID-managed background processes, infra services run via docker compose.
muster setup --stack dev --scan # detect dev commands from project files
muster dev # deploy all + watch health every 5s (Ctrl+C to cleanup)The scanner detects start commands from project files: package.json → npm start, go.mod → go run ., requirements.txt → Django/FastAPI/Flask detection, etc.
When a deploy fails, muster doesn't just abort — it shows interactive recovery options:
- Retry — run the same deploy again (fresh log file)
- Rollback — run the service's rollback hook
- Rollback & restart — undo k8s image change + restart pods (k8s update mode only)
- Skip and continue — move on to the next service
- Abort — stop everything
On k8s services, muster auto-diagnoses failures before showing the menu — inspecting pod events, logs, and matching 11 known error patterns (ImagePullBackOff, ErrImagePull, ErrImageNeverPull, InvalidImageName, OOMKilled, CrashLoopBackOff, CreateContainerConfigError, RunContainerError, Unschedulable, missing secrets/PVCs, version mismatch). K8s deploy hooks also detect terminal errors early (within ~10s) instead of waiting for the full rollout timeout, and show rolling progress ("2/3 pods ready").
Skills with post-deploy hooks (like Discord notifications) fire immediately when a deploy fails — before the recovery menu appears — so your team gets alerted right away.
Run diagnostics on your project:
muster doctor # check everything
muster doctor --fix # auto-fix what it can
muster --minimal doctor # plain text output (PASS/WARN/FAIL lines)13 checks: deploy.json validity, hook existence and permissions, health check status, tool availability, stale PID files, .env presence, old logs, k8s cluster reachability, fleet connectivity, build context overlap detection, and more.
In monorepos, one service's Docker build context (usually .) can contain another service's directory. This causes cache invalidation from unrelated changes, bloated build contexts, and potential secret leakage. muster detects this automatically:
- Dashboard — warning banner + "Doctor !" badge on the menu item when issues are found
- Deploy — yellow warning line before build starts
- Setup — detection runs after hook generation with fix suggestions
- Doctor — detailed diagnostics with
--fixto auto-add directories to.dockerignore
Results are cached at ~/.muster/.build_context_cache and refreshed when deploy.json or .dockerignore changes.
muster history # recent deploy/rollback events
muster history --all # full log
muster history api # filter by serviceFor scripts and CI pipelines that don't need the TUI:
muster --minimal # plain text service status, no interactive dashboard
muster --minimal doctor # PASS/WARN/FAIL lines, no color or boxes
muster --minimal deploy api # build context warnings to stderr as commentsMinimal mode outputs plain text to stdout and warnings as # comment-style lines to stderr, making it easy to pipe and parse.
- Pure bash — zero runtime dependencies, runs anywhere bash runs
- Modular — each file does one thing
- Your scripts, your way — muster orchestrates, you decide how things deploy
- Stack agnostic — Docker, k8s, bare metal, cloud — if you can script it, muster can run it
- Beautiful by default — spinners, progress bars, live log boxes, color-coded everything
- Graceful degradation — missing tools disable features, never crash
PRs welcome. The codebase is modular by design — each file in lib/ is self-contained.
make testApache License 2.0 — see LICENSE for details.
Copyright 2026 Ricky Eipper. You must retain copyright and attribution notices in any copy or derivative work.
