Files
certctl/docs/contributor/qa-prerequisites.md
T
shankar0123 1720e11109 docs: fix broken single-file demo invocation in README + qa-prerequisites + ENVIRONMENTS
The README's Quick Start, the qa-prerequisites contributor doc, and the
landing page (separate repo, separate commit) all shipped a copy-paste
command that produces:

  service "certctl-server" has neither an image nor a build context
  specified: invalid compose project

The bug landed silently with commit a3d8b9c (the U-3 master). Pre-U-3,
docker-compose.demo.yml was self-contained and could be invoked with a
single -f flag. U-3 deliberately reduced it to a 27-line overlay — its
only payload today is `CERTCTL_DEMO_SEED=true` on the certctl-server
service — because the demo seed now applies at boot via
postgres.RunDemoSeed, not via /docker-entrypoint-initdb.d/. The overlay
no longer carries an image: or build: of its own, so it MUST be passed
alongside the base file.

The README/qa-doc/landing-page never picked up the rename of the contract.
Every operator who copy-pasted the Quick Start since U-3 has hit the
"invalid compose project" error and bounced. The operator caught it
running the demo locally today.

This commit fixes the three certctl-repo sites:

  README.md (Quick Start)
    docker compose -f deploy/docker-compose.demo.yml up -d --build
    →
    docker compose -f deploy/docker-compose.yml -f deploy/docker-compose.demo.yml up -d --build

    Plus the "drop the -f flag for clean install" prose now spells out
    the correct fallback (`-f deploy/docker-compose.yml` alone).

  docs/contributor/qa-prerequisites.md (Step 1)
    Same single-file → two-file fix, plus an inline note explaining
    why the override-only file requires the base (so the next person
    who reads it understands the contract instead of re-discovering it).

  deploy/ENVIRONMENTS.md (Demo Overlay → What it adds)
    Replaced the stale "One line: mounts seed_demo.sql into PostgreSQL's
    init directory" claim — that hasn't been true since U-3 — with the
    accurate "One env var: CERTCTL_DEMO_SEED=true; server applies
    seed_demo.sql at boot via postgres.RunDemoSeed" description, plus
    the historical context for why the overlay can't stand alone.

The certctl.io landing page hits the same bug (line 759); fix shipping
in a separate commit in that repo.

Acceptance gate (manual):
  - copy/paste the new README Quick Start command end-to-end against
    a fresh clone — succeeds, dashboard at https://localhost:8443
    shows the seeded demo data within ~30s.
  - clean-install fallback (`docker compose -f deploy/docker-compose.yml
    up -d --build`) starts a working stack with no demo data.
2026-05-05 20:55:26 +00:00

4.5 KiB

QA Prerequisites

Last reviewed: 2026-05-05

Operational prereqs for running release QA against certctl. Before any of the contributor-facing testing surfaces (test-environment.md, gui-qa-checklist.md, release-sign-off.md) are useful, the local stack needs to be in a known-good state.

Why manual QA on top of automated tests?

Automated tests mock dependencies and run in isolation. Manual QA validates the full integrated stack: real PostgreSQL, real HTTP, real agent binary, real file I/O, real scheduler timing. It catches issues that unit tests can't: migration ordering, Docker networking, env var parsing, browser rendering, and timing-dependent scheduler behavior.

Environment setup

Step 1: Start the full stack.

cd deploy && docker compose -f docker-compose.yml -f docker-compose.demo.yml up --build -d

This builds three containers (postgres, certctl-server, certctl-agent) and runs them on a bridge network. The --build flag ensures you're testing the current code, not a stale image. The demo overlay is an override file (no image: or build: of its own) that layers CERTCTL_DEMO_SEED=true onto the base — both files must be passed in that order or compose errors with service "certctl-server" has neither an image nor a build context specified. The seed populates the database with realistic fixtures.

Step 2: Wait for healthy state.

for i in $(seq 1 30); do
  STATUS=$(docker compose ps --format json 2>/dev/null | jq -r 'select(.Health != null) | "\(.Name): \(.Health)"' 2>/dev/null)
  echo "$STATUS"
  echo "$STATUS" | grep -q "unhealthy\|starting" || break
  sleep 2
done

Why: Docker Compose starts containers in dependency order (postgres → server → agent), but "started" doesn't mean "ready." Health checks confirm postgres accepts connections, the server responds on /health, and the agent process is running.

Step 3: Set shell variables used throughout the QA flow.

export SERVER=https://localhost:8443
export API_KEY="change-me-in-production"
export AUTH="Authorization: Bearer $API_KEY"
export CT="Content-Type: application/json"
export CACERT="--cacert ./deploy/test/certs/ca.crt"

Every curl command in QA docs uses these variables. Setting them once avoids typos and keeps the docs copy-pasteable.

Note: The default Docker Compose sets CERTCTL_AUTH_TYPE: none for the demo overlay, meaning auth is disabled. Tests that exercise auth require flipping this to api-key; instructions are in the relevant test docs.

Step 4: Build CLI and MCP server binaries on the host.

go build -o certctl-cli ./cmd/cli/...
go build -o certctl-mcp ./cmd/mcp-server/...

The CLI and MCP server are separate binaries that talk to the server over HTTP. Building them verifies the code compiles and produces the executables you'll test later.

Demo data baseline

The seed data (migrations/seed.sql + migrations/seed_demo.sql) pre-populates the database with realistic fixtures. Confirm it loaded:

curl -s $CACERT -H "$AUTH" $SERVER/api/v1/stats/summary | jq .

Expected shape:

{
  "total_certificates": 15,
  "active_certificates": ...,
  "expiring_certificates": ...,
  "expired_certificates": ...,
  "pending_renewals": ...
}

Reference IDs in the demo data (used across QA docs):

Resource IDs Count
Teams t-platform, t-security, t-payments, t-frontend, t-data 5
Owners o-alice, o-bob, o-carol, o-dave, o-eve 5
Policies rp-standard, rp-urgent, rp-manual 3
Issuers iss-local, iss-acme-le, iss-stepca, iss-digicert 4
Agents ag-web-prod, ag-web-staging, ag-lb-prod, ag-iis-prod, ag-data-prod 5
Targets tgt-nginx-prod, tgt-nginx-staging, tgt-f5-prod, tgt-iis-prod, tgt-nginx-data 5
Profiles prof-standard-tls, prof-internal-mtls, prof-short-lived, prof-high-security 4
Certificates mc-api-prod, mc-web-prod, mc-pay-prod, etc. 15
Agent Groups ag-linux-prod, ag-linux-amd64, ag-windows, ag-datacenter-a, ag-manual 5
Network Scan Targets nst-dc1-web, nst-dc2-apps, nst-dmz 3

Once these are green

Move to the appropriate downstream surface: