W3 bms-1 Rollback Playbook — 2026-07-10
Stan aktualny po incydencie 2026-07-09 (postmortem:
docs/incidents/2026-07-09-w3-cascading-outage-postmortem.md) v32-prod działa od: 2026-07-09T22:49:21Z Wszystkie 7 bugów incydentu naprawione i zmergowane domain. Update 2026-07-11: oba wcześniej otwarte ryzyka (poniżej) zamknięte — generyczny pushV32_*(PR 3667) i finalna rotacjaw3_app(PR 3694, propagowana też na reso/socket).
Co teraz działa i dlaczego
| Element | Mechanizm |
|---|---|
| Backend W3 | v32-prod (ECR), env z backend-environment.env via secrets-sync |
| S3 W3 | s3-v32-prod (ECR), env z s3-environment.env via secrets-sync |
| Redis W3 | redis-v32 — redis:7-alpine, statyczny (brak CI/CD) |
| MongoDB W3 | V32_MONGODB_URL = V32_PMONGODB_URL = V32_DB_URI = V32_PINBOX_PROD_DB — zsynchronizowane w SOPS (PR #3612, ponownie wyrównane przy rotacji #3693) |
| Redis client | persistent-patches/crudService.js — node-redis v5 API fix (PR #3607) |
| Twilio/OneSignal | persistent-patches/twilioService.js + pushNotification.helper.js — guard przed crash-loop (PR #3613) |
| Mongoose | persistent-patches/mongoose.js — connect-retry loop (PR #3613) |
| nginx-proxy | VIRTUAL_HOST bez BOM — czyste env od secrets-sync |
secrets-sync.yml key coverage | Generyczny push WSZYSTKICH kluczy V32_* (prefix-stripped), nie wąska lista — PR 3667 |
v32-prod-reso / v32-prod-socket | Osobne compose (/home/p24-server-scripts/v3/v3reso/, .../v3socket/), NIE force-recreate’owane przez secrets-sync, ale ich env pliki są teraz utrzymywane aktualne przy każdym pushu (PR #3694) — patrz §Containers NOT covered w bms1-dr-plan.md |
Obraz ECR (aktualny working)
| Parametr | Wartość |
|---|---|
| ECR image | 563740926945.dkr.ecr.eu-central-1.amazonaws.com/v32-prod:latest |
| Image digest | sha256:c63d663262e190776619ad370439ac31eea0a8a09e60bf80f2366af51d8e0b8eb |
| Image ID (short) | 976d1ac2f4ed |
| Git tag | w3-working-2026-07-10 |
| bms-1 IP | 94.23.26.113 |
| BUILD dir | /home/gitlab-runner/builds/eZQeLfuJe/0/pinbox24/p24-v-3.2/ |
| Env file | /opt/p24-infra/bms-1/pinbox24-w3.env |
Scenariusz A — GitLab CI wytarł env files (główne ryzyko)
Trigger: CI job prod-back-end-deploy uruchamia git clean, który usuwa backend-environment.env i s3-environment.env (są untracked).
Symptomy:
- PM2 crash-loop co 1-2s
api.w3.pinbox24.comzwraca 502/503- Logi:
MongooseError buffering timed outlubusername is required
Rollback (2 minuty):
gh workflow run secrets-sync.yml --repo radieu/p24-infra -f target=pinbox24-w3Secrets-sync: re-deployuje env pliki, persistent-patches, force-recreate v32-prod + s3-v32-prod, oraz od PR #3694 również synchronizuje env v32-prod-reso/v32-prod-socket (bez ich restartu).
Scenariusz B — Nowy obraz ma bug (crash-loop po GitLab deploy)
Pinowanie do działającego digestu:
# SSH na bms-1 (94.23.26.113)
GOOD_IMAGE="563740926945.dkr.ecr.eu-central-1.amazonaws.com/v32-prod@sha256:c63d663262e190776619ad370439ac31eea0a8a09e60bf80f2366af51d8e0b8eb"
cd /home/gitlab-runner/builds/eZQeLfuJe/0/pinbox24/p24-v-3.2
# Podmień image w docker-compose i uruchom
sed -i "s|image:.*v32-prod.*|image: ${GOOD_IMAGE}|" docker-compose.yml
docker-compose up -d --force-recreate backend s3Po weryfikacji — trigger secrets-sync żeby przywrócić oryginalny docker-compose z git:
gh workflow run secrets-sync.yml --repo radieu/p24-infra -f target=pinbox24-w3Scenariusz C — V32_PMONGODB_URL rozjeżdża się z V32_MONGODB_URL
Symptom: logowanie działa (mongojs), ale /api/i18n/langs, formularze, widgety dashboardu zwracają 422 z buffering timed out after 10000ms.
Diagnoza:
docker exec v32-prod printenv MONGODB_URL | cut -c1-30
docker exec v32-prod printenv PMONGODB_URL | cut -c1-30
# Powinny mieć ten sam prefix (ten sam host/user/db)Fix: zsynchronizować oba klucze w SOPS — V32_PMONGODB_URL = V32_MONGODB_URL — przez /request-sm lub sesję secret-manager. Następnie trigger secrets-sync.
Od PR secrets-sync.yml zawiera też defense-in-depth: jeśli te dwa klucze rozjadą się w SOPS, sync sam wymusza PMONGODB_URL = MONGODB_URL przy deployu.
Weryfikacja po rollbacku
# 1. Kontenery running
docker inspect v32-prod --format '{{.State.Status}}' # running
docker inspect s3-v32-prod --format '{{.State.Status}}' # running
docker inspect redis-v32 --format '{{.State.Status}}' # running
# 2. PM2 workers (min. 1)
docker exec v32-prod pm2 jlist | python3 -c \
"import json,sys; p=json.load(sys.stdin); print(sum(1 for x in p if x.get('pm2_env',{}).get('status')=='online'))"
# 3. MongoDB (oba klienty)
docker exec v32-prod sh -c "curl -s http://localhost:3000/api/i18n/langs | head -c 50"
# Oczekiwane: JSON (nie błąd mongoose)
# 4. nginx-proxy widzi kontener
docker exec nginx-proxy curl -s http://v32-prod:3000/api/i18n/langs | head -c 30
# 5. HTTP public
curl -s -o /dev/null -w "%{http_code}" https://api.w3.pinbox24.com/api/i18n/langs
# Oczekiwane: 200
# 6. reso/socket (osobne compose, ale env powinien być aktualny)
docker exec v32-prod-reso printenv MONGODB_URL | grep -oP '://[^:]+:\K[^@]+' | sha256sum | cut -c1-12
docker exec v32-prod printenv MONGODB_URL | grep -oP '://[^:]+:\K[^@]+' | sha256sum | cut -c1-12
# Oczekiwane: te same hasheKrytyczne ryzyka (otwarte follow-upy po incydencie)
| Ryzyko | Status | Obejście |
|---|---|---|
| GitLab CI czyści env files na każdym deploy | OTWARTE — brak auto-retrigger secrets-sync po CI | Ręcznie: target=pinbox24-w3 po każdym CI deploy |
ZAMKNIĘTE — PR 3667: generyczny push wszystkich V32_* | — | |
| ZAMKNIĘTE — PR 3694, propagowane na main+reso+socket, wszystko zweryfikowane | — | |
v32-prod-reso/v32-prod-socket poza force-recreate secrets-sync | ŚWIADOMA DECYZJA (nie ryzyko) — socket.io ma żywe połączenia, env i tak trzymany aktualny (PR #3694) | Ręczny recreate gdy naprawdę potrzebny |
Śledzenie
Issues: #3171 (orchestrator), #3609, #3611, #3612, #3613, #3614, #3660 (naprawione/zamknięte incydenty)
Postmortem: docs/incidents/2026-07-09-w3-cascading-outage-postmortem.md
DR plan: docs/playbooks/bms1-dr-plan.md