Skip to content

Quickstart

This walks you through running SREForge’s validated v1 incident — latency-cache-stampede on the booklogr use-case — end-to-end, using the scripted reference fix. By the end you’ll have watched the closed loop drive a real alert from firing to cleared.

  • Docker with Compose v2 (docker compose …) and the daemon running.
  • Node 18+ and pnpm (the repo pins pnpm via packageManager; running corepack enable selects the right version).
  • A few GB of free RAM — the deploy plane + observability stack run ~8 containers alongside the shared Gitea forge.
  • WSL2 + Rancher Desktop is supported, but has two known gotchas — see Troubleshooting.
  1. Clone and install the repo-root tooling once.

    Terminal window
    git clone https://github.com/prismalens/sreforge.git
    cd sreforge
    pnpm install
  2. Bootstrap the shared forge — first run only. SREForge imports each substrate into a local Gitea forge — its own Git remote + CI/CD, with no github.com. The forge is shared infrastructure that persists across runs, so you set it up once, before the first setup/fresh. pnpm forge fresh does not start the forge for you.

    Terminal window
    # from the repo root — copy and fill the stack env
    cp use-cases/booklogr/stacks/flask-compose/.env.example \
    use-cases/booklogr/stacks/flask-compose/.env
    # edit that .env: set GITEA_ADMIN_PASSWORD (review GITEA_ADMIN_USER / _EMAIL)
    # start Gitea, create the admin user, register a runner
    docker compose -f infra/forge/forge.yml up -d gitea
    # create the admin via the UI at http://localhost:3000, or:
    # docker exec -it sreforge-gitea gitea admin user create \
    # --username sreforge --password '<pw>' --email admin@localhost --admin
    # mint a runner token (Gitea → Site Admin → Actions → Runners), put it in
    # the .env as GITEA_RUNNER_REGISTRATION_TOKEN, then:
    docker compose -f infra/forge/forge.yml up -d act_runner

    infra/forge/forge.yml’s header is the authoritative bootstrap reference.

  3. Cold bring-up. Import the substrate into the forge, author the regression, and start the deploy plane.

    Terminal window
    pnpm forge fresh booklogr

    fresh is a composite verb — it expands to setup then up. See the CLI reference for the full verb list.

  4. Run one graded incident with the reference fix. This arms the incident, runs it, and verifies behaviourally.

    Terminal window
    pnpm forge incident booklogr

    incident expands to arm → run → verify. The harness injects the fault, confirms the BooklogrApiLatencyP99High alert is firing, applies the reference fix through the CI → merge → redeploy chain, and then checks the alert clears and stays cleared while the k6 storm is still running.

  5. Tear down the deploy and load planes when you’re done (the local forge persists).

    Terminal window
    pnpm forge down booklogr

Once the stack is up, these endpoints are live:

Service URL
booklogr API http://localhost:5000
Web frontend http://localhost:5150
Prometheus http://localhost:9090
Alertmanager http://localhost:9093
Grafana http://localhost:3002
Gitea forge http://localhost:3000

During the run, watch BooklogrApiLatencyP99High move to firing in Alertmanager after the fault is injected, then clear after the reference fix redeploys — all while load continues.

The lower-level smoke scripts demonstrate the behavioural oracle directly. Each script self-resolves and runs standalone:

Terminal window
cd use-cases/booklogr/stacks/flask-compose
bash scripts/smoke-positive.sh

The reference fix flows through the full conductor loop and the alert clears under sustained load — the run passes.

The search-response cache is disabled (CACHE_TYPE = "NullCache") in the booklogr API, so every GET /v1/books/search misses cache and blocks a Gunicorn worker on a deterministically slow (1.2 s) book-metadata upstream. Under a k6 constant-arrival-rate storm over a small query set, the four workers back up, p99 latency crosses 0.3 s, and BooklogrApiLatencyP99High fires. The reference fix restores an effective cache, so repeated queries hit it and p99 clears while the storm is still running.

pnpm forge fresh hangs at “ensure org + empty repo exist in Gitea”. The shared forge isn’t bootstrapped. Confirm Gitea is up (docker compose -f infra/forge/forge.yml ps), the admin user exists, and the stack .env is filled — see step 2 above.

All deploy containers exit with code 255 at once (WSL2 + Rancher Desktop). This is a Rancher/WSL daemon cycle, not a crash — sometimes the Docker socket briefly disappears and takes the shared runner down with it. Recovery is idempotent: wait for the socket to return, restart the forge with docker compose -f infra/forge/forge.yml up -d, then bring the app stack back with pnpm forge up booklogr. (The deployment is stateless except its DB volume.)

A container fails with mount … not a directory / “mount a directory onto a file” (WSL2 + Rancher Desktop). A single-file bind mount can resolve as a directory through Rancher’s mount shim. The repo already avoids this (it binds parent directories or bakes files into images); if you add config, bind the parent directory, never a single file.

Port already in use. The stack needs host ports 5000, 5150, 5432, 9090, 9093, 3002 for the app + observability, plus 3000 and 222 for the forge. Free the conflicting service or stop a previous run with pnpm forge down booklogr.