Each step is a command you can copy. Check them off as you go — your progress is saved and survives a refresh.
Tip: to scaffold straight into the current directory (e.g. a fresh git repo root) instead of a subfolder, use fabbro create <name> --here.
From the project root, create a virtual environment and install both the runtime and dev dependencies.
Windows (PowerShell): python -m venv .venv; .venv\Scripts\Activate.ps1; pip install -r requirements.txt -r requirements-dev.txt
The doctor is the pre-flight check. It inspects your project, works out which secrets and environment variables the code and configs need, writes a .env with the required keys, and boots the app in a sandbox to prove it starts. Run it first — the next step fills in the keys it laid out.
It runs the project's forjedoctor.py under your .venv. Use --strict to treat warnings as failures.
Fill the .env the doctor created with real values. fabbro secret gen writes a FERNET_KEY (vault encryption) and a SECRET_KEY (session signing) in place — placeholders will not boot.
.env holds secrets and is already in .gitignore — never commit it. Non-secret dev infra (DB_PATH, APP_BASE_URL) lives in config/runtime.yaml, which is committed and read by fabbro start.
Run the doctor once more. With the secrets in place it should sandbox-boot the app cleanly — green means you are ready to run.
Create the first admin account. This is the only way an admin is made — the role is CLI-only. The command prompts for an email and a hidden password.
One command runs your whole local stack: the playbook server, the Flask app, and every worker under workers/. It reads your secrets from .env and the runtime vars (DB_PATH, APP_BASE_URL) from config/runtime.yaml, injects them into every process, and creates the database schema on first boot. This is the local equivalent of what docker-compose does in production.
Then open http://127.0.0.1:5000 — the login screen, already styled, auth working out of the box. The playbooks stay at http://127.0.0.1:4600. One Ctrl-C stops the whole stack; if any process dies, the rest come down with it. Flags: --no-app, --no-workers, --no-playbooks. In production the bundled docker-compose serves the app with gunicorn on port 8000.
Background jobs — sending email, and anything you enqueue — run in separate worker processes, not in the web app; each reads the same database. fabbro start already discovers and launches every workers/*.py automatically, so a new worker you add is picked up on the next start — no extra terminal, no config to edit.
The web app and every worker must point at the same local DB file — never a network filesystem. In production, compose runs each worker as its own service. To run just the app while debugging a worker, use fabbro start --no-workers and launch the one you want with python -m workers.<name>.