Skip to content

Recipes β€” ready-made .perch files you can download and run

22 curated .perch files that solve real problems β€” local Redis, the whole AI/observability/Kafka stack, cross-platform tool installers, daily Docker/kubectl wrappers. Download one, audit it with perch --scan, run it. No clone, no install, no source build.

TL;DR β€” one line install + run

# Download a recipe + its shared library
curl -fsSL https://raw.githubusercontent.com/olivierdevelops/perch/main/recipes/redis.perch -o redis.perch
curl -fsSL https://raw.githubusercontent.com/olivierdevelops/perch/main/recipes/_lib.perch -o _lib.perch

# Audit BEFORE running β€” risk score + what it touches
perch --scan -f redis.perch

# Verify it's feasible on THIS machine without running it
perch -f redis.perch --check

# Run
perch -f redis.perch up
perch -f redis.perch cli

Recipes declare what they need in a requires block (the Docker recipes declare bin "docker"). With it present, perch runs in strict mode β€” any undeclared shell bin is refused, and perch --check catches it statically, before you run. See requires.md.

The catalog (22 recipes)

Single-service local databases / queues (8)

One container, six-to-eight verbs, persistent volume, idempotent up.

Recipe Verbs What it gives you
redis up Β· down Β· cli Β· flush Β· monitor Β· logs Β· backup Β· status Redis 7 with rdb backup
postgres up Β· down Β· destroy Β· psql Β· createdb Β· dump Β· restore Β· logs Β· status Postgres 16 with persistent volume
mongodb up Β· down Β· destroy Β· shell Β· dump Β· restore Β· logs Β· status MongoDB 7 with mongosh
mysql up Β· down Β· destroy Β· cli Β· dump Β· restore Β· status MySQL 8 with persistent volume
mailpit up Β· down Β· open Β· logs Β· status SMTP catcher + web inbox
minio up Β· down Β· destroy Β· make_bucket Β· logs Β· status S3-compatible storage + console
rabbitmq up Β· down Β· destroy Β· logs Β· status RabbitMQ + management UI
localstack up Β· down Β· destroy Β· status Β· logs AWS S3/DynamoDB/SQS/SNS/Lambda emulator

Multi-service stacks (4) β€” perch's real value

Bring up three services with one command, using parallel.

Recipe Services Why
devstack Postgres + Redis + MinIO Canonical web-app local stack β€” typical dev needs DB + cache + object storage
aistack Ollama + ChromaDB + Open WebUI Local LLM lab β€” model runtime + vector store + chat UI
observe Prometheus + Grafana + Loki Local metrics + logs + dashboards
kafka-stack Kafka (KRaft mode) + Kafka UI Stream processing dev environment, no Zookeeper
$ perch -f devstack.perch up
==> Starting devstack
βœ“ postgres up
βœ“ redis up
βœ“ minio up
βœ“ devstack ready

  Postgres:  postgres://postgres:postgres@localhost:5432/app
  Redis:     redis://localhost:6379
  MinIO API: http://localhost:9000  (minioadmin/minioadmin)
  MinIO UI:  http://localhost:9001

Cross-platform tool installers (4)

Hide brew / apt / winget differences behind one command.

