docs(ops): the cutover runbook contradicts the compose file about DEMO_MODE #196

Closed
opened 2026-08-27 11:07:42 -05:00 by bermudalamb · 0 comments
Owner

#190 changed DEMO_MODE from a hardcoded compose value to a Portainer stack variable (- DEMO_MODE=${DEMO_MODE}, deliberately with no default) and updated the compose header to match. The cutover runbook, which is the document that actually creates the stack, was not updated in the same change. It now disagrees with the file it deploys, in three places.

docs/ops/production-stack-cutover.md:63 omits DEMO_MODE entirely. That list enumerates the stack variables to record and carry across, and step 6 says "Add the environment variables from steps 2 and 3". An operator following this literally creates the stack without DEMO_MODE, and because there is no default the app refuses to boot. The same line still says "a missing PayPal secret crash-loops the container, because DEMO_MODE is false here" — it is not false here any more.

:231 actively steers the operator away from the answer. It says: "Anything hardcoded there — PAYPAL_ENV, DEMO_MODE, UPLOADS_DIR — cannot be missing, so its absence from the error list proves nothing." An unset DEMO_MODE is now the single most likely cause of a crash loop, and the troubleshooting section tells the reader to rule it out. This is the most dangerous sentence in the file.

:220-227 shows the wrong crash loop. It presents the PayPal-triple failure as "the likeliest outcome of a missed step 2". With DEMO_MODE=true that block cannot occur. The message the operator will actually see is DEMO_MODE is required and must be exactly 'true' or 'false', which appears nowhere in the runbook.

Worth noting what this is: the drift that composeEnvironment.test.ts exists to prevent, reappearing in the one place no test can reach. The guard keeps the compose file honest about its own intent and cannot see the runbook beside it.

Also stale, same cause

docker-compose.prod.yml:77-79 still reads "Live PayPal credentials. Required because DEMO_MODE is false below; the app refuses to start without them." DEMO_MODE is not false below; it is ${DEMO_MODE} at line 142. Same fix, same commit.

Fix

  • Add DEMO_MODE to the :63 stack variable list, with the exactly-true-or-false requirement stated.
  • Remove DEMO_MODE from the "hardcoded, cannot be missing" list at :231.
  • Add the DEMO_MODE is required... error to the crash-loop examples at :220-227.
  • Reword docker-compose.prod.yml:77-79.

Worth one sentence somewhere that Compose only warns on an unset variable and deploys anyway — in Portainer's git-stack UI that warning is easy to miss, and the container then crash-loops under restart: unless-stopped, which is loud in the logs and invisible in a glance at the stack list.

Found by

Code review of the #190/#191/#192 cutover range (5f21d97..fdb5b7a), raised as Critical 2.

#190 changed `DEMO_MODE` from a hardcoded compose value to a Portainer stack variable (`- DEMO_MODE=${DEMO_MODE}`, deliberately with no default) and updated the compose header to match. The cutover runbook, which is the document that actually creates the stack, was not updated in the same change. It now disagrees with the file it deploys, in three places. **`docs/ops/production-stack-cutover.md:63` omits `DEMO_MODE` entirely.** That list enumerates the stack variables to record and carry across, and step 6 says "Add the environment variables from steps 2 and 3". An operator following this literally creates the stack without `DEMO_MODE`, and because there is no default the app refuses to boot. The same line still says "a missing PayPal secret crash-loops the container, because `DEMO_MODE` is false here" — it is not false here any more. **`:231` actively steers the operator away from the answer.** It says: "Anything hardcoded there — `PAYPAL_ENV`, **`DEMO_MODE`**, `UPLOADS_DIR` — cannot be missing, so its absence from the error list proves nothing." An unset `DEMO_MODE` is now the single most likely cause of a crash loop, and the troubleshooting section tells the reader to rule it out. This is the most dangerous sentence in the file. **`:220-227` shows the wrong crash loop.** It presents the PayPal-triple failure as "the likeliest outcome of a missed step 2". With `DEMO_MODE=true` that block cannot occur. The message the operator will actually see is `DEMO_MODE is required and must be exactly 'true' or 'false'`, which appears nowhere in the runbook. Worth noting what this is: the drift that `composeEnvironment.test.ts` exists to prevent, reappearing in the one place no test can reach. The guard keeps the compose file honest about its own intent and cannot see the runbook beside it. ## Also stale, same cause `docker-compose.prod.yml:77-79` still reads "Live PayPal credentials. Required because DEMO_MODE is false below; the app refuses to start without them." `DEMO_MODE` is not false below; it is `${DEMO_MODE}` at line 142. Same fix, same commit. ## Fix - Add `DEMO_MODE` to the `:63` stack variable list, with the exactly-`true`-or-`false` requirement stated. - Remove `DEMO_MODE` from the "hardcoded, cannot be missing" list at `:231`. - Add the `DEMO_MODE is required...` error to the crash-loop examples at `:220-227`. - Reword `docker-compose.prod.yml:77-79`. Worth one sentence somewhere that Compose only *warns* on an unset variable and deploys anyway — in Portainer's git-stack UI that warning is easy to miss, and the container then crash-loops under `restart: unless-stopped`, which is loud in the logs and invisible in a glance at the stack list. ## Found by Code review of the #190/#191/#192 cutover range (`5f21d97..fdb5b7a`), raised as Critical 2.
bermudalamb self-assigned this 2026-08-27 11:29:11 -05:00
bermudalamb added this to the Code Quality and Hardening 2 project 2026-08-27 11:29:21 -05:00
bermudalamb added reference feature/196-runbook-demo-mode 2026-08-27 17:02:23 -05:00
bermudalamb moved this to Review in Code Quality and Hardening 2 on 2026-08-27 17:02:32 -05:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bermudalamb/redefined-designs#196