Run on 2026-06-13, host interserver2. All 9 steps from
M1_VERIFICATION.md passed.
| # | step | result |
|---|---|---|
| 1 | docker compose build |
✅ all 6 images built |
| 1 | docker compose up -d |
✅ all 10 services up (postgres, redis, nats, emqx, clickhouse, fakefcmd, ingestd, routerd, deliverd, admind) |
| 1 | docker compose up seed |
✅ seed: ok |
| 2 | verify companies/individuals/fcm_tokens | ✅ 1+1+1 rows |
| 3 | fakefcmd /health |
✅ {"status":"ok","received":0,"failed":0} |
| 4 | signed POST to ingestd | ✅ 202 {"alert_id":"0000019ec2...","dedupe_count":1} |
| 5 | deliveries row appears |
✅ status=sent, attempts=1, channel=fcm |
| 6 | fakefcmd log | ✅ alert_id=0000019ec2... title="Disk full on db-prod-03" |
| 7 | bad signature | ✅ 401 |
| 7 | payload > 256KB | ✅ 413 |
| 7 | invalid JSON | ✅ 400 |
| 7 | bad severity | ✅ 400 |
| 8 | loadgen-http 50/s × 30s | ✅ 1529 sent, 0 failed, 0 rate_limited |
| 8 | deliveries count after burst | ✅ 1530 sent (1529 burst + 1 step-4) |
| 9 | same dedupe_key 3x | ✅ dedupe_count: 1, 2, 3 |
| # | issue | fix |
|---|---|---|
| 1 | Dockerfile COPY ... 2>/dev/null \|\| true not supported by BuildKit |
removed the shell redirect; only copy the file that exists |
| 2 | go.mod requires Go 1.25; Docker base image was 1.24 |
bumped Dockerfile FROM golang:1.25-alpine |
| 3 | emqx/emqx:5-alpine tag no longer exists in Docker Hub |
pinned to emqx/emqx:5.10.4 (latest v5 stable) |
| 4 | EMQX 5.10 healthcheck wget against /api/v5/status requires auth |
swapped to bash /dev/tcp/127.0.0.1/1883 — the MQTT TCP port is the real liveness signal |
| 5 | nats:2.10-alpine healthcheck failed because HTTP monitoring needs explicit -m 8222 flag |
added -m 8222 to the nats command line |
| 6 | Host already has a redis on :6379 and a postgres on :5432; docker proxy failed to bind |
changed compose to expose: (no host port mapping) for postgres + redis. App services reach them via docker DNS. |
emqx container shows health: starting indefinitely in step 1; the
TCP probe is succeeding (we can connect to 1883) but docker's
healthcheck machinery seems slow to mark it healthy. Doesn't block
M1. Will revisit in M4.seed container is a one-shot sidecar that doesn't restart. To
re-run it: docker compose up seed.BA_POSTGRES_PASSWORD and BA_REDIS_URL in compose are
dev-only values; production overrides via .env are out of M1
scope.