Recipe What it installs
modern-unix ripgrep + fd + bat + fzf + jq + yq + eza + zoxide
clouds aws + gcloud + az + kubectl + helm + terraform
node-stack fnm + pnpm + project bootstrap + .nvmrc pinning
python-stack uv (Astral's fast Python PM) + venv + project bootstrap
$ perch -f modern-unix.perch install   # works on macOS / Linux / Windows
$ perch -f modern-unix.perch check
  βœ“ rg
  βœ“ fd
  βœ“ bat
  βœ“ fzf
  βœ“ jq
  βœ“ yq
  βœ“ eza
  βœ“ zoxide

Daily CLI workflow wrappers (3)

Codify the verbs your team uses, with typed args and per-command --help.

Recipe Wraps Verbs
gh-flow gh (GitHub CLI) pr Β· land Β· sync Β· cleanup Β· wip Β· review Β· checks Β· status
docker-mgr docker status Β· big_images Β· stop_all Β· prune_safe Β· prune_all Β· top_cpu Β· shell Β· logs
kube-helpers kubectl ctx Β· ns Β· pods Β· shell Β· logs Β· pf Β· restart Β· top Β· events Β· who_am_i
$ perch -f gh-flow.perch land   # squash-merge current PR + delete branch
$ perch -f docker-mgr.perch prune_safe   # safe prune β€” no volumes
$ perch -f kube-helpers.perch restart api-deploy

Ops & security (3)

Recipe What it does
mkcert-local Local HTTPS β€” install root CA, mint per-domain certs
backup Encrypted backups with restic β€” snapshot/restore/forget/check/mount
scan-secrets Scan repo + container images for committed secrets via gitleaks

The safety story β€” three lines of defense

Before running a recipe you didn't write, you have static checks AND runtime gates:

1. perch --scan β€” static audit (no execution)

$ perch --scan -f redis.perch
── redis.perch ─────────────────────────────────
8 command(s), no catch, 2 binding(s)

CAPABILITIES NEEDED
  βœ“ shell       (12 calls: docker exec, docker run, docker ps, …)
  βœ“ subprocess  (the `docker` binary)

ENV VARS REFERENCED
  (none)

RISK FINDINGS
  [LOW]  shell args interpolate ${port} β€” value is bounded by type=string

RECOMMENDED INVOCATION
  perch --no-network --allow-bin docker --max-runtime 60 -f redis.perch up

2. perch --dry-run β€” execute nothing, show everything (including block bodies)

$ perch --dry-run -f redis.perch up
──── Dry-run β€” printing plan; no ops execute ────
  [1] has_bin "docker"   β†’ ${has_docker}
  [2] if lhs="has_docker" op="falsy"   {1 body op}
        fail msg="docker is required. Install Docker Desktop, or alias docker→podman."
  [3] shell_output "docker ps -q -f name=^perch-redis$"   β†’ ${running}
  [4] if lhs="running" op="truthy"   {1 body op}
        print msg="βœ“ ${NAME} already running"
  [5] if lhs="running" op="falsy"   {5 body ops}
        shell_output "docker ps -aq -f name=^${NAME}$"   β†’ ${existing}
        if lhs="existing" op="truthy"   {1 body op}
           shell cmd="docker rm ${NAME}"
        shell cmd="docker run -d --name ${NAME} -p ${port}:6379 ${IMAGE}"
        print msg="βœ“ redis up on port ${port}"
        print msg="  connect: redis-cli -p ${port}"

Block ops (if, parallel, retry, cache, sandbox, …) have their bodies expanded inline, so what you see is every op that could fire.

3. perch --no-X flags β€” runtime restrictions

perch --no-network -f recipe.perch status      # status doesn't need net
perch --no-write   -f recipe.perch logs        # logs doesn't write
perch --allow-bin docker -f recipe.perch up    # ONLY docker can shell out

Combine with --ask for per-op confirmation.

How the recipes are built

Each recipe is 30–140 lines of straightforward .perch. They share a common library at recipes/_lib.perch providing four templates:

  • require_docker β€” fail fast if docker is missing
  • require_bin "NAME" β€” fail fast if a specific bin is missing
  • say "label" β†’ ==> label
  • ok "msg" β†’ βœ“ msg
  • warn "msg" β†’ ⚠ msg (stderr; doesn't fail)

This shows off perch's import system (the recipe imports a helper file) and template system (one declaration, used everywhere by name).

Compose your own

Recipes are starting points. Fork one, change defaults, add verbs, ship it as your team's commands.perch:

cp recipes/devstack.perch ./my-team-stack.perch
# Edit. Maybe swap MinIO for Elasticsearch. Add `seed` and `reset` verbs.
perch --check -f my-team-stack.perch
perch -f my-team-stack.perch up

Or perch --build -f my-team-stack.perch -o devup and your colleagues just run ./devup up. No perch install needed.

Status

Pre-1.0. Recipes will grow; the import / template / context features they rely on are stable. Open a PR to add a recipe for the thing you wish existed.

Source: github.com/olivierdevelops/perch/tree/main/recipes.