Update arc: the undo and ladder spiked, the build plan for the 2026-09-23 rulings
gates / gates (push) Successful in 26s

- Part 1 (09 §6.1a, audit): the undo performed by hand on 9202 for docmost
  (PostgreSQL), romm (MariaDB) and vikunja (SQLite volume) - all three came
  back with data written before AND after the backup. The product's loader
  cannot do it: over a migrated PG database it fails on the new tables'
  foreign keys; over MariaDB it leaves them behind. A truncated PG copy loads
  rc 0 into an empty database. No-DB apps have no last-second copy.
- Part 2: one press jumps A -> C; the box's catalog clone is depth 1.
  Ladder format recommended: update_ladder in .felhom.yml, not git history.
- Part 3: memory watch red-proof results (harness change in the catalog repo).
- Part 4 (09 §6.4): ten parts, ~22 evenings; one open point (R-643).
- Rows R-637..R-644 opened; R-446/450/451/462/463 updated. STATUS, CONTEXT.

No product code. Live catalog untouched; 9202 back on it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-23 08:54:41 +02:00
parent 805ad1e962
commit 4c92beab8f
67 changed files with 5977 additions and 162 deletions
@@ -777,6 +777,27 @@ the harness has proven it, is slice 6's.
**Not gated here:** a multi-major jump (R-40). It fails health and is held honestly; stepping is slice 6.
### 6.1a The undo (decision 15) — SPIKED BY HAND 2026-09-23, not built
Evidence: `audits/update-rulings-2026-09-23/README.md`. Three real migrating edges on 9202, each made
to fail a deliberately wrong probe, each held by today's product, each then undone by hand.
| | docmost (PostgreSQL) | romm (MariaDB) | vikunja (SQLite in a volume) |
|---|---|---|---|
| old version on the migrated data, nothing loaded | **refuses** (migration ledger) | **refuses** (alembic revision) | starts and serves |
| the safety dump | DB only, holds the post-backup write | DB only, holds it | **none — no-op** |
| undo, load + start → healthy | **≈ 16 s** | **≈ 38 s** | ≈ 1 s |
| data written before AND after the backup read back | yes / yes | yes / yes | yes / yes |
**The undo works — and not with the loader the product has.** `ImportDump` over a migrated
PostgreSQL database FAILS (the new version's foreign keys block the dump's own drops); over MariaDB it
succeeds and leaves the new version's tables behind. The load that worked empties the schema and loads
the copy in one transaction. **And a truncated PostgreSQL copy loads with exit 0 into an EMPTY
database** — the copy's completion marker must be checked first, which `ValidateDump` does not do. A
product path that loads a safety dump back exists (`rollbackSafetyDump`), but only the off-site
restore calls it. The eight things the build must add are listed in the audit; §6.4 part 1 prices
them.
**The release could not reach the fleet by floor — R-472.** The hub holds a controller floor above the
vouched golden (publish-train rule 1), so under the weekly golden cadence (R-468) v0.237.0 and v0.238.0
were hand-deployed to the demo guests. **RESOLVED by §3 decision 7 (hub v0.112.0):** v0.239.0 reached
@@ -816,10 +837,19 @@ evidence; Slice 6 puts the same shape in the catalog.
"seed_read_before": true, "seed_read_after": true, "healthy_after": true,
"migration_observed": "verbatim log line, or null",
"abort": "starts-and-serves | refuses | starts-data-gone | not-attempted",
"memory": {"soak_s": 600, "containers": {"<name>": {"limit": 0, "peak": 0, "peak_pct": 0.0,
"oom_kills": 0, "restarts": 0}}, "first_kill": null},
"marks": ["memory_tight"],
"abort_detail": "the refusal quoted verbatim, or null",
"duration_s": 0, "measured_at": "RFC3339", "evidence": "relative path"}
```
**Harness version 2 (2026-09-23, R-635) adds `memory` and `marks`.** After a successful readback the
harness runs the new version for `--soak` seconds (default 600) under light load and reads the
kernel's own `oom_kill` counter host-side. A kill or a restart turns `proven` into `failed`; a peak
above 80 % of the compose limit adds `memory_tight`. The two fields are the test record's memory half
(decision 13).
**`inconclusive` is a first-class verdict and must never be collapsed into `failed`.** "We could not
measure it" and "it does not work" are different facts, and only one of them is about the app.
**`migration_observed` is a quoted line, never an inference from timing** — the value of both the
@@ -900,7 +930,16 @@ spend) or the leg gets almost no time. That is a build choice inside decision 11
**How far — one step at a time (decision 14).** A box two steps behind applies step A→B, then B→C,
each the full guarded update, each with its own health check and undo. A failed step stops the
ladder for that app. The ladder's format is §6.4 / `audits/update-rulings-2026-09-23/`.
ladder for that app. **Measured 2026-09-23:** today one press jumps A → C and B never runs, and the
box cannot see B at all — its catalog clone is `--depth 1` (`sync.go:283`, `:300`; one commit
visible on both demo guests).
**The ladder's format — recommended, not ruled** (`audits/update-rulings-2026-09-23/README.md` Part 2):
an `update_ladder:` list in `.felhom.yml`, one entry per step — `from`/`to` refs per service, the
digest per ref, the test record, the marks — and, for every step but the last, the step's OWN
complete definition in `templates/<app>/steps/<to>.yml`. **Not the git history:** romm's image-moving
commit `15f9ebf` is the definition that OOM-looped on demo-hp; the step that works is its images with
the later `f4eb94f` template, and no commit holds that pair.
**When it fails — undo, then hold only if the undo fails (decision 15).** The household is told on
the app page and by **one** mail, in the box's language (R-606 is a precondition — an automatic
@@ -949,7 +988,47 @@ Rank stays P3-LOW at two enrolled boxes. It rises with the fleet, and §2 of the
that looks like today: the only way to answer *"is the fleet current?"* was to read both boxes' files
by hand.
### 6.4 The update night — a drill brief outline, costed from R-462's real numbers
### 6.4 The build order for the 2026-09-23 rulings (PLAN — each part returns to the operator for go/no-go)
Costed in **CC-evenings** (one evening ≈ one unattended session: build, red-proofs, live proof on 9202,
release). Written from the two spikes and the memory watch of 2026-09-23
(`audits/update-rulings-2026-09-23/`), not from source reading alone. **Risk to customer data** is
what the part can do to a household's data if it is wrong, not how likely that is.
| # | part | rulings / rows | cost | depends on | risk to customer data |
|---|---|---|---|---|---|
| **1** | **The undo.** Keep the pre-update copies (compose, applied, pin, **old `.felhom.yml`**) until the undo is over; in `failAndHold`: pin back → DB up alone → **validate the copy's completion marker** → **empty-then-load in one transaction** (PostgreSQL: the dump's schemas dropped and recreated inside the load's transaction; MariaDB: every table dropped first, and a failed load HOLDS with a sentence saying the database is in neither state) → full start → **health with the OLD probe** → `undone`, else HOLD. A volume tar at safety-dump time for apps with no database server. Household page + event; the mail rides part 2. | 15; the audit's 8-point list | **4** | — | **HIGH by nature** — it writes the customer's database. Bounded: it only ever loads the copy taken seconds before, validated first, atomically on PostgreSQL; every failure mode ends in today's hold. **It also makes the manual button safer on its own**, which is why it goes first. |
| **2** | **The update sentences in the household's language** (R-606) and a mail when an automatic update is undone or held. | R-606, 15 | **1** | — | none |
| **3** | **A disabled notifier says so** (R-620), so the mail of part 2 can be measured on a scratch box at all. | R-620 | **0.5** | — | none |
| **4** | **The test record + the catalog gate + the memory check.** The harness writes the ladder entry (below) from its verdict record, including the memory watch's peak and marks; the gate refuses an image move with no entry, an entry with a `failed` verdict, or one with no memory watch; `CompareImageRefs`' rule moves here as the push-time safety net. **Backfill:** one entry per current pin — the 21 proven moves from their records, every other pin `needs_person: "never tested"`, which is honest and keeps them manual. A version move re-checks `mem_limit` against the watch's peak (the RomM follow-up: gate, not checklist, because the watch now produces the number). | 13, R-635 follow-up | **2.5** | the memory watch (shipped 2026-09-23) | none on a box — catalog-side only |
| **5** | **The ladder on the box.** Read `update_ladder:` from the clone, find the installed step, apply ONE step with its OWN definition (`steps/<to>.yml`, the last step the current template), repeat next night; a failed step stops the ladder for that app. `CatalogOrder` compares refs with the digest stripped (see part 7). | 14 | **2.5** | 1, 4 | medium — each step is the guarded update + undo; the new risk is rendering the wrong step's definition, pinned by a test per step shape |
| **6** | **Digests.** The catalog records `sha256` per pin at push time (`check-image-resolvable.py` already resolves it); the box compares it for the badge and renders `name:tag@sha256:…` when present. **Measured 2026-09-23 on 9202:** Docker and Compose both pull and run `redis:7-alpine@sha256:858f…`, and refuse a digest that does not exist (`audits/update-rulings-2026-09-23/70-…`). **Build trap, read from source:** `splitImageRef` returns "unorderable" for ANY ref containing `@` (`updateorder.go:134`), so the digest must be split off before ordering or every digest-pinned app reads Unknown. A digest gone upstream fails the PULL — Scenario E, pin back, nothing ran. | 17, R-446 | **2** | 4 (the entry carries the digest) | low |
| **7** | **The update leg in the chain + the automatic caller + the switch.** A leg that starts when the off-site leg has FINISHED (legs are clock-scheduled today, not chained — a completion signal is new), one app at a time (there is no single-flight, §3b Q4), `app_update.unattended` default ON, `stacks.update_window` removed, reads `UpdateRefusal.Reason`, remembers a failed step so it never re-presses it. **See the one open point below.** | 11, 12 | **3** | 1, 2, 5 | medium — the only part that acts with nobody watching; everything above is what makes it safe |
| **8** | **R-636** — the same OOM key re-firing escalates instead of staying one `warning` for six hours. | R-636 | **1** | — | none |
| **9** | **R-625** — a held app stops offering an Update it will refuse. With the undo, holds become rarer; the lie on the page does not go away by itself. | R-625 | **0.5** | 1 | none |
| **10** | **PostgreSQL majors converted by the box.** A guarded-update step: `pg_dumpall` from the old engine, a NEW datadir (the old one kept aside, never deleted, until the check passes), load, check; then each of the eleven apps proven on the bench before its catalog move. | 16, R-463 | **2 + 3** | 1 (the same load discipline), 4 | **HIGH** — it rebuilds the datadir; bounded by keeping the old datadir aside |
| **11** | **Fleet view** — per compose service: installed ref, catalog ref, badge state in the report; the hub lists boxes behind. | 18, R-451 | 2 | — | none — **deferred by the ruling** until the fleet grows |
**Recommended order: 1 → 2 + 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10**, part 11 when the fleet grows. **Total
for 1–10: ≈ 22 evenings.** The automatic caller (7) is deliberately late: it is the only part that
acts with nobody watching, and every part before it is what makes that safe. Parts 8 and 9 are small
and independent and can fill any short evening.
**The one open point the build cannot settle alone — part 7, inside decision 11.** The ruled chain is
*off-site copy → updates → full-system backup*. Today the off-site leg starts at **W+105m** and the
full-system backup's gate opens at **W+2h** (`quiesce.go` `gateOpenOffsetMin = 120`, span to W+6h). So
the update leg has **at most 15 minutes**, and none on a night the off-site copy runs long — while one
step takes ~1 min when it works and ~2–6 min when it fails and is undone.
| option | cost |
|---|---|
| **the full-system backup waits for the update leg, inside its own window; the leg stops starting new steps at W+5h** | the full-system backup starts later on update nights, still inside its four-hour window, with an hour kept; one more interlock between two nightly jobs |
| the leg stops at W+2h as the chain stands | ≤ 15 min a night — about ten steps on a good night, none on a slow one; a box far behind takes weeks to climb |
**Recommendation: the first.** It keeps the ruling's order and its promise that the full-system backup
is never skipped for an update; only the start time inside its existing window moves.
### 6.4.1 (record) The update night — the drill brief that preceded the rulings, costed and re-costed
**The ruling is decision 6: all 53 apps, through the nightly rotation.** This is an ORDER inside that
ruling, not a scope change. The database apps go first because they are the ones where a wrong answer
@@ -0,0 +1,10 @@
git:
branch: main
repo_url: https://gitea.dooplex.hu/admin/app-catalog-drill.git
sync_interval: 15m
token: <redacted>
username: "admin"
hub:
update:
health_timeout: 90s
@@ -0,0 +1,26 @@
sync: 429
rescan: 200
--- control 1: 9202 follows the drill catalog
cache=/var/lib/docker/volumes/felhom-controller-data/_data/data/catalog-cache
02844ae decoys: eight cases for the probe target rule (R-630)
https://<cred>@gitea.dooplex.hu/admin/app-catalog-drill.git
image: docmost/docmost:0.96.0
docmost catalog_images= None
vikunja catalog_images= None
romm catalog_images= None
--- control 2: demo-hp guest 9201 still follows the live catalog
02844ae decoys: eight cases for the probe target rule (R-630)
https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
--- control 3: live catalog main unchanged
02844ae0a579e8bf66882d01598c2212264a1b78 refs/heads/main
=== retry after the 429 (a sync was already in flight at startup)
sync: 200 {'ok': True, 'data': {'ok': True, 'updated': ['docmost', 'romm', 'vikunja'], 'message': 'Sablonok frissítve — frissítve:
rescan: 200
193001a DRILL: FROM states for the undo spike (docmost 0.95.0, vikunja 2.3.0, romm 5.0.0)
image: docmost/docmost:0.95.0
image: vikunja/vikunja:2.3.0
image: rommapp/romm:5.0.0
@@ -0,0 +1,15 @@
### guest 9202 (currently on the DRILL catalog)
shallow: true
/var/lib/docker/volumes/felhom-controller-data/_data/data/catalog-cache/.git/shallow
has .git/shallow
commits reachable from HEAD: 1
commits touching templates/docmost/docker-compose.yml:
419f243 DRILL docmost: docmost/docmost:0.95.0 -> docmost/docmost:0.96.0
... total 1
template B readable at an older commit?
### guest 9201 demo-hp (the LIVE catalog, never repointed)
shallow: true
commits: 1
romm compose history: 1
02844ae 2026-09-22 decoys: eight cases for the probe target rule (R-630)
@@ -0,0 +1,24 @@
08:25:27 === Part 2.1 — today's behaviour with a box TWO catalog steps behind
08:25:30 installed now: {'vikunja': 'vikunja/vikunja:2.3.0'}
08:25:30 [5] drill commit 610ed1a66dee: vikunja vikunja/vikunja:2.6.0 -> vikunja/vikunja:2.4.0 (push rc=0)
08:25:31 [5] drill commit c71807f5d47e: vikunja vikunja/vikunja:2.4.0 -> vikunja/vikunja:2.5.0 (push rc=0)
08:25:31 drill commits: step B 610ed1a66dee (2.4.0), step C c71807f5d47e (2.5.0)
08:25:36 badge caught up after 4.5 s; catalog_images = {'vikunja': 'vikunja/vikunja:2.5.0'}
08:25:36 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
08:25:36 + 0.0s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None
08:25:37 + 0.6s phase=pulling label=Új verzió letöltése… err=None hold=None
08:25:40 + 3.7s phase=starting label=Indítás az új verzióval… err=None hold=None
08:25:41 + 4.7s phase=verifying label=Működés ellenőrzése… err=None hold=None
08:25:45 + 9.5s phase=done label=Frissítve err=None hold=None
08:25:45 {"final_phase": "done", "update_error": null, "hold_reason": null, "state": "running", "duration_s": 9.5}
08:25:48 AFTER ONE PRESS: {"pinned_images": {"vikunja": "vikunja/vikunja:2.5.0"}, "installed_images": {"vikunja": "vikunja/vikunja:2.5.0"}, "catalog_images": {"vikunja": "vikunja/vikunja:2.5.0"}, "live_compose_image_lines": ["image: vikunja/vikunja:2.5.0"], "docker_inspect": ["vikunja vikunja/vikunja:2.5.0 running=true restarts=0"]}
08:25:50 time=2026-09-23T08:25:40.726+02:00 level=INFO msg="Running migrations…"
time=2026-09-23T08:25:40.747+02:00 level=INFO msg="Ran all migrations successfully."
time=2026-09-23T08:25:40.757+02:00 level=INFO msg="Vikunja version v2.5.0"
2026/09/23 06:22:30 pin.go:362: [INFO] [stacks] update vikunja: pin advanced to the catalog's current definition (vikunja=vikunja/vikunja:2.6.0)
2026/09/23 06:25:36 update.go:623: [INFO] [stacks] update vikunja: precondition met — Tier 1 (own recovery unit) copy from 2026-09-23T06:24:24Z (1m0s old, limit 24h0m0s)
2026/09/23 06:25:36 pin.go:362: [INFO] [stacks] update vikunja: pin advanced to the catalog's current definition (vikunja=vikunja/vikunja:2.5.0)
2026/09/23 06:25:45 update.go:737: [INFO] [stacks] update vikunja: DONE in 9s
08:25:51 vikunja: readback of the seeded project http=200 ok=True
08:25:51 seed A after the jump: True
@@ -0,0 +1,18 @@
08:26:52 [X] stop -> 200 {'ok': True, 'message': 'Stack docmost stop completed'}
08:27:24 [X] remove (with drive data) -> 200 {'ok': True, 'data': {'removed': 'docmost', 'volumes_removed': ['docmost_docmost_postgres_data', 'docmost_docmost_redis_data', 'docmost_docmost_storage'], 'hdd_
08:27:32 [X] after remove: deployed=False leftovers='/opt/docker/stacks/docmost'
08:27:34 [X] stop -> 200 {'ok': True, 'message': 'Stack romm stop completed'}
08:27:39 [X] remove (with drive data) -> 409 {'ok': False, 'error': 'A(z) /mnt/felhom-drives/scratch_hdd/userdata/romm tárhely jelenleg nem elérhető — az alkalmazás nem távolítható el, amíg a meghajtó viss
08:27:39 [X] refused because the drive path cannot be resolved (R-442, fail-closed and right) — removing the app and KEEPING the drive data instead
08:28:06 [X] remove (keeping drive data) -> 200 {'ok': True, 'data': {'removed': 'romm', 'volumes_removed': ['romm_romm_config', 'romm_romm_db_data', 'romm_romm_redis_data'], 'hdd_paths_removed': [], 'hdd_pat
08:28:13 [X] after remove: deployed=False leftovers='/opt/docker/stacks/romm'
08:28:14 [X] stop -> 200 {'ok': True, 'message': 'Stack vikunja stop completed'}
08:28:45 [X] remove (with drive data) -> 200 {'ok': True, 'data': {'removed': 'vikunja', 'volumes_removed': ['vikunja_vikunja_data', 'vikunja_vikunja_db'], 'hdd_paths_removed': [], 'hdd_paths_preserved': [
08:28:53 [X] after remove: deployed=False leftovers='/opt/docker/stacks/vikunja'
08:29:15 docmost: containers=0 volumes=0 stackdir-appyaml=0
romm: containers=0 volumes=0 stackdir-appyaml=0
vikunja: containers=0 volumes=0 stackdir-appyaml=0
08:29:15 docmost deployed= False hold= None
08:29:15 romm deployed= False hold= None
08:29:15 vikunja deployed= False hold= None
@@ -0,0 +1,10 @@
installed: redis@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
ref with tag AND digest: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
docker.io/library/redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
pull rc=0
image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
Redis server v=7.4.11 sha=00000000:0 malloc=jemalloc-5.3.0 bits=64 build=40ff01a501d8e4b6
negative control — a digest that does not exist:
Error response from daemon: manifest for redis@sha256:0000000000000000000000000000000000000000000000000000000000000000 not found: manifest unknown: manifest unknown
rc=0
NOTE (added after the run): the 'rc=0' on the last line is the exit code of the 'tail' in that pipe, NOT of docker pull — the refusal is the daemon's own sentence above it.
@@ -0,0 +1,17 @@
git:
branch: main
repo_url: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
sync_interval: 15m
token: <redacted>
username: ""
hub:
0
sync: 200 {'ok': True, 'data': {'ok': True, 'message': 'Sablonok naprakészek — nincs változás'}, 'message': 'S
02844ae decoys: eight cases for the probe target rule (R-630)
https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
0
controller.yaml == the saved pre-rulings copy
02844ae0a579e8bf66882d01598c2212264a1b78 refs/heads/main
@@ -0,0 +1,7 @@
02844ae decoys: eight cases for the probe target rule (R-630)
405a127 probe target: explicit container for paperless-ngx and immich; ambiguity refused (R-630)
dcb6b1d CHANGELOG: the six proven moves (R-462)
8898b1d termix: 2.5.0 -> 2.8.0 (proven on 9202, R-462)
0b283d2 sonarr: 4.0.19 -> 4.0.20 (proven on 9202, R-462)
b7b0479 radarr: 6.3.0 -> 6.4.4 (proven on 9202, R-462)
(drill commits made this session, now reset away: 193001a 419f243 57a4be3 88613e2 610ed1a c71807f; drill HEAD == origin == live == 02844ae0a579; image lines identical)
@@ -0,0 +1,22 @@
containers now:
felhom-controller gitea.dooplex.hu/admin/felhom-controller:0.262.1 Up 13 minutes (healthy)
filebrowser gtstef/filebrowser:1.3.3-stable Up 36 minutes (healthy)
gokapi f0rc3/gokapi:v1.9.6 Restarting (1) 33 seconds ago
paperless-postgres postgres:16-alpine Up 32 minutes (healthy)
paperless-redis redis:7-alpine Up 32 minutes (healthy)
paperless-webserver ghcr.io/paperless-ngx/paperless-ngx:2.20.15 Up 32 minutes (healthy)
privatebin privatebin/pdo:2.0.6 Up 32 minutes (healthy)
traefik traefik:v3.6.7 Up 35 hours
/opt/upg removed
removed docmost/docmost:0.95.0
removed docmost/docmost:0.96.0
removed rommapp/romm:5.0.0
removed rommapp/romm:5.3.0
removed vikunja/vikunja:2.3.0
absent vikunja/vikunja:2.4.0
removed vikunja/vikunja:2.5.0
removed vikunja/vikunja:2.6.0
romm drive folder removed
calibre-web documents downloads emby immich jellyfin komga media nextcloud paperless-ngx plex radarr roms sonarr
no leftover volumes
/dev/loop1 69G 43G 23G 67% /var/lib/felhom
@@ -0,0 +1,178 @@
# Update rulings 2026-09-23 — the undo spike, the ladder spike, the memory watch
Venue: scratch guest **9202** on demo-hp, controller v0.262.1, pointed at the **drill catalog**
(`admin/app-catalog-drill`, reset to live `02844ae0a579` first) with `update.health_timeout: 90s`.
The live catalog carried no test reference at any point (control 3 in `02-three-controls.txt`).
Architecture document for the area: `architecture/09-update-architecture.md` (§3 decisions 11–18,
§6.1a, §6.4).
**Method honesty.** The product has no undo path, so the undo was performed BY HAND, in the order
the product would take it, each step timed. Where a product path exists it was used: the Update, the
Start, the Remove, the backup. Lifting the hold used the operator CLI `--clear-restore-hold` plus a
controller restart (the only exit that exists today). **An attempt to decrypt the app's secrets so
compose could be run by hand was refused by the session's safety guard; that route was dropped, not
worked around** — the product's own Start supplies the secrets.
---
## Part 1 — the automatic undo, by hand
### Does a product path already load a safety dump back?
**Yes, one — and the update never calls it.** `backup.Manager.rollbackSafetyDump`
(`internal/backup/offbox_reconstitute.go:413`) re-applies a `pre-restore-*` undo copy through
`ImportDump` — but only inside `ReconstituteFromOffsite`. `runGuardedUpdate` → `failAndHold`
(`internal/stacks/update.go:766`) writes the safety dump in phase 3 and never reads it again.
**And `failAndHold` deletes the journal's pre-update definition copies** (`removePreUpdateCopies`),
so after a hold the old definition survives only in the recovery unit's `compose/` directory. It was
there in all three cases because a backup preceded each update; that is not guaranteed.
### The four cases — each a REAL migration that then failed a deliberately wrong probe
| case | edge (drill) | what migrated | the safety dump | old version on the migrated data, nothing loaded | the load | undo → healthy | seed A (before backup) | seed B (after backup) |
|---|---|---|---|---|---|---|---|---|
| **PostgreSQL** docmost | 0.95.0 → 0.96.0, held 95.3 s | 4 migrations, 42 → 48 tables (`docmost-31`) | 135 816 B, DB only, **holds B** (tier copy does not) | **REFUSES** — *corrupted migrations: previously executed migration 20260824T211732-page-title-trgm-index is missing* | product semantics **FAILS** (below); fixed load **1.38 s** | **14.8 s** | yes | **yes** |
| **MariaDB** romm | 5.0.0 → 5.3.0, held 102.6 s | alembic 0095 → 0128, 27 → 39 tables | 62 943 B, DB only, **holds B** | **REFUSES** — *Can't locate revision identified by '0128_hltb_main_story_column'* | product semantics **1.25 s**, rc 0 — **12 new tables left behind** | **36.5 s** | yes | **yes** |
| **Volume data, no DB server** vikunja | 2.3.0 → 2.6.0, held 93.3 s | *Ran all migrations successfully* (SQLite in a volume) | **none** — *the app has no database — nothing to copy (no-op)* | **STARTS AND SERVES** in 0.7 s, A, B and B's attachment read back | — | 0.7 s | yes | **yes** |
| vikunja, **if it had refused** | the only other copy: the tier unit's volume tar | — | — | — | volume put back from the tier copy **0.86 s** | — | yes | **NO — lost** |
| **Files on disk** | vikunja's attachment (a file in the files volume, written after the backup); romm's two drive folders | none touched the files | the undo copy never holds files | the attachment read back after the update AND after the undo | — | — | — | attachment yes |
Three different apps, three mechanisms of refusal now measured (Nextcloud's version check §4, docmost's
migration ledger, RomM's alembic revision) — and in each refusing case **the undo made the old version
start**, because it met the data it knew.
**romm's drive folders were empty before, after the update and after the undo** (tree hash
`e3b0c442…` throughout) — so they measured nothing, and are reported as unmeasured, not as "untouched".
### The finding that shapes decision 15's build: the product's loader cannot undo a migration
`ImportDump` replays a `pg_dump --clean --if-exists` file over the live database. **Over a database
the new version migrated, that FAILS**: the new version created six tables (`oauth_*`,
`public_spaces`, `siem_destinations`) whose foreign keys point at old tables, and the dump's own
`DROP … workspaces_pkey` is refused — *cannot drop constraint workspaces_pkey on table
public.workspaces because other objects depend on it* — rc 3 in 0.40 s, database unchanged
(`docmost-45`). The same loader on MariaDB "succeeds" (`FOREIGN_KEY_CHECKS=0`) and leaves the new
version's **12 tables** behind; RomM 5.0.0 happens to ignore them.
**What worked:** empty the schema and load the copy **in ONE transaction** —
`DROP SCHEMA public CASCADE; CREATE SCHEMA public;` + the dump, `psql --single-transaction
ON_ERROR_STOP=1`: rc 0 in 1.38 s, 42 tables, 48 ledger rows, `pg_trgm` and `unaccent` back.
### The wrong case — a truncated undo copy
| engine / loader | exit | what it left | is the outcome honest? |
|---|---|---|---|
| PostgreSQL, product semantics | rc 3 | unchanged (it failed on the foreign key before reaching the cut) | yes — nothing moved; the hold's named copy is intact |
| **PostgreSQL, the fixed atomic load** | **rc 0 (!)** | **42 tables and 48 ledger rows — and 0 users, 0 spaces, 0 constraints, 0 indexes** (`docmost-47`, measured in a scratch database beside the real one) | **NO.** psql treats end-of-file inside a `COPY` as end of data and commits. The undo would report success, the old version would start on an EMPTY database, and a health check would pass on it. No hold. |
| MariaDB, product semantics | rc 1 in 0.94 s | **half-replaced**: alembic back to 0095, later tables still the new version's — neither state | partly — the load is not transactional; the hold names the tier copy, which can still bring the app back |
**The check that separates them already exists in the files:** the whole PostgreSQL copy ends with
`-- PostgreSQL database dump complete` (and a `\unrestrict` line), the MariaDB copy with
`-- Dump completed`; the truncated copies have neither. **`ValidateDump` does not look for them** — it
checks the header and one `CREATE TABLE` (`internal/appbackup/dbdump.go:415`, read from source), so it
would accept both truncated copies.
### Seconds
| | find the copy | old definition + pin back | load | start → healthy (old probe) | undo total |
|---|---|---|---|---|---|
| docmost | 0.04 s | 0.03 s | 1.38 s | 14.8 s | **≈ 16 s** |
| romm | 0.04 s | 0.04 s | 1.25 s | 36.5 s | **≈ 38 s** |
| vikunja | — | 0.02 s | none | 0.7 s | **≈ 1 s** |
Plus the failing health wait that precedes any undo (`update.health_timeout`, 90 s here, 5 min by
default). Lifting the hold by hand cost 15.8 s (CLI + restart) and is NOT part of a product undo,
which would never hold in the first place.
### What the product must add — the list decision 15's build starts from
1. **Keep the pre-update copies until the undo is over** — compose, applied definition, pin **and the
old `.felhom.yml`**. `failAndHold` deletes the first three today; the fourth was never kept.
2. **The undo step inside `failAndHold`:** `pinBack` (exists) → DB service up alone → validated load →
full start → **health check with the OLD `.felhom.yml` probe** (the new one may name a port the old
version does not answer — it did in this spike by construction) → `undone`, or HOLD.
3. **The loader must empty the database first, atomically.** PostgreSQL: drop and recreate exactly
the schemas the dump creates, in the same transaction as the load. MariaDB: drop every table first
(`FOREIGN_KEY_CHECKS=0`); its DDL is not transactional, so a failed load is a HOLD with a sentence
saying the database is in neither state.
4. **Validate the copy's completion marker before loading**, both engines. A truncated PostgreSQL copy
is otherwise a silent, successful load of an empty database.
5. **Apps with no database server need their own last-second copy**: a tar of the data volumes at
safety-dump time (vikunja: 2.2 MB, put back in 0.86 s). Without it, an app whose old version
refuses loses everything written since the last backup. Vikunja's old version happens to start —
**a per-app fact the test record should carry**, not a rule.
6. **Files on disk:** nothing measured was touched by a migration, and the undo does nothing to files.
A step that does rewrite files must say so — decision 13's *files may change* mark is that place.
7. **The Start button says `start completed` (200) while the app crash-loops** (docmost and romm, both
negative controls). The undo's success must be the probe, never the start's return.
8. **No retry:** after an undo the badge reads „Frissítés elérhető" again, because the catalog is still
ahead. The caller must remember the failed step (decision 15), or it presses it every night.
---
## Part 2 — the ladder
### Today's behaviour, measured (`51-part2-ladder-today.txt`)
vikunja installed at **2.3.0**; the drill catalog then got step **B = 2.4.0** (`610ed1a66dee`) and
step **C = 2.5.0** (`c71807f5d47e`); one sync, one press. **Result: `done` in 9.5 s, pin, installed
record, live compose and container all `vikunja/vikunja:2.5.0`; 2.4.0 never ran.** The box jumps.
### Can the box see the steps? No (`50-part2-clone-depth.txt`)
Both 9202 (drill) and 9201 (live) hold a **shallow clone of depth 1**: `is-shallow-repository true`,
`rev-list --count HEAD` = **1**, one commit visible per template. Source agrees:
`sync.go:283` clones `--depth 1`, `sync.go:300` fetches `--depth 1`. **The brief's premise that "the
box keeps a git clone" with history is wrong** — it keeps a clone of the newest commit only.
### The format — two options, one recommended
**Size is not the cost.** The whole catalog history is 529 KiB packed, 286 commits.
**The cost is that history does not contain the tested steps.** romm's compose has **16 commits, 3
of which move an image**; the step that works today is *15f9ebf's images with f4eb94f's template*
(two workers, 768M) — **the commit that moved the image is the one that OOM-looped on demo-hp**. A box
walking history would apply the definition that is known to be broken.
| option | what it is | cost |
|---|---|---|
| **A — `update_ladder:` in `.felhom.yml` (recommended)** | per app, one entry per step: `from` and `to` refs per service, the digest per ref (decision 17), the test record (verdict, date, harness version, memory peak), the marks (`files_may_change`, `needs_person: "<why>"`), and — for every step that is NOT the last — the step's own complete definition in `templates/<app>/steps/<to>.yml`. The last step is the current `docker-compose.yml`. | every image move adds an entry (the catalog gate enforces it: no entry, no move — decision 13); an intermediate definition that needs a fix is fixed in its step file too, or the step is retired; entries older than the support window are pruned. `.felhom.yml` already flows to frozen apps (§5.4), so the box sees the ladder while frozen; step files are read from the clone. |
| B — the box walks the catalog's git history | deepen the clone, treat each image-moving commit as a step | every box carries full history; a history rewrite breaks every box; a commit is not a tested step and cannot be made one retroactively; **and it applies the broken intermediate definition measured above** |
The test record and the marks of decision 13 live in the same entry, so one gate reads one place.
---
## Part 3 — the memory watch in the harness (`app-catalog-felhom.eu/scripts/upgrade-test.py` v2)
After an edge reads back, the harness runs the new version for `--soak` seconds (default 600) under
four light callers and samples every 15 s, per container: memory against the compose limit, the
**kernel's own `oom_kill` counter read host-side** (`/sys/fs/cgroup/system.slice/docker-<id>.scope/
memory.events` — works on images with no shell, and does not depend on Docker's OOMKilled flag, which
has read false for real kills on this kind of guest), the peak, and restarts. A kill or a restart →
`failed`; a peak above 80 % → mark `memory_tight`.
Run on 9202 in `/opt/upg` with raw compose (no controller in the path), after Part 1's apps were
removed so the fixed `container_name`s could not collide.
| edge | template | verdict | memory |
|---|---|---|---|
| **M1old** — the red-proof | as promoted, catalog `15f9ebf`: 512M, four workers | **failed** | seeded, migrated (2 lines), read back — then **first kernel OOM kill at +76 s**, peak 512 MiB = **100 %**, restarts **0** (the container kept running, which is how it hid on demo-hp), Docker's OOMKilled read true here; abort `refuses` |
| **M1** — the positive control | current: 768M, two workers | **proven** + mark `memory_tight` | 608.5 s under 11 429 requests (5 712 × 200, 5 717 × 401): **0 kernel OOM kills, 0 restarts**, peak 621 MiB = **81 %** of 768 MiB — the watch passes the fix and still flags the thin headroom R-635 left open |
**Is ten minutes long enough?** For this failure, under load, yes by a wide margin: +76 s. demo-hp's
first kill came two hours in only because nothing was loading the app. What ten minutes cannot see is
a leak that grows over days; that is a monitoring question (R-636), not a test-bench one.
Evidence: `harness/M1old.log`, `harness/evidence/M1old/` (verdict, memory samples, logs), and the same
for M1.
---
## Controls and teardown
- `02-three-controls.txt` — 9202 followed the drill catalog; 9201 stayed on the live one; the live
catalog's `main` was `02844ae0a579` before and after.
- `60-part1-teardown.txt` — docmost, romm, vikunja removed through the product; romm's drive data was
kept by the product (R-442's fail-closed refusal on 9202, as in every earlier drill) and removed by
name at the end.
@@ -0,0 +1,18 @@
07:58:58 deploy docmost at the drill FROM pin
07:58:58 [1] deploy -> 202 {'ok': True, 'message': 'Telepítés elindítva – az állapot a kártyán követhető'}
08:00:39 [1] deployed, controller state=unhealthy, pinned={'docmost': 'docmost/docmost:0.95.0', 'docmost-postgres': 'postgres:16-alpine', 'docmost-redis': 'redis:7-alpine'}
08:00:39 [1] NOTE: the controller's own state is 'unhealthy', not 'running' — recorded, not treated as a failure; the fixture's front-door wait is the real gate
08:00:39 deployed: True
08:00:41 {"pinned_images": {"docmost": "docmost/docmost:0.95.0", "docmost-postgres": "postgres:16-alpine", "docmost-redis": "redis:7-alpine"}, "installed_images": {"docmost": "docmost/docmost:0.95.0", "docmost-postgres": "postgres:16-alpine", "docmost-redis": "redis:7-alpine"}, "catalog_images": null, "live_compose_image_lines": ["image: docmost/docmost:0.95.0", "image: postgres:16-alpine", "image: redis:7-alpine"], "docker_inspect": ["docmost docmost/docmost:0.95.0 running=true restarts=0", "docmost-postgres postgres:16-alpine running=true restarts=0", "docmost-redis redis:7-alpine running=true restarts=0"]}
08:00:42 docmost: /api/auth/setup http=200 rc=0
08:00:42 seed A: True
08:00:42 docmost: login as the seeded user http=200 ok=True
08:00:42 C1 A reads back: True
08:00:48 login 200 {"success":true,"status":200}
nR5cCI6IkpXVCJ9.eyJzdWIiOiIwMWEwY2NkYS0xZWViLTc4NTItOGRjNi1lMjNmZmExMzE0ODEiLCJlbWFpbCI6ImRyaWxsLTQ2NjFhMWVhQGdhdGUuaW52YWxpZCIsIndvcmtzcGFjZUlkIjoiMDFhMGNjZGEtMWVmMi03OGU1LTkwZjUtMDhlYTEyNDI5Mzk1IiwidHlwZSI6ImFjY2VzcyIsInNlc3Npb25JZCI6IjAxYTBjY2RhLTM5N2MtNzQ1ZS1iZmI2LWYyZWZmZDg0YWQ0MiIsImlhdCI6MTc5MDE0MzI0OCwiZXhwIjoxNzk3OTE5MjQ4LCJpc3MiOiJEb2Ntb3N0In0.uvcxRF50aQGZA_DniKLWO9BhFV8rEI1AYsOmNVxlUNU
08:00:59 [4] „Mentés most" -> 200 {'ok': True, 'message': 'Mentés elindítva'}
08:01:39 [4] backup idle; last=None
08:01:39 docmost seed B: /api/spaces/create http=200 {"data":{"id":"01a0ccdb-009f-7975-a992-d0486e2b67e4","name":"drillB3c2580","description":"","slug":"drillb3c2580","logo":null,"visibility":"private","defaultRol
08:01:40 docmost B: /api/spaces http=200 seeded-space-listed=True (negative control listed=False)
08:01:40 B reads back: True
@@ -0,0 +1,16 @@
08:01:53 pg before update (tables | last 3 migrations | count):
42
20260620T010047-personal-spaces
20260529T125146-bases
20260509T121236-labels
48
08:01:54 [5] drill commit 419f24385ddf: docmost docmost/docmost:0.95.0 -> docmost/docmost:0.96.0 (push rc=0)
checks:
- type: http
port: 3999
# --- English copy (localisation slice 5, R-560) -------------------------
08:01:58 badge caught up after 4.5 s
08:01:58 {"hu": [{"title": "Újabb változat érhető el ehhez az alkalmazáshoz. A frissítés indításához nyomd meg a Frissítés gombot.", "text": "Frissítés elérhető — ma"}], "en": [{"title": "A newer version of this app is available. Select the Update button to start it.", "text": "Update available — today"}]}
@@ -0,0 +1,24 @@
08:02:05 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
08:02:05 + 0.0s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None
08:02:06 + 1.1s phase=pulling label=Új verzió letöltése… err=None hold=None
08:02:07 + 2.1s phase=starting label=Indítás az új verzióval… err=None hold=None
08:02:08 + 3.1s phase=verifying label=Működés ellenőrzése… err=None hold=None
08:03:40 + 95.3s phase=failed label=A frissítés nem sikerült err=A(z) docmost frissítése 2026-09-23 08:03-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: saját meghajtó, 2026-09-23 08:01 — ez a másolat a beállításokat, az adatbázist és az adatköteteket tartalmazza. hold=A(z) docmost frissítése 2026-09-23 08:03-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: saját meghajtó, 2026-09-23 08:01 — ez a másolat a beállításokat, az adatbázist és az adatköteteket tartalmazza.
08:03:40 {"final_phase": "failed", "update_error": "A(z) docmost frissítése 2026-09-23 08:03-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: saját meghajtó, 2026-09-23 08:01 — ez a másolat a beállításokat, az adatbázist és az adatköteteket tartalmazza.", "hold_reason": "A(z) docmost frissítése 2026-09-23 08:03-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: saját meghajtó, 2026-09-23 08:01 — ez a másolat a beállításokat, az adatbázist és az adatköteteket tartalmazza.", "state": "stopped", "duration_s": 95.4}
08:03:43 {"pinned_images": {"docmost": "docmost/docmost:0.96.0", "docmost-postgres": "postgres:16-alpine", "docmost-redis": "redis:7-alpine"}, "installed_images": {"docmost": "docmost/docmost:0.95.0", "docmost-postgres": "postgres:16-alpine", "docmost-redis": "redis:7-alpine"}, "catalog_images": {"docmost": "docmost/docmost:0.96.0", "docmost-postgres": "postgres:16-alpine", "docmost-redis": "redis:7-alpine"}, "live_compose_image_lines": ["image: docmost/docmost:0.96.0", "image: postgres:16-alpine", "image: redis:7-alpine"], "docker_inspect": []}
08:03:45 total 28
drwxr-xr-x 3 root root 4096 Sep 23 06:03 .
drwxr-xr-x 57 root root 4096 Sep 13 20:22 ..
-rw-r--r-- 1 root root 3998 Sep 23 06:01 .felhom.yml
-rw------- 1 root root 1184 Sep 23 06:02 app.yaml
-rw-r--r-- 1 root root 3105 Sep 23 06:02 applied-compose.yml
-rw-r--r-- 1 root root 3105 Sep 23 06:02 docker-compose.yml
drwxr-xr-x 3 root root 4096 Sep 23 06:03 hold-logs
hold-logs:
20260923T060338Z
hold-logs/20260923T060338Z:
compose-logs.txt
@@ -0,0 +1,8 @@
=== migration lines in the kept hold log
docmost | {"level":"info","time":"2026-09-23T06:02:19.400Z","pid":45,"hostname":"8ddf85c23281","context":"DatabaseMigrationService","msg":"Migration \"20260824T211732-page-title-trgm-index\" executed successfully"}
docmost | {"level":"info","time":"2026-09-23T06:02:19.400Z","pid":45,"hostname":"8ddf85c23281","context":"DatabaseMigrationService","msg":"Migration \"20260825T022612-oauth\" executed successfully"}
docmost | {"level":"info","time":"2026-09-23T06:02:19.400Z","pid":45,"hostname":"8ddf85c23281","context":"DatabaseMigrationService","msg":"Migration \"20260902T121326-siem-destinations\" executed successfully"}
docmost | {"level":"info","time":"2026-09-23T06:02:19.400Z","pid":45,"hostname":"8ddf85c23281","context":"DatabaseMigrationService","msg":"Migration \"20260904T171920-public-spaces\" executed successfully"}
=== where is the unit
/mnt/sys_drive/felhom-data/backups/primary/docmost
/var/lib/felhom/sys_drive/felhom-data/backups/primary/docmost
@@ -0,0 +1,33 @@
=== step 1: the safety dump the update wrote (unit: /mnt/sys_drive/felhom-data/backups/primary/docmost)
/mnt/sys_drive/felhom-data/backups/primary/docmost:
total 24
drwxr-xr-x 5 root root 4096 2026-09-23 06:01:37.035847153 +0000 .
drwxr-xr-x 7 root root 4096 2026-09-23 06:00:59.201405588 +0000 ..
drwxr-xr-x 2 root root 4096 2026-09-23 06:01:37.035847153 +0000 compose
drwxr-xr-x 2 root root 4096 2026-09-23 06:02:05.524179635 +0000 db-dumps
-rw-r--r-- 1 root root 1298 2026-09-23 06:01:37.035847153 +0000 manifest.json
drwxr-xr-x 2 root root 4096 2026-09-23 06:01:02.101439434 +0000 volume-dumps
/mnt/sys_drive/felhom-data/backups/primary/docmost/db-dumps:
total 276
drwxr-xr-x 2 root root 4096 2026-09-23 06:02:05.524179635 +0000 .
drwxr-xr-x 5 root root 4096 2026-09-23 06:01:37.035847153 +0000 ..
-rw-r--r-- 1 root root 134941 2026-09-23 06:00:59.482408868 +0000 docmost-postgres.sql
-rw-r--r-- 1 root root 135816 2026-09-23 06:02:05.511179483 +0000 pre-restore-20260923T060205Z-docmost-postgres.sql
/mnt/sys_drive/felhom-data/backups/primary/docmost/volume-dumps:
total 50608
drwxr-xr-x 2 root root 4096 2026-09-23 06:01:02.101439434 +0000 .
drwxr-xr-x 5 root root 4096 2026-09-23 06:01:37.035847153 +0000 ..
-rw-r--r-- 1 root root 51780096 2026-09-23 06:01:01.084427565 +0000 docmost_docmost_postgres_data.tar
-rw-r--r-- 1 root root 25088 2026-09-23 06:01:01.592631070 +0000 docmost_docmost_redis_data.tar
-rw-r--r-- 1 root root 1536 2026-09-23 06:01:01.967437870 +0000 docmost_docmost_storage.tar
newest undo copy: /mnt/sys_drive/felhom-data/backups/primary/docmost/db-dumps/pre-restore-20260923T060205Z-docmost-postgres.sql
size: 135816 bytes
holds: 42 CREATE TABLE, 42 COPY blocks, drop-first: 42 DROP TABLE IF EXISTS
migration ledger rows in the dump:
48
seed B (space created after the backup) in the dump: 1
seed B in the unit's canonical dump (the tier copy): 0
unit compose image:
step 1 took 0.04s
@@ -0,0 +1,19 @@
total 20
drwxr-xr-x 2 root root 4096 Sep 23 06:01 .
drwxr-xr-x 5 root root 4096 Sep 23 06:01 ..
-rw-r--r-- 1 root root 3998 Sep 23 06:01 .felhom.yml
-rw------- 1 root root 445 Sep 23 06:01 app.yaml
-rw-r--r-- 1 root root 3105 Sep 23 06:01 docker-compose.yml
16: image: docmost/docmost:0.95.0
56: image: postgres:16-alpine
80: image: redis:7-alpine
=== the pre-update copies the journal kept: 0 (failAndHold removes them)
=== pin now:
pinned_images:
docmost: docmost/docmost:0.95.0
docmost-postgres: postgres:16-alpine
docmost-redis: redis:7-alpine
16: image: docmost/docmost:0.95.0
56: image: postgres:16-alpine
80: image: redis:7-alpine
step 2 took 0.03s
@@ -0,0 +1,14 @@
81: port: 3000
/usr/local/bin/felhom-controller --config /opt/docker/felhom-controller/controller.yaml
flag provided but not defined: -list-restore-holds
Usage of /usr/local/bin/felhom-controller:
-abandon-extend int
R-241 (operator): extend a running abandonment countdown by N days from now, then exit. Refuses when no countdown is running.
-abandon-status
NOW RESTART THE CONTROLLER, or it will keep refusing to start the app:
systemctl restart felhom-controller-bootstrap.service
Check the app's data first — the undo copies are in its unit's db-dumps dir.
flag provided but not defined: -list-restore-holds
Usage of /usr/local/bin/felhom-controller:
-abandon-extend int
step 2b (hold lifted + controller restart) took 15.80s
@@ -0,0 +1,16 @@
08:08:07 hold_reason after lift: None state: degraded pinned: {'docmost': 'docmost/docmost:0.95.0', 'docmost-postgres': 'postgres:16-alpine', 'docmost-redis': 'redis:7-alpine'}
08:08:09 product start -> 200 {'ok': True, 'message': 'Stack docmost start completed'}
08:08:57 after 45 s: docmost docmost/docmost:0.95.0 Restarting (1) Less than a second ago
docmost-postgres postgres:16-alpine Up 58 seconds (healthy)
docmost-redis redis:7-alpine Up 58 seconds (healthy)
08:08:59 {"level":"error","time":"2026-09-23T06:08:47.595Z","pid":45,"hostname":"c89a9567fa85","context":"DatabaseMigrationService","msg":"Failed to run database migration. Exiting program."}
{"level":"error","time":"2026-09-23T06:08:47.595Z","pid":45,"hostname":"c89a9567fa85","context":"DatabaseMigrationService","err":{"type":"Error","message":"corrupted migrations: previously executed migration 20260824T211732-page-title-trgm-index is missing","stack":"Error: corrupted migrations: previously executed migration 20260824T211732-page-title-trgm-index is missing\n at #ensureNoMissingMigrations (/app/node_modules/.pnpm/kysely@0.28.17/node_modules/kysely/dist/cjs/migration/migrator.js:495:23)\n at #getState (/app/node_modules/.pnpm/kysely@0.28.17/node_modules/kysely/dist/cjs/migration/migrator.js:447:40)\n at process.processTicksAndRejections (node:internal/process/task_queues:103:5)\n at async run (/app/node_modules/.pnpm/kysely@0.28.17/node_modules/kysely/dist/cjs/migration/migrator.js:417:31)\n at async /app/node_modules/.pnpm/kysely@0.28.17/node_modules/kysely/dist/cjs/kysely.js:578:32\n at async DefaultConnectionProvider.provideConnection (/app/node_modules/.pnpm/kysely@0.28.17/node_modules/kysely/dist/cjs/driver/default-connection-provider.js:12:20)\n at async #migrate (/app/node_modules/.pnpm/kysely@0.28.17/node_modules/kysely/dist/cjs/migration/migrator.js:273:20)\n at async MigrationService.migrateToLatest (/app/apps/server/dist/database/services/migration.service.js:36:36)\n at async DatabaseModule.onApplicationBootstrap (/app/apps/server/dist/database/database.module.js:59:13)\n at async callModuleBootstrapHook (/app/node_modules/.pnpm/@nestjs+core@11.1.27_@nestjs+common@11.1.27_class-transformer@0.5.1_class-validator@0.1_d57b2ebf04f40b3fdc1575d79e91a4e1/node_modules/@nestjs/core/hooks/on-app-bootstrap.hook.js:51:9)\n at async NestApplication.callBootstrapHook (/app/node_modules/.pnpm/@nestjs+core@11.1.27_@nestjs+common@11.1.27_class-transformer@0.5.1_class-validator@0.1_d57b2ebf04f40b3fdc1575d79e91a4e1/node_modules/@nestjs/core/nest-application-context.js:274:13)\n at async NestApplication.init (/app/node_modules/.pnpm/@nestjs+core@11.1.27_@nestjs+common@11.1.27_class-transformer@0.5.1_class-validator@0.1_d57b2ebf04f40b3fdc1575d79e91a4e1/node_modules/@nestjs/core/nest-application.js:107:9)\n at async NestApplication.listen (/app/node_modules/.pnpm/@nestjs+core@11.1.27_@nestjs+common@11.1.27_class-transformer@0.5.1_class-validator@0.1_d57b2ebf04f40b3fdc1575d79e91a4e1/node_modules/@nestjs/core/nest-application.js:177:13)\n at async bootstrap (/app/apps/server/dist/main.js:122:5)"},"msg":"corrupted migrations: previously executed migration 20260824T211732-page-title-trgm-index is missing"}
Exit status 1
 ELIFECYCLE  Command failed with exit code 1.
{"level":"error","time":"2026-09-23T06:08:56.732Z","pid":45,"hostname":"c89a9567fa85","context":"DatabaseMigrationService","msg":"Failed to run database migration. Exiting program."}
{"level":"error","time":"2026-09-23T06:08:56.732Z","pid":45,"hostname":"c89a9567fa85","context":"DatabaseMigrationService","err":{"type":"Error","message":"corrupted migrations: previously executed migration 20260824T211732-page-title-trgm-index is missing","stack":"Error: corrupted migrations: previously executed migration 20260824T211732-page-title-trgm-index is missing\n at #ensureNoMissingMigrations (/app/node_modules/.pnpm/kysely@0.28.17/node_modules/kysely/dist/cjs/migration/migrator.js:495:23)\n at #getState (/app/node_modules/.pnpm/kysely@0.28.17/node_modules/kysely/dist/cjs/migration/migrator.js:447:40)\n at process.processTicksAndRejections (node:internal/process/task_queues:103:5)\n at async run (/app/node_modules/.pnpm/kysely@0.28.17/node_modules/kysely/dist/cjs/migration/migrator.js:417:31)\n at async /app/node_modules/.pnpm/kysely@0.28.17/node_modules/kysely/dist/cjs/kysely.js:578:32\n at async DefaultConnectionProvider.provideConnection (/app/node_modules/.pnpm/kysely@0.28.17/node_modules/kysely/dist/cjs/driver/default-connection-provider.js:12:20)\n at async #migrate (/app/node_modules/.pnpm/kysely@0.28.17/node_modules/kysely/dist/cjs/migration/migrator.js:273:20)\n at async MigrationService.migrateToLatest (/app/apps/server/dist/database/services/migration.service.js:36:36)\n at async DatabaseModule.onApplicationBootstrap (/app/apps/server/dist/database/database.module.js:59:13)\n at async callModuleBootstrapHook (/app/node_modules/.pnpm/@nestjs+core@11.1.27_@nestjs+common@11.1.27_class-transformer@0.5.1_class-validator@0.1_d57b2ebf04f40b3fdc1575d79e91a4e1/node_modules/@nestjs/core/hooks/on-app-bootstrap.hook.js:51:9)\n at async NestApplication.callBootstrapHook (/app/node_modules/.pnpm/@nestjs+core@11.1.27_@nestjs+common@11.1.27_class-transformer@0.5.1_class-validator@0.1_d57b2ebf04f40b3fdc1575d79e91a4e1/node_modules/@nestjs/core/nest-application-context.js:274:13)\n at async NestApplication.init (/app/node_modules/.pnpm/@nestjs+core@11.1.27_@nestjs+common@11.1.27_class-transformer@0.5.1_class-validator@0.1_d57b2ebf04f40b3fdc1575d79e91a4e1/node_modules/@nestjs/core/nest-application.js:107:9)\n at async NestApplication.listen (/app/node_modules/.pnpm/@nestjs+core@11.1.27_@nestjs+common@11.1.27_class-transformer@0.5.1_class-validator@0.1_d57b2ebf04f40b3fdc1575d79e91a4e1/node_modules/@nestjs/core/nest-application.js:177:13)\n at async bootstrap (/app/apps/server/dist/main.js:122:5)"},"msg":"corrupted migrations: previously executed migration 20260824T211732-page-title-trgm-index is missing"}
Exit status 1
 ELIFECYCLE  Command failed with exit code 1.
08:08:59 front door http: 404
@@ -0,0 +1,11 @@
app container stopped (DB kept up): exited
DB state BEFORE any load (the migrated state): 48 tables | ledger rows: 52 | newest: 20260904T171920-public-spaces
truncated copy: 67908 of 135816 bytes
load of the TRUNCATED copy: rc=3 in 0.34s
constraint siem_destinations_workspace_id_fkey on table public.siem_destinations depends on index public.workspaces_pkey
constraint public_spaces_workspace_id_fkey on table public.public_spaces depends on index public.workspaces_pkey
HINT: Use DROP ... CASCADE to drop the dependent objects too.
DB state AFTER the failed load: 48 tables | ledger rows: 52 | newest: 20260904T171920-public-spaces
old app on it: exited restarts=0 exit=1
"msg":"corrupted migrations: previously executed migration 20260824T211732-page-title-trgm-index is missing"
wrong case total 31.37s
@@ -0,0 +1,13 @@
=== the WHOLE undo copy, loaded exactly as the product's ImportDump loads it (psql -v ON_ERROR_STOP=1 --single-transaction)
rc=3 in 0.40s
ERROR: cannot drop constraint workspaces_pkey on table public.workspaces because other objects depend on it
DETAIL: constraint oauth_clients_workspace_id_fkey on table public.oauth_clients depends on index public.workspaces_pkey
HINT: Use DROP ... CASCADE to drop the dependent objects too.
DB state after: 48 tables | ledger rows: 52 | newest: 20260904T171920-public-spaces
=== the tables the NEW version created that the old dump does not know
oauth_authorization_codes
oauth_clients
oauth_grants
oauth_tokens
public_spaces
siem_destinations
@@ -0,0 +1,10 @@
=== WRONG CASE, atomic form: empty the schema + the TRUNCATED copy, ONE transaction
rc=0 in 0.81s
DETAIL: drop cascades to table kysely_migration
DB state after the failed atomic load (must be the MIGRATED state, untouched): 42 tables | ledger rows: 48 | newest: 20260620T010047-personal-spaces
=== RIGHT CASE, atomic form: empty the schema + the WHOLE copy, ONE transaction
rc=0 in 1.38s
DETAIL: drop cascades to extension pg_trgm
DB state after (expect 42 tables, 48 ledger rows, newest 20260620T010047-personal-spaces): 42 tables | ledger rows: 48 | newest: 20260620T010047-personal-spaces
extensions: plpgsql,pg_trgm,unaccent
@@ -0,0 +1,9 @@
full rc=0
trunc rc=0
== scratch_full: tables=42 constraints(pk/fk/unique)=189 indexes=147 users=1 spaces=2 ledger=48
== scratch_trunc: tables=42 constraints(pk/fk/unique)=0 indexes=0 users=0 spaces=0 ledger=48
== where the cut fell: rifiers; Type: TABLE DATA; Schema: public; Owner: - -- COPY public.page_verifiers (id, page_verification_id, user_id, is_primary, added_by_id, created_at) FROM
== the completion marker pg_dump writes at the end:
full copy : 0
truncated : 0
scratch databases dropped
@@ -0,0 +1,10 @@
08:11:30 started
08:11:42 health (the OLD version's own probe: http :3000 answered through the front door) = True after 14.8s
08:11:44 docmost/docmost:0.95.0 running restarts=0
"msg":"Nest application successfully started"
08:11:45 docmost: login as the seeded user http=200 ok=True
08:11:45 docmost B: /api/spaces http=200 seeded-space-listed=True (negative control listed=False)
08:11:45 READBACK after the undo: seed A (before the backup)=True seed B (after the backup, only in the safety dump)=True
08:11:47 {"pinned_images": {"docmost": "docmost/docmost:0.95.0", "docmost-postgres": "postgres:16-alpine", "docmost-redis": "redis:7-alpine"}, "installed_images": {"docmost": "docmost/docmost:0.95.0", "docmost-postgres": "postgres:16-alpine", "docmost-redis": "redis:7-alpine"}, "catalog_images": {"docmost": "docmost/docmost:0.96.0", "docmost-postgres": "postgres:16-alpine", "docmost-redis": "redis:7-alpine"}, "live_compose_image_lines": ["image: docmost/docmost:0.95.0", "image: postgres:16-alpine", "image: redis:7-alpine"], "docker_inspect": ["docmost docmost/docmost:0.95.0 running=true restarts=0", "docmost-postgres postgres:16-alpine running=true restarts=0", "docmost-redis redis:7-alpine running=true restarts=0"]}
@@ -0,0 +1,41 @@
docmost | $ pnpm --filter ./apps/server run start:prod
docmost | $ cross-env NODE_ENV=production node dist/main
docmost-postgres |
docmost-redis | 1:C 23 Sep 2026 08:01:02.584 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
docmost-redis | 1:C 23 Sep 2026 08:01:02.584 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
docmost-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
docmost-redis | 1:C 23 Sep 2026 08:01:02.584 * Redis version=7.4.11, bits=64, commit=00000000, modified=0, pid=1, just started
docmost-postgres |
docmost-redis | 1:C 23 Sep 2026 08:01:02.584 * Configuration loaded
docmost-postgres | 2026-09-23 08:01:02.662 CEST [1] LOG: starting PostgreSQL 16.15 on x86_64-pc-linux-musl, compiled by gcc (Alpine 15.2.0) 15.2.0, 64-bit
docmost | (node:45) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
docmost-postgres | 2026-09-23 08:01:02.663 CEST [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
docmost | (Use `node --trace-warnings ...` to show where the warning was created)
docmost-postgres | 2026-09-23 08:01:02.663 CEST [1] LOG: listening on IPv6 address "::", port 5432
docmost | {"level":"info","time":"2026-09-23T06:02:18.725Z","pid":45,"hostname":"8ddf85c23281","context":"RedisModule","msg":"default: the connection was successfully established"}
docmost-redis | 1:M 23 Sep 2026 08:01:02.584 * Increased maximum number of open files to 10032 (it was originally set to 1024).
docmost | {"level":"info","time":"2026-09-23T06:02:18.968Z","pid":45,"hostname":"8ddf85c23281","context":"DatabaseModule","msg":"Establishing database connection"}
docmost | {"level":"info","time":"2026-09-23T06:02:18.996Z","pid":45,"hostname":"8ddf85c23281","context":"DatabaseModule","msg":"Database connection successful"}
docmost-redis | 1:M 23 Sep 2026 08:01:02.584 * monotonic clock: POSIX clock_gettime
docmost | {"level":"info","time":"2026-09-23T06:02:19.400Z","pid":45,"hostname":"8ddf85c23281","context":"DatabaseMigrationService","msg":"Migration \"20260824T211732-page-title-trgm-index\" executed successfully"}
docmost-postgres | 2026-09-23 08:01:02.670 CEST [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
docmost-postgres | 2026-09-23 08:01:02.679 CEST [29] LOG: database system was shut down at 2026-09-23 08:01:00 CEST
docmost-postgres | 2026-09-23 08:01:02.687 CEST [1] LOG: database system is ready to accept connections
docmost-redis | 1:M 23 Sep 2026 08:01:02.586 * Running mode=standalone, port=6379.
docmost-redis | 1:M 23 Sep 2026 08:01:02.586 * Server initialized
docmost-redis | 1:M 23 Sep 2026 08:01:02.586 * Reading RDB base file on AOF loading...
docmost-redis | 1:M 23 Sep 2026 08:01:02.586 * Loading RDB produced by version 7.4.11
docmost-redis | 1:M 23 Sep 2026 08:01:02.586 * RDB age 52 seconds
docmost-redis | 1:M 23 Sep 2026 08:01:02.586 * RDB memory usage when created 0.90 Mb
docmost-redis | 1:M 23 Sep 2026 08:01:02.586 * RDB is base AOF
docmost-redis | 1:M 23 Sep 2026 08:01:02.586 * Done loading RDB, keys loaded: 0, keys expired: 0.
docmost | {"level":"info","time":"2026-09-23T06:02:19.400Z","pid":45,"hostname":"8ddf85c23281","context":"DatabaseMigrationService","msg":"Migration \"20260825T022612-oauth\" executed successfully"}
docmost | {"level":"info","time":"2026-09-23T06:02:19.400Z","pid":45,"hostname":"8ddf85c23281","context":"DatabaseMigrationService","msg":"Migration \"20260902T121326-siem-destinations\" executed successfully"}
docmost | {"level":"info","time":"2026-09-23T06:02:19.400Z","pid":45,"hostname":"8ddf85c23281","context":"DatabaseMigrationService","msg":"Migration \"20260904T171920-public-spaces\" executed successfully"}
docmost-redis | 1:M 23 Sep 2026 08:01:02.586 * DB loaded from base file appendonly.aof.1.base.rdb: 0.000 seconds
docmost | {"level":"info","time":"2026-09-23T06:02:19.465Z","pid":45,"hostname":"8ddf85c23281","context":"NestApplication","msg":"Nest application successfully started"}
docmost-redis | 1:M 23 Sep 2026 08:01:02.587 * DB loaded from incr file appendonly.aof.1.incr.aof: 0.001 seconds
docmost | {"level":"info","time":"2026-09-23T06:02:19.478Z","pid":45,"hostname":"8ddf85c23281","context":"NestApplication","msg":"Listening on http://127.0.0.1:3000 / https://docs.enkisfelhom.hu"}
docmost-redis | 1:M 23 Sep 2026 08:01:02.587 * DB loaded from append only file: 0.001 seconds
docmost-redis | 1:M 23 Sep 2026 08:01:02.587 * Opening AOF incr file appendonly.aof.1.incr.aof on server start
docmost-redis | 1:M 23 Sep 2026 08:01:02.587 * Ready to accept connections tcp
@@ -0,0 +1,116 @@
romm | INFO: [RomM][init][2026-09-23 08:15:25] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:15:25] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:15:25] | |__) |___ _ __ ___ | \ / |
romm-redis | 1:C 23 Sep 2026 08:13:58.183 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
romm-db | 2026-09-23 08:13:58+02:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:11.4.13+maria~ubu2404 started.
romm | INFO: [RomM][init][2026-09-23 08:15:25] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:15:25] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:15:25] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:15:25]
romm | INFO: [RomM][init][2026-09-23 08:15:25] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:15:25]
romm-db | 2026-09-23 08:13:58+02:00 [Warn] [Entrypoint]: /sys/fs/cgroup///memory.pressure not writable, functionality unavailable to MariaDB
romm-redis | 1:C 23 Sep 2026 08:13:58.183 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
romm-db | 2026-09-23 08:13:58+02:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
romm-db | 2026-09-23 08:13:58+02:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:11.4.13+maria~ubu2404 started.
romm-db | 2026-09-23 08:13:58+02:00 [Note] [Entrypoint]: MariaDB upgrade not required
romm-redis | 1:C 23 Sep 2026 08:13:58.183 * Redis version=7.4.11, bits=64, commit=00000000, modified=0, pid=1, just started
romm-db | 2026-09-23 8:13:58 0 [Note] Starting MariaDB 11.4.13-MariaDB-ubu2404 source revision 170b1d70737be6f134448f51713cdc1ae215b420 server_uid w6iGLIckToxP3WCDRLUzm1Y/EIs= as process 1
romm-redis | 1:C 23 Sep 2026 08:13:58.183 * Configuration loaded
romm-redis | 1:M 23 Sep 2026 08:13:58.184 * Increased maximum number of open files to 10032 (it was originally set to 1024).
romm-redis | 1:M 23 Sep 2026 08:13:58.184 * monotonic clock: POSIX clock_gettime
romm-redis | 1:M 23 Sep 2026 08:13:58.185 * Running mode=standalone, port=6379.
romm-redis | 1:M 23 Sep 2026 08:13:58.186 * Server initialized
romm-redis | 1:M 23 Sep 2026 08:13:58.186 * Reading RDB base file on AOF loading...
romm-redis | 1:M 23 Sep 2026 08:13:58.186 * Loading RDB produced by version 7.4.11
romm-redis | 1:M 23 Sep 2026 08:13:58.186 * RDB age 103 seconds
romm-redis | 1:M 23 Sep 2026 08:13:58.186 * RDB memory usage when created 0.90 Mb
romm-redis | 1:M 23 Sep 2026 08:13:58.186 * RDB is base AOF
romm-redis | 1:M 23 Sep 2026 08:13:58.186 * Done loading RDB, keys loaded: 0, keys expired: 0.
romm-redis | 1:M 23 Sep 2026 08:13:58.186 * DB loaded from base file appendonly.aof.1.base.rdb: 0.000 seconds
romm-redis | 1:M 23 Sep 2026 08:13:58.256 * DB loaded from incr file appendonly.aof.1.incr.aof: 0.070 seconds
romm | INFO: [RomM][init][2026-09-23 08:15:25] Version: 5.3.0
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: Compressed tables use zlib 1.3
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: Number of transaction pools: 1
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
romm-db | 2026-09-23 8:13:58 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: Using Linux native AIO
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: innodb_buffer_pool_size_max=8388608m, innodb_buffer_pool_size=128m
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: Completed initialization of buffer pool
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: File system buffers for log disabled (block size=512 bytes)
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: End of log at LSN=3042523
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: Opened 3 undo tablespaces
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: 128 rollback segments in 3 undo tablespaces are active.
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: log sequence number 3042523; transaction id 2444
romm | INFO: [RomM][init][2026-09-23 08:15:25]
romm-redis | 1:M 23 Sep 2026 08:13:58.256 * DB loaded from append only file: 0.070 seconds
romm-redis | 1:M 23 Sep 2026 08:13:58.256 * Opening AOF incr file appendonly.aof.1.incr.aof on server start
romm | INFO: [RomM][init][2026-09-23 08:15:25] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm-redis | 1:M 23 Sep 2026 08:13:58.256 * Ready to accept connections tcp
romm-redis | 1:M 23 Sep 2026 08:14:59.034 * 10000 changes in 60 seconds. Saving...
romm-redis | 1:M 23 Sep 2026 08:14:59.036 * Background saving started by pid 51
romm-redis | 51:C 23 Sep 2026 08:14:59.155 * DB saved on disk
romm-redis | 51:C 23 Sep 2026 08:14:59.156 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 0 MB
romm-redis | 1:M 23 Sep 2026 08:14:59.238 * Background saving terminated with success
romm-db | 2026-09-23 8:13:58 0 [Note] Plugin 'FEEDBACK' is disabled.
romm | INFO: [RomM][init][2026-09-23 08:15:25] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:15:25] Running database migrations
romm | INFO: [RomM][init][2026-09-23 08:15:41] Database migrations succeeded
romm | INFO: [RomM][startup][2026-09-23 08:15:53] Running startup tasks
romm | INFO: [RomM][startup][2026-09-23 08:15:53] Cleared 2 job(s) left behind by the old scheduler
romm | INFO: [RomM][startup][2026-09-23 08:15:53] Initializing cache with fixtures data
romm | INFO: [RomM][startup][2026-09-23 08:15:53] Startup tasks completed
romm | INFO: [RomM][init][2026-09-23 08:15:54] Starting backend
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
romm | INFO: [RomM][init][2026-09-23 08:15:54] Starting RQ cron scheduler
romm-db | 2026-09-23 8:13:58 0 [Note] Plugin 'wsrep-provider' is disabled.
romm-db | 2026-09-23 8:13:58 0 [Note] InnoDB: Buffer pool(s) load completed at 260923 8:13:58
romm-db | 2026-09-23 8:14:01 0 [Note] Server socket created on IP: '0.0.0.0', port: '3306'.
romm-db | 2026-09-23 8:14:01 0 [Note] Server socket created on IP: '::', port: '3306'.
romm-db | 2026-09-23 8:14:01 0 [Note] mariadbd: Event Scheduler: Loaded 0 events
romm-db | 2026-09-23 8:14:01 0 [Note] mariadbd: ready for connections.
romm-db | Version: '11.4.13-MariaDB-ubu2404' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
romm-db | 2026-09-23 8:15:24 16 [Warning] Aborted connection 16 to db: 'romm' user: 'romm' host: '172.21.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:15:24 15 [Warning] Aborted connection 15 to db: 'romm' user: 'romm' host: '172.21.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:15:41 31 [Warning] Aborted connection 31 to db: 'romm' user: 'romm' host: '172.21.0.4' (Got an error reading communication packets)
romm | INFO: [RomM][init][2026-09-23 08:15:54] Starting RQ worker
romm | INFO: [RomM][init][2026-09-23 08:15:54] Starting RQ scan worker
romm | INFO: [RomM][init][2026-09-23 08:15:56] Starting nginx
romm | 2026/09/23 08:15:56 [notice] 128#128: js vm init njs: 00007A0B0A878B00
romm | INFO: [RomM][init][2026-09-23 08:15:56] 🚀 RomM is now available at http://0.0.0.0:8080
romm | 08:15:56 Worker bfc3044001f04323ab0fcd969f27f134: started with PID 104, version 2.12.0
romm | 08:15:56 Worker bfc3044001f04323ab0fcd969f27f134: subscribing to channel rq:pubsub:bfc3044001f04323ab0fcd969f27f134
romm | 08:15:56 *** Listening on high, default, low...
romm | 08:15:56 Acquired scheduler lock for low
romm | 08:15:56 Acquired scheduler lock for high
romm | 08:15:56 Acquired scheduler lock for default
romm | 08:15:56 Loading cron configuration from tasks.cron_config
romm | 08:15:56 Scheduler for low, high, default started with PID 143
romm | 08:15:57 Worker 1c07db4039a94c7db8fac0f5a05b08ea: started with PID 107, version 2.12.0
romm | 08:15:57 Worker 1c07db4039a94c7db8fac0f5a05b08ea: subscribing to channel rq:pubsub:1c07db4039a94c7db8fac0f5a05b08ea
romm | 08:15:57 *** Listening on scans...
romm | 08:15:57 Acquired scheduler lock for scans
romm | 08:15:57 Scheduler for scans started with PID 146
romm | INFO: [RomM][cron_config][2026-09-23 08:16:05] Scheduled 'build_recommendations' at '30 5 * * *'
romm | INFO: [RomM][cron_config][2026-09-23 08:16:05] Scheduled 'cleanup_zip_cache' at '0 4 * * *'
romm | INFO: [RomM][cron_config][2026-09-23 08:16:05] Scheduled 'cleanup_netplay' at '*/30 * * * *'
romm | INFO: [RomM][cron_config][2026-09-23 08:16:05] Scheduled 'cleanup_upload_tmp' at '0 * * * *'
romm | 08:16:05 Registered 'tasks.tasks.run_task_by_name' to run on low with cron schedule '30 5 * * *'
romm | 08:16:05 Registered 'tasks.tasks.run_task_by_name' to run on low with cron schedule '0 4 * * *'
romm | 08:16:05 Registered 'tasks.tasks.run_task_by_name' to run on low with cron schedule '*/30 * * * *'
romm | 08:16:05 Registered 'tasks.tasks.run_task_by_name' to run on low with cron schedule '0 * * * *'
romm | 08:16:05 Successfully registered 4 cron jobs from 'tasks.cron_config'
romm | 08:16:05 CronScheduler 02b0b707a3fd:101:7e5404: starting...
romm | 08:16:05 CronScheduler 02b0b707a3fd:101:7e5404: registering birth...
romm | INFO: [RomM][nginx][2026-09-23 08:16:00] 127.0.0.1 | - | GET / 200 | 5878 | Unknown Unknown | 0.000
romm | INFO: [RomM][server][2026-09-23 08:16:12] Started server process [124]
romm | INFO: [RomM][on][2026-09-23 08:16:12] Waiting for application startup.
romm | INFO: [RomM][on][2026-09-23 08:16:12] Application startup complete.
romm | INFO: [RomM][logs][2026-09-23 08:16:12] Log stream forwarder started
romm | INFO: [RomM][server][2026-09-23 08:16:12] Started server process [125]
romm | INFO: [RomM][on][2026-09-23 08:16:12] Waiting for application startup.
romm | INFO: [RomM][on][2026-09-23 08:16:12] Application startup complete.
romm | INFO: [RomM][nginx][2026-09-23 08:16:30] 127.0.0.1 | - | GET / 200 | 5878 | Unknown Unknown | 0.000
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,123 @@
[06:37:57] M1: deploying romm at FROM {'romm': 'rommapp/romm:5.0.0'}
[06:38:45] FROM settled=True in 36.7s :: {"romm": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-db": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-redis": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[06:38:53] romm: POST /api/users http=201
[06:38:55] romm: login as the seeded user http=200 ok=True
[06:38:55] C1 (seed reads back BEFORE): True
[06:38:55] M1: swapping to TO {'romm': 'rommapp/romm:5.3.0'}
[06:38:58] TO up -d rc=0
[06:39:29] TO settled=True in 31.6s :: {"romm": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-db": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-redis": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[06:39:29] migration lines observed: 2
[06:39:46] romm: login as the seeded user http=200 ok=True
[06:39:46] RESULT (seed reads back AFTER): True
[06:39:46] memory watch: 600s, 4 callers on 8 path(s) at 172.18.0.6:8080
[06:40:01] + 15s romm=615M/768M peak=620M kills=0 rs=0 romm-db=140M/384M peak=146M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=291
[06:40:16] + 30s romm=615M/768M peak=620M kills=0 rs=0 romm-db=141M/384M peak=146M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=584
[06:40:31] + 46s romm=615M/768M peak=620M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=877
[06:40:47] + 61s romm=616M/768M peak=620M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=1169
[06:41:02] + 76s romm=616M/768M peak=620M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=1459
[06:41:17] + 91s romm=615M/768M peak=620M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=1751
[06:41:32] + 106s romm=616M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=2042
[06:41:47] + 122s romm=449M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=2334
[06:42:03] + 137s romm=536M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=14M/128M peak=37M kills=0 rs=0 reqs=2431
[06:42:18] + 152s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=2719
[06:42:33] + 167s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=14M/128M peak=37M kills=0 rs=0 reqs=3012
[06:42:48] + 182s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=3302
[06:43:03] + 198s romm=614M/768M peak=621M kills=0 rs=0 romm-db=142M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=3594
[06:43:19] + 213s romm=615M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=3885
[06:43:34] + 228s romm=615M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=14M/128M peak=37M kills=0 rs=0 reqs=4175
[06:43:49] + 243s romm=498M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=4466
[06:44:04] + 258s romm=615M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=4753
[06:44:19] + 274s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=5046
[06:44:35] + 289s romm=478M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=5337
[06:44:50] + 304s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=5626
[06:45:05] + 319s romm=615M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=5918
[06:45:20] + 334s romm=614M/768M peak=621M kills=0 rs=0 romm-db=142M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=6210
[06:45:35] + 350s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=6500
[06:45:51] + 365s romm=536M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=6790
[06:46:06] + 380s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=16M/128M peak=37M kills=0 rs=0 reqs=7079
[06:46:21] + 395s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=7369
[06:46:36] + 410s romm=555M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=7653
[06:46:51] + 426s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=7942
[06:47:07] + 441s romm=615M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=8235
[06:47:22] + 456s romm=614M/768M peak=621M kills=0 rs=0 romm-db=142M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=8527
[06:47:37] + 471s romm=614M/768M peak=621M kills=0 rs=0 romm-db=142M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=8819
[06:47:52] + 486s romm=615M/768M peak=621M kills=0 rs=0 romm-db=142M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=9111
[06:48:07] + 502s romm=526M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=9401
[06:48:23] + 517s romm=613M/768M peak=621M kills=0 rs=0 romm-db=142M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=9690
[06:48:38] + 532s romm=456M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=9983
[06:48:53] + 547s romm=608M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=14M/128M peak=37M kills=0 rs=0 reqs=10273
[06:49:08] + 563s romm=608M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=17M/128M peak=37M kills=0 rs=0 reqs=10563
[06:49:24] + 578s romm=608M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=17M/128M peak=37M kills=0 rs=0 reqs=10855
[06:49:39] + 593s romm=490M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=17M/128M peak=37M kills=0 rs=0 reqs=11139
[06:49:54] + 608s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=16M/128M peak=37M kills=0 rs=0 reqs=11429
[06:49:54] memory watch: killed=False tight=['romm'] requests=11429 codes={'200': 5712, '401': 5717}
[06:49:54] M1: ABORT — putting the FROM images back
[06:53:05] ABORT: the app did NOT come back (rc=0, 182.4s)
{
"harness_version": 2,
"edge": "M1",
"app": "romm",
"note": "catalog move 15f9ebf 5.0.0 -> 5.3.0 on the CURRENT template (768M, 2 workers)",
"from": {
"romm": "rommapp/romm:5.0.0"
},
"to": {
"romm": "rommapp/romm:5.3.0"
},
"verdict": "proven",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"migration_observed": "romm | \u001b[0;32mINFO: \u001b[0;34m[RomM]\u001b[0;95m[init]\u001b[0;36m[2026-09-23 08:38:58]\u001b[0;00m Running database migrations",
"abort": "refuses",
"abort_detail": "to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:49:34 148 [Warning] Aborted connection 148 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:50:01 171 [Warning] Aborted connection 171 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:50:01 165 [Warning] Aborted connection 165 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:50:01 164 [Warning] Aborted connection 164 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:50:01 168 [Warning] Aborted connection 168 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)",
"engine_state_after": null,
"memory": {
"soak_s": 608.5,
"requested_s": 600,
"requests": 11429,
"codes": {
"200": 5712,
"401": 5717
},
"first_kill": null,
"containers": {
"romm": {
"limit": 805306368,
"peak": 651239424,
"peak_pct": 0.809,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
},
"romm-db": {
"limit": 402653184,
"peak": 155947008,
"peak_pct": 0.387,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
},
"romm-redis": {
"limit": 134217728,
"peak": 39243776,
"peak_pct": 0.292,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
}
},
"unmeasured": []
},
"marks": [
"memory_tight"
],
"duration_s": 31.6,
"measured_at": "2026-09-23T06:53:05Z",
"evidence": "evidence/M1",
"total_s": 908.0
}
rc=0
@@ -0,0 +1,93 @@
[06:30:39] M1old: deploying romm at FROM {'romm': 'rommapp/romm:5.0.0'}
[06:31:27] FROM settled=True in 36.7s :: {"romm": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-db": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-redis": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[06:31:34] romm: POST /api/users http=201
[06:31:36] romm: login as the seeded user http=200 ok=True
[06:31:36] C1 (seed reads back BEFORE): True
[06:31:36] M1old: swapping to TO {'romm': 'rommapp/romm:5.3.0'}
[06:31:39] TO up -d rc=0
[06:32:11] TO settled=True in 31.5s :: {"romm": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-db": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-redis": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[06:32:11] migration lines observed: 2
[06:32:44] romm: login as the seeded user http=200 ok=True
[06:32:44] RESULT (seed reads back AFTER): True
[06:32:44] memory watch: 600s, 4 callers on 8 path(s) at 172.18.0.6:8080
[06:33:00] + 15s romm=511M/512M peak=512M kills=0 rs=0 romm-db=140M/384M peak=145M kills=0 rs=0 romm-redis=15M/128M peak=30M kills=0 rs=0 reqs=286
[06:33:15] + 30s romm=509M/512M peak=512M kills=0 rs=0 romm-db=140M/384M peak=146M kills=0 rs=0 romm-redis=15M/128M peak=30M kills=0 rs=0 reqs=575
[06:33:30] + 46s romm=510M/512M peak=512M kills=0 rs=0 romm-db=140M/384M peak=146M kills=0 rs=0 romm-redis=15M/128M peak=30M kills=0 rs=0 reqs=864
[06:33:45] + 61s romm=508M/512M peak=512M kills=0 rs=0 romm-db=140M/384M peak=146M kills=0 rs=0 romm-redis=15M/128M peak=30M kills=0 rs=0 reqs=1157
[06:34:00] + 76s romm=509M/512M peak=512M kills=1 rs=0 romm-db=140M/384M peak=146M kills=0 rs=0 romm-redis=15M/128M peak=30M kills=0 rs=0 reqs=1404
[06:34:00] memory watch: STOPPING EARLY — {'t': 76.0, 'container': 'romm', 'oom_kills': 1, 'restarts': 0}
[06:34:01] memory watch: killed=True tight=['romm'] requests=1405 codes={'401': 704, '200': 701}
[06:34:01] VERDICT -> failed: the new version was OOM-killed or restarted under light load
[06:34:01] M1old: ABORT — putting the FROM images back
[06:37:15] ABORT: the app did NOT come back (rc=0, 182.4s)
{
"harness_version": 2,
"edge": "M1old",
"app": "romm",
"note": "the same move on the template AS PROMOTED (512M, 4 workers) \u2014 must FAIL the memory watch",
"from": {
"romm": "rommapp/romm:5.0.0"
},
"to": {
"romm": "rommapp/romm:5.3.0"
},
"verdict": "failed",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"migration_observed": "romm | \u001b[0;32mINFO: \u001b[0;34m[RomM]\u001b[0;95m[init]\u001b[0;36m[2026-09-23 08:31:39]\u001b[0;00m Running database migrations",
"abort": "refuses",
"abort_detail": "ection 33 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:33:51 41 [Warning] Aborted connection 41 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:33:51 32 [Warning] Aborted connection 32 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:34:11 36 [Warning] Aborted connection 36 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:34:11 42 [Warning] Aborted connection 42 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:34:11 49 [Warning] Aborted connection 49 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)",
"engine_state_after": null,
"memory": {
"soak_s": 76.5,
"requested_s": 600,
"requests": 1405,
"codes": {
"401": 704,
"200": 701
},
"first_kill": {
"t": 76.0,
"container": "romm",
"oom_kills": 1,
"restarts": 0
},
"containers": {
"romm": {
"limit": 536870912,
"peak": 536875008,
"peak_pct": 1.0,
"oom_kills": 1,
"restarts": 0,
"oomkilled_flag": true,
"measured": true
},
"romm-db": {
"limit": 402653184,
"peak": 153600000,
"peak_pct": 0.381,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
},
"romm-redis": {
"limit": 134217728,
"peak": 32137216,
"peak_pct": 0.239,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
}
},
"unmeasured": []
},
"marks": [],
"duration_s": 31.5,
"measured_at": "2026-09-23T06:37:15Z",
"evidence": "evidence/M1old",
"total_s": 395.7
}
rc=0
@@ -0,0 +1,106 @@
romm-redis | 1:C 23 Sep 2026 08:37:58.125 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
romm-redis | 1:C 23 Sep 2026 08:37:58.125 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
romm-redis | 1:C 23 Sep 2026 08:37:58.125 * Redis version=7.4.11, bits=64, commit=00000000, modified=0, pid=1, just started
romm-redis | 1:C 23 Sep 2026 08:37:58.125 * Configuration loaded
romm-redis | 1:M 23 Sep 2026 08:37:58.125 * Increased maximum number of open files to 10032 (it was originally set to 1024).
romm-redis | 1:M 23 Sep 2026 08:37:58.125 * monotonic clock: POSIX clock_gettime
romm-redis | 1:M 23 Sep 2026 08:37:58.128 * Running mode=standalone, port=6379.
romm-redis | 1:M 23 Sep 2026 08:37:58.128 * Server initialized
romm-redis | 1:M 23 Sep 2026 08:37:58.136 * Creating AOF base file appendonly.aof.1.base.rdb on server start
romm-redis | 1:M 23 Sep 2026 08:37:58.145 * Creating AOF incr file appendonly.aof.1.incr.aof on server start
romm-redis | 1:M 23 Sep 2026 08:37:58.145 * Ready to accept connections tcp
romm-redis | 1:M 23 Sep 2026 08:38:59.091 * 10000 changes in 60 seconds. Saving...
romm-redis | 1:M 23 Sep 2026 08:38:59.093 * Background saving started by pid 52
romm-redis | 52:C 23 Sep 2026 08:38:59.225 * DB saved on disk
romm | INFO: [RomM][init][2026-09-23 08:51:18]
romm-redis | 52:C 23 Sep 2026 08:38:59.226 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 1 MB
romm-redis | 1:M 23 Sep 2026 08:38:59.295 * Background saving terminated with success
romm-redis | 1:M 23 Sep 2026 08:44:00.006 * 100 changes in 300 seconds. Saving...
romm-redis | 1:M 23 Sep 2026 08:44:00.007 * Background saving started by pid 233
romm-redis | 233:C 23 Sep 2026 08:44:00.119 * DB saved on disk
romm-redis | 233:C 23 Sep 2026 08:44:00.120 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 1 MB
romm-redis | 1:M 23 Sep 2026 08:44:00.210 * Background saving terminated with success
romm-redis | 1:M 23 Sep 2026 08:49:01.065 * 100 changes in 300 seconds. Saving...
romm-redis | 1:M 23 Sep 2026 08:49:01.066 * Background saving started by pid 408
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: 128 rollback segments in 3 undo tablespaces are active.
romm | INFO: [RomM][init][2026-09-23 08:51:18] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:51:18]
romm | INFO: [RomM][init][2026-09-23 08:51:18] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:51:18] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:51:18] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:51:27] Failed to run database migrations
romm-redis | 408:C 23 Sep 2026 08:49:01.191 * DB saved on disk
romm-redis | 408:C 23 Sep 2026 08:49:01.192 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 1 MB
romm | INFO: [RomM][init][2026-09-23 08:51:40] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:51:40] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:51:40] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:51:40] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:51:40] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:51:40] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:51:40]
romm-redis | 1:M 23 Sep 2026 08:49:01.268 * Background saving terminated with success
romm | INFO: [RomM][init][2026-09-23 08:51:40] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:51:40]
romm | INFO: [RomM][init][2026-09-23 08:51:40] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:51:40]
romm | INFO: [RomM][init][2026-09-23 08:51:40] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:51:40] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:51:40] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:51:49] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:52:15] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:52:15] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:52:15] | |__) |___ _ __ ___ | \ / |
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: log sequence number 45568; transaction id 14
romm-db | 2026-09-23 8:38:04 0 [Note] Plugin 'FEEDBACK' is disabled.
romm-db | 2026-09-23 8:38:04 0 [Note] Plugin 'wsrep-provider' is disabled.
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Buffer pool(s) load completed at 260923 8:38:04
romm-db | 2026-09-23 8:38:05 0 [Note] Server socket created on IP: '0.0.0.0', port: '3306'.
romm-db | 2026-09-23 8:38:05 0 [Note] Server socket created on IP: '::', port: '3306'.
romm-db | 2026-09-23 8:38:05 0 [Note] mariadbd: Event Scheduler: Loaded 0 events
romm-db | 2026-09-23 8:38:05 0 [Note] mariadbd: ready for connections.
romm-db | Version: '11.4.13-MariaDB-ubu2404' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
romm-db | 2026-09-23 8:38:27 5 [Warning] Aborted connection 5 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:38:56 16 [Warning] Aborted connection 16 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm | INFO: [RomM][init][2026-09-23 08:52:15] | _ // _ \| '_ ` _ \| |\/| |
romm-db | 2026-09-23 8:38:56 15 [Warning] Aborted connection 15 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm | INFO: [RomM][init][2026-09-23 08:52:15] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:52:15] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:52:15]
romm | INFO: [RomM][init][2026-09-23 08:52:15] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:52:15]
romm | INFO: [RomM][init][2026-09-23 08:52:15] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:52:15]
romm | INFO: [RomM][init][2026-09-23 08:52:15] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:52:15] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:52:15] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:52:23] Failed to run database migrations
romm-db | 2026-09-23 8:39:12 19 [Warning] Aborted connection 19 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:41:46 35 [Warning] Aborted connection 35 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:41:46 30 [Warning] Aborted connection 30 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:41:54 44 [Warning] Aborted connection 44 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:41:54 29 [Warning] Aborted connection 29 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:43:44 62 [Warning] Aborted connection 62 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:43:44 61 [Warning] Aborted connection 61 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:43:44 63 [Warning] Aborted connection 63 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:44:31 75 [Warning] Aborted connection 75 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:44:31 66 [Warning] Aborted connection 66 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:45:42 91 [Warning] Aborted connection 91 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:45:42 90 [Warning] Aborted connection 90 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:46:26 115 [Warning] Aborted connection 115 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:46:26 100 [Warning] Aborted connection 100 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:48:00 118 [Warning] Aborted connection 118 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:48:00 123 [Warning] Aborted connection 123 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:48:36 137 [Warning] Aborted connection 137 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:48:36 128 [Warning] Aborted connection 128 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:49:34 153 [Warning] Aborted connection 153 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:49:34 148 [Warning] Aborted connection 148 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:50:01 171 [Warning] Aborted connection 171 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:50:01 165 [Warning] Aborted connection 165 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:50:01 164 [Warning] Aborted connection 164 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:50:01 168 [Warning] Aborted connection 168 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
@@ -0,0 +1,20 @@
{
"romm": {
"status": "restarting",
"health": "unhealthy",
"restarts": 0,
"exit": 1
},
"romm-db": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
},
"romm-redis": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
}
}
@@ -0,0 +1,288 @@
romm-db | 2026-09-23 08:37:58+02:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:11.4.13+maria~ubu2404 started.
romm-db | 2026-09-23 08:37:58+02:00 [Warn] [Entrypoint]: /sys/fs/cgroup///memory.pressure not writable, functionality unavailable to MariaDB
romm-db | 2026-09-23 08:37:58+02:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
romm-db | 2026-09-23 08:37:58+02:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:11.4.13+maria~ubu2404 started.
romm-db | 2026-09-23 08:37:58+02:00 [Note] [Entrypoint]: Initializing database files
romm-db | 2026-09-23 8:37:58 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 08:38:01+02:00 [Note] [Entrypoint]: Database files initialized
romm-db | 2026-09-23 08:38:01+02:00 [Note] [Entrypoint]: Starting temporary server
romm-db | 2026-09-23 08:38:01+02:00 [Note] [Entrypoint]: Waiting for server startup
romm-db | 2026-09-23 8:38:01 0 [Note] Starting MariaDB 11.4.13-MariaDB-ubu2404 source revision 170b1d70737be6f134448f51713cdc1ae215b420 server_uid CoZjczEYgGSu3N2tEniVTdlmtSg= as process 90
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Compressed tables use zlib 1.3
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Number of transaction pools: 1
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
romm-db | 2026-09-23 8:38:01 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Using Linux native AIO
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: innodb_buffer_pool_size_max=8388608m, innodb_buffer_pool_size=128m
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Completed initialization of buffer pool
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: File system buffers for log disabled (block size=512 bytes)
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: End of log at LSN=45568
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Opened 3 undo tablespaces
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: 128 rollback segments in 3 undo tablespaces are active.
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: log sequence number 45568; transaction id 14
romm-db | 2026-09-23 8:38:01 0 [Note] Plugin 'FEEDBACK' is disabled.
romm-db | 2026-09-23 8:38:01 0 [Note] Plugin 'wsrep-provider' is disabled.
romm-db | 2026-09-23 8:38:02 0 [Note] mariadbd: Event Scheduler: Loaded 0 events
romm-db | 2026-09-23 8:38:02 0 [Note] mariadbd: ready for connections.
romm-db | Version: '11.4.13-MariaDB-ubu2404' socket: '/run/mysqld/mysqld.sock' port: 0 mariadb.org binary distribution
romm-db | 2026-09-23 08:38:03+02:00 [Note] [Entrypoint]: Temporary server started.
romm-db | 2026-09-23 08:38:03+02:00 [Note] [Entrypoint]: Creating database romm
romm-db | 2026-09-23 08:38:03+02:00 [Note] [Entrypoint]: Creating user romm
romm-db | 2026-09-23 08:38:03+02:00 [Note] [Entrypoint]: Giving user romm access to schema romm
romm-db | 2026-09-23 08:38:03+02:00 [Note] [Entrypoint]: Securing system users (equivalent to running mysql_secure_installation)
romm-db |
romm-db | 2026-09-23 08:38:03+02:00 [Note] [Entrypoint]: Stopping temporary server
romm-db | 2026-09-23 8:38:03 0 [Note] mariadbd (initiated by: unknown): Normal shutdown
romm-db | 2026-09-23 8:38:03 0 [Note] InnoDB: FTS optimize thread exiting.
romm-db | 2026-09-23 8:38:03 0 [Note] InnoDB: Starting shutdown...
romm-db | 2026-09-23 8:38:03 0 [Note] InnoDB: Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool
romm-db | 2026-09-23 8:38:03 0 [Note] InnoDB: Buffer pool(s) dump completed at 260923 8:38:03
romm-db | 2026-09-23 8:38:03 0 [Note] InnoDB: Removed temporary tablespace data file: "./ibtmp1"
romm-db | 2026-09-23 8:38:03 0 [Note] Shutdown completed; log sequence number 45568; transaction id 15
romm-db | 2026-09-23 8:38:04 0 [Note] mariadbd: Shutdown complete
romm-db | 2026-09-23 08:38:04+02:00 [Note] [Entrypoint]: Temporary server stopped
romm-db |
romm-db | 2026-09-23 08:38:04+02:00 [Note] [Entrypoint]: MariaDB init process done. Ready for start up.
romm-db |
romm-db | 2026-09-23 8:38:04 0 [Note] Starting MariaDB 11.4.13-MariaDB-ubu2404 source revision 170b1d70737be6f134448f51713cdc1ae215b420 server_uid CoZjczEYgGSu3N2tEniVTdlmtSg= as process 1
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Compressed tables use zlib 1.3
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Number of transaction pools: 1
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
romm-db | 2026-09-23 8:38:04 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Using Linux native AIO
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: innodb_buffer_pool_size_max=8388608m, innodb_buffer_pool_size=128m
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Completed initialization of buffer pool
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: File system buffers for log disabled (block size=512 bytes)
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: End of log at LSN=45568
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Opened 3 undo tablespaces
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: 128 rollback segments in 3 undo tablespaces are active.
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: log sequence number 45568; transaction id 14
romm-db | 2026-09-23 8:38:04 0 [Note] Plugin 'FEEDBACK' is disabled.
romm-db | 2026-09-23 8:38:04 0 [Note] Plugin 'wsrep-provider' is disabled.
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Buffer pool(s) load completed at 260923 8:38:04
romm-db | 2026-09-23 8:38:05 0 [Note] Server socket created on IP: '0.0.0.0', port: '3306'.
romm-db | 2026-09-23 8:38:05 0 [Note] Server socket created on IP: '::', port: '3306'.
romm-db | 2026-09-23 8:38:05 0 [Note] mariadbd: Event Scheduler: Loaded 0 events
romm-db | 2026-09-23 8:38:05 0 [Note] mariadbd: ready for connections.
romm-db | Version: '11.4.13-MariaDB-ubu2404' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
romm-db | 2026-09-23 8:38:27 5 [Warning] Aborted connection 5 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:38:56 16 [Warning] Aborted connection 16 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:38:56 15 [Warning] Aborted connection 15 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:39:12 19 [Warning] Aborted connection 19 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:41:46 35 [Warning] Aborted connection 35 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:41:46 30 [Warning] Aborted connection 30 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:41:54 44 [Warning] Aborted connection 44 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:41:54 29 [Warning] Aborted connection 29 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:43:44 62 [Warning] Aborted connection 62 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:43:44 61 [Warning] Aborted connection 61 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:43:44 63 [Warning] Aborted connection 63 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:44:31 75 [Warning] Aborted connection 75 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:44:31 66 [Warning] Aborted connection 66 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:45:42 91 [Warning] Aborted connection 91 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:45:42 90 [Warning] Aborted connection 90 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:46:26 115 [Warning] Aborted connection 115 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:46:26 100 [Warning] Aborted connection 100 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:48:00 118 [Warning] Aborted connection 118 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm | INFO: [RomM][init][2026-09-23 08:50:03] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:50:03] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:50:03] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:50:03] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:50:03] | | \ \ (_) | | | | | | | | |
romm-redis | 1:C 23 Sep 2026 08:37:58.125 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
romm | INFO: [RomM][init][2026-09-23 08:50:03] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:50:03]
romm-redis | 1:C 23 Sep 2026 08:37:58.125 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
romm | INFO: [RomM][init][2026-09-23 08:50:03] The beautiful, powerful, self-hosted Rom manager and player
romm-db | 2026-09-23 8:48:00 123 [Warning] Aborted connection 123 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm | INFO: [RomM][init][2026-09-23 08:50:03]
romm-db | 2026-09-23 8:48:36 137 [Warning] Aborted connection 137 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-redis | 1:C 23 Sep 2026 08:37:58.125 * Redis version=7.4.11, bits=64, commit=00000000, modified=0, pid=1, just started
romm-db | 2026-09-23 8:48:36 128 [Warning] Aborted connection 128 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:49:34 153 [Warning] Aborted connection 153 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-redis | 1:C 23 Sep 2026 08:37:58.125 * Configuration loaded
romm-db | 2026-09-23 8:49:34 148 [Warning] Aborted connection 148 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-redis | 1:M 23 Sep 2026 08:37:58.125 * Increased maximum number of open files to 10032 (it was originally set to 1024).
romm-db | 2026-09-23 8:50:01 171 [Warning] Aborted connection 171 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-redis | 1:M 23 Sep 2026 08:37:58.125 * monotonic clock: POSIX clock_gettime
romm-db | 2026-09-23 8:50:01 165 [Warning] Aborted connection 165 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm | INFO: [RomM][init][2026-09-23 08:50:03] Version: 5.0.0
romm-db | 2026-09-23 8:50:01 164 [Warning] Aborted connection 164 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:50:01 168 [Warning] Aborted connection 168 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm | INFO: [RomM][init][2026-09-23 08:50:03]
romm | INFO: [RomM][init][2026-09-23 08:50:03] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:50:03] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:50:03] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:50:11] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:50:12] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:50:12] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:50:12] | |__) |___ _ __ ___ | \ / |
romm-redis | 1:M 23 Sep 2026 08:37:58.128 * Running mode=standalone, port=6379.
romm-redis | 1:M 23 Sep 2026 08:37:58.128 * Server initialized
romm-redis | 1:M 23 Sep 2026 08:37:58.136 * Creating AOF base file appendonly.aof.1.base.rdb on server start
romm-redis | 1:M 23 Sep 2026 08:37:58.145 * Creating AOF incr file appendonly.aof.1.incr.aof on server start
romm-redis | 1:M 23 Sep 2026 08:37:58.145 * Ready to accept connections tcp
romm-redis | 1:M 23 Sep 2026 08:38:59.091 * 10000 changes in 60 seconds. Saving...
romm-redis | 1:M 23 Sep 2026 08:38:59.093 * Background saving started by pid 52
romm-redis | 52:C 23 Sep 2026 08:38:59.225 * DB saved on disk
romm-redis | 52:C 23 Sep 2026 08:38:59.226 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 1 MB
romm-redis | 1:M 23 Sep 2026 08:38:59.295 * Background saving terminated with success
romm-redis | 1:M 23 Sep 2026 08:44:00.006 * 100 changes in 300 seconds. Saving...
romm-redis | 1:M 23 Sep 2026 08:44:00.007 * Background saving started by pid 233
romm | INFO: [RomM][init][2026-09-23 08:50:12] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:50:12] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:50:12] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:50:12]
romm | INFO: [RomM][init][2026-09-23 08:50:12] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:50:12]
romm | INFO: [RomM][init][2026-09-23 08:50:12] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:50:12]
romm | INFO: [RomM][init][2026-09-23 08:50:12] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:50:12] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:50:12] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:50:21] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:50:21] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:50:21] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:50:21] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:50:21] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:50:21] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:50:21] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:50:21]
romm | INFO: [RomM][init][2026-09-23 08:50:21] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:50:21]
romm | INFO: [RomM][init][2026-09-23 08:50:21] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:50:21]
romm | INFO: [RomM][init][2026-09-23 08:50:21] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:50:21] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:50:21] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:50:30] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:50:31] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:50:31] | __ \ | \/ |
romm-redis | 233:C 23 Sep 2026 08:44:00.119 * DB saved on disk
romm | INFO: [RomM][init][2026-09-23 08:50:31] | |__) |___ _ __ ___ | \ / |
romm-redis | 233:C 23 Sep 2026 08:44:00.120 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 1 MB
romm | INFO: [RomM][init][2026-09-23 08:50:31] | _ // _ \| '_ ` _ \| |\/| |
romm-redis | 1:M 23 Sep 2026 08:44:00.210 * Background saving terminated with success
romm | INFO: [RomM][init][2026-09-23 08:50:31] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:50:31] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:50:31]
romm | INFO: [RomM][init][2026-09-23 08:50:31] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:50:31]
romm | INFO: [RomM][init][2026-09-23 08:50:31] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:50:31]
romm | INFO: [RomM][init][2026-09-23 08:50:31] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm-redis | 1:M 23 Sep 2026 08:49:01.065 * 100 changes in 300 seconds. Saving...
romm | INFO: [RomM][init][2026-09-23 08:50:31] REDIS_HOST is set, not starting internal valkey-server
romm-redis | 1:M 23 Sep 2026 08:49:01.066 * Background saving started by pid 408
romm | INFO: [RomM][init][2026-09-23 08:50:31] Running database migrations
romm-redis | 408:C 23 Sep 2026 08:49:01.191 * DB saved on disk
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm-redis | 408:C 23 Sep 2026 08:49:01.192 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 1 MB
romm | ERROR: [RomM][init][2026-09-23 08:50:39] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:50:40] _____ __ __
romm-redis | 1:M 23 Sep 2026 08:49:01.268 * Background saving terminated with success
romm | INFO: [RomM][init][2026-09-23 08:50:40] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:50:40] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:50:40] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:50:40] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:50:40] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:50:40]
romm | INFO: [RomM][init][2026-09-23 08:50:40] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:50:40]
romm | INFO: [RomM][init][2026-09-23 08:50:40] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:50:40]
romm | INFO: [RomM][init][2026-09-23 08:50:40] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:50:40] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:50:40] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:50:49] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:50:51] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:50:51] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:50:51] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:50:51] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:50:51] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:50:51] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:50:51]
romm | INFO: [RomM][init][2026-09-23 08:50:51] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:50:51]
romm | INFO: [RomM][init][2026-09-23 08:50:51] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:50:51]
romm | INFO: [RomM][init][2026-09-23 08:50:51] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:50:51] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:50:51] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:51:00] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:51:03] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:51:03] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:51:03] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:51:03] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:51:03] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:51:03] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:51:03]
romm | INFO: [RomM][init][2026-09-23 08:51:03] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:51:03]
romm | INFO: [RomM][init][2026-09-23 08:51:03] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:51:03]
romm | INFO: [RomM][init][2026-09-23 08:51:03] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:51:03] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:51:03] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:51:12] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:51:18] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:51:18] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:51:18] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:51:18] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:51:18] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:51:18] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:51:18]
romm | INFO: [RomM][init][2026-09-23 08:51:18] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:51:18]
romm | INFO: [RomM][init][2026-09-23 08:51:18] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:51:18]
romm | INFO: [RomM][init][2026-09-23 08:51:18] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:51:18] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:51:18] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:51:27] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:51:40] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:51:40] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:51:40] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:51:40] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:51:40] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:51:40] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:51:40]
romm | INFO: [RomM][init][2026-09-23 08:51:40] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:51:40]
romm | INFO: [RomM][init][2026-09-23 08:51:40] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:51:40]
romm | INFO: [RomM][init][2026-09-23 08:51:40] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:51:40] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:51:40] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:51:49] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:52:15] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:52:15] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:52:15] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:52:15] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:52:15] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:52:15] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:52:15]
romm | INFO: [RomM][init][2026-09-23 08:52:15] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:52:15]
romm | INFO: [RomM][init][2026-09-23 08:52:15] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:52:15]
romm | INFO: [RomM][init][2026-09-23 08:52:15] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:52:15] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:52:15] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:52:23] Failed to run database migrations
@@ -0,0 +1,2 @@
romm | INFO: [RomM][init][2026-09-23 08:38:58] Running database migrations
romm | INFO: [RomM][init][2026-09-23 08:39:12] Database migrations succeeded
@@ -0,0 +1,55 @@
[06:37:57] M1: deploying romm at FROM {'romm': 'rommapp/romm:5.0.0'}
[06:38:45] FROM settled=True in 36.7s :: {"romm": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-db": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-redis": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[06:38:53] romm: POST /api/users http=201
[06:38:55] romm: login as the seeded user http=200 ok=True
[06:38:55] C1 (seed reads back BEFORE): True
[06:38:55] M1: swapping to TO {'romm': 'rommapp/romm:5.3.0'}
[06:38:58] TO up -d rc=0
[06:39:29] TO settled=True in 31.6s :: {"romm": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-db": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-redis": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[06:39:29] migration lines observed: 2
[06:39:46] romm: login as the seeded user http=200 ok=True
[06:39:46] RESULT (seed reads back AFTER): True
[06:39:46] memory watch: 600s, 4 callers on 8 path(s) at 172.18.0.6:8080
[06:40:01] + 15s romm=615M/768M peak=620M kills=0 rs=0 romm-db=140M/384M peak=146M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=291
[06:40:16] + 30s romm=615M/768M peak=620M kills=0 rs=0 romm-db=141M/384M peak=146M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=584
[06:40:31] + 46s romm=615M/768M peak=620M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=877
[06:40:47] + 61s romm=616M/768M peak=620M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=1169
[06:41:02] + 76s romm=616M/768M peak=620M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=1459
[06:41:17] + 91s romm=615M/768M peak=620M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=1751
[06:41:32] + 106s romm=616M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=2042
[06:41:47] + 122s romm=449M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=2334
[06:42:03] + 137s romm=536M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=14M/128M peak=37M kills=0 rs=0 reqs=2431
[06:42:18] + 152s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=2719
[06:42:33] + 167s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=14M/128M peak=37M kills=0 rs=0 reqs=3012
[06:42:48] + 182s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=3302
[06:43:03] + 198s romm=614M/768M peak=621M kills=0 rs=0 romm-db=142M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=3594
[06:43:19] + 213s romm=615M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=3885
[06:43:34] + 228s romm=615M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=14M/128M peak=37M kills=0 rs=0 reqs=4175
[06:43:49] + 243s romm=498M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=4466
[06:44:04] + 258s romm=615M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=4753
[06:44:19] + 274s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=5046
[06:44:35] + 289s romm=478M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=5337
[06:44:50] + 304s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=5626
[06:45:05] + 319s romm=615M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=5918
[06:45:20] + 334s romm=614M/768M peak=621M kills=0 rs=0 romm-db=142M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=6210
[06:45:35] + 350s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=6500
[06:45:51] + 365s romm=536M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=6790
[06:46:06] + 380s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=16M/128M peak=37M kills=0 rs=0 reqs=7079
[06:46:21] + 395s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=7369
[06:46:36] + 410s romm=555M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=7653
[06:46:51] + 426s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=7942
[06:47:07] + 441s romm=615M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=8235
[06:47:22] + 456s romm=614M/768M peak=621M kills=0 rs=0 romm-db=142M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=8527
[06:47:37] + 471s romm=614M/768M peak=621M kills=0 rs=0 romm-db=142M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=8819
[06:47:52] + 486s romm=615M/768M peak=621M kills=0 rs=0 romm-db=142M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=9111
[06:48:07] + 502s romm=526M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=9401
[06:48:23] + 517s romm=613M/768M peak=621M kills=0 rs=0 romm-db=142M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=9690
[06:48:38] + 532s romm=456M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=15M/128M peak=37M kills=0 rs=0 reqs=9983
[06:48:53] + 547s romm=608M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=14M/128M peak=37M kills=0 rs=0 reqs=10273
[06:49:08] + 563s romm=608M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=17M/128M peak=37M kills=0 rs=0 reqs=10563
[06:49:24] + 578s romm=608M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=17M/128M peak=37M kills=0 rs=0 reqs=10855
[06:49:39] + 593s romm=490M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=17M/128M peak=37M kills=0 rs=0 reqs=11139
[06:49:54] + 608s romm=614M/768M peak=621M kills=0 rs=0 romm-db=141M/384M peak=148M kills=0 rs=0 romm-redis=16M/128M peak=37M kills=0 rs=0 reqs=11429
[06:49:54] memory watch: killed=False tight=['romm'] requests=11429 codes={'200': 5712, '401': 5717}
[06:49:54] M1: ABORT — putting the FROM images back
[06:53:05] ABORT: the app did NOT come back (rc=0, 182.4s)
@@ -0,0 +1,134 @@
romm-db | 2026-09-23 08:37:58+02:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:11.4.13+maria~ubu2404 started.
romm-db | 2026-09-23 08:37:58+02:00 [Warn] [Entrypoint]: /sys/fs/cgroup///memory.pressure not writable, functionality unavailable to MariaDB
romm-db | 2026-09-23 08:37:58+02:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
romm-db | 2026-09-23 08:37:58+02:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:11.4.13+maria~ubu2404 started.
romm-db | 2026-09-23 08:37:58+02:00 [Note] [Entrypoint]: Initializing database files
romm-db | 2026-09-23 8:37:58 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 08:38:01+02:00 [Note] [Entrypoint]: Database files initialized
romm-db | 2026-09-23 08:38:01+02:00 [Note] [Entrypoint]: Starting temporary server
romm-db | 2026-09-23 08:38:01+02:00 [Note] [Entrypoint]: Waiting for server startup
romm-db | 2026-09-23 8:38:01 0 [Note] Starting MariaDB 11.4.13-MariaDB-ubu2404 source revision 170b1d70737be6f134448f51713cdc1ae215b420 server_uid CoZjczEYgGSu3N2tEniVTdlmtSg= as process 90
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Compressed tables use zlib 1.3
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Number of transaction pools: 1
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
romm-db | 2026-09-23 8:38:01 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Using Linux native AIO
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: innodb_buffer_pool_size_max=8388608m, innodb_buffer_pool_size=128m
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Completed initialization of buffer pool
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: File system buffers for log disabled (block size=512 bytes)
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: End of log at LSN=45568
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Opened 3 undo tablespaces
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: 128 rollback segments in 3 undo tablespaces are active.
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
romm-db | 2026-09-23 8:38:01 0 [Note] InnoDB: log sequence number 45568; transaction id 14
romm-db | 2026-09-23 8:38:01 0 [Note] Plugin 'FEEDBACK' is disabled.
romm-db | 2026-09-23 8:38:01 0 [Note] Plugin 'wsrep-provider' is disabled.
romm-db | 2026-09-23 8:38:02 0 [Note] mariadbd: Event Scheduler: Loaded 0 events
romm-db | 2026-09-23 8:38:02 0 [Note] mariadbd: ready for connections.
romm-db | Version: '11.4.13-MariaDB-ubu2404' socket: '/run/mysqld/mysqld.sock' port: 0 mariadb.org binary distribution
romm-db | 2026-09-23 08:38:03+02:00 [Note] [Entrypoint]: Temporary server started.
romm-db | 2026-09-23 08:38:03+02:00 [Note] [Entrypoint]: Creating database romm
romm-db | 2026-09-23 08:38:03+02:00 [Note] [Entrypoint]: Creating user romm
romm-db | 2026-09-23 08:38:03+02:00 [Note] [Entrypoint]: Giving user romm access to schema romm
romm-db | 2026-09-23 08:38:03+02:00 [Note] [Entrypoint]: Securing system users (equivalent to running mysql_secure_installation)
romm-db |
romm-db | 2026-09-23 08:38:03+02:00 [Note] [Entrypoint]: Stopping temporary server
romm-db | 2026-09-23 8:38:03 0 [Note] mariadbd (initiated by: unknown): Normal shutdown
romm-db | 2026-09-23 8:38:03 0 [Note] InnoDB: FTS optimize thread exiting.
romm-db | 2026-09-23 8:38:03 0 [Note] InnoDB: Starting shutdown...
romm-db | 2026-09-23 8:38:03 0 [Note] InnoDB: Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool
romm-db | 2026-09-23 8:38:03 0 [Note] InnoDB: Buffer pool(s) dump completed at 260923 8:38:03
romm-db | 2026-09-23 8:38:03 0 [Note] InnoDB: Removed temporary tablespace data file: "./ibtmp1"
romm-db | 2026-09-23 8:38:03 0 [Note] Shutdown completed; log sequence number 45568; transaction id 15
romm-db | 2026-09-23 8:38:04 0 [Note] mariadbd: Shutdown complete
romm-db | 2026-09-23 08:38:04+02:00 [Note] [Entrypoint]: Temporary server stopped
romm-db |
romm-db | 2026-09-23 08:38:04+02:00 [Note] [Entrypoint]: MariaDB init process done. Ready for start up.
romm-db |
romm-db | 2026-09-23 8:38:04 0 [Note] Starting MariaDB 11.4.13-MariaDB-ubu2404 source revision 170b1d70737be6f134448f51713cdc1ae215b420 server_uid CoZjczEYgGSu3N2tEniVTdlmtSg= as process 1
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Compressed tables use zlib 1.3
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Number of transaction pools: 1
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
romm-db | 2026-09-23 8:38:04 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Using Linux native AIO
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: innodb_buffer_pool_size_max=8388608m, innodb_buffer_pool_size=128m
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Completed initialization of buffer pool
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: File system buffers for log disabled (block size=512 bytes)
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: End of log at LSN=45568
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Opened 3 undo tablespaces
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: 128 rollback segments in 3 undo tablespaces are active.
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: log sequence number 45568; transaction id 14
romm-db | 2026-09-23 8:38:04 0 [Note] Plugin 'FEEDBACK' is disabled.
romm-db | 2026-09-23 8:38:04 0 [Note] Plugin 'wsrep-provider' is disabled.
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
romm-db | 2026-09-23 8:38:04 0 [Note] InnoDB: Buffer pool(s) load completed at 260923 8:38:04
romm-db | 2026-09-23 8:38:05 0 [Note] Server socket created on IP: '0.0.0.0', port: '3306'.
romm-db | 2026-09-23 8:38:05 0 [Note] Server socket created on IP: '::', port: '3306'.
romm-db | 2026-09-23 8:38:05 0 [Note] mariadbd: Event Scheduler: Loaded 0 events
romm-db | 2026-09-23 8:38:05 0 [Note] mariadbd: ready for connections.
romm-db | Version: '11.4.13-MariaDB-ubu2404' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
romm-db | 2026-09-23 8:38:27 5 [Warning] Aborted connection 5 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:38:56 16 [Warning] Aborted connection 16 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:38:56 15 [Warning] Aborted connection 15 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:39:12 19 [Warning] Aborted connection 19 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm | INFO: [RomM][init][2026-09-23 08:38:58] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:38:58] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:38:58] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:38:58] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:38:58] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:38:58] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:38:58]
romm | INFO: [RomM][init][2026-09-23 08:38:58] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:38:58]
romm | INFO: [RomM][init][2026-09-23 08:38:58] Version: 5.3.0
romm | INFO: [RomM][init][2026-09-23 08:38:58]
romm | INFO: [RomM][init][2026-09-23 08:38:58] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:38:58] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:38:58] Running database migrations
romm | INFO: [RomM][init][2026-09-23 08:39:12] Database migrations succeeded
romm | INFO: [RomM][startup][2026-09-23 08:39:24] Running startup tasks
romm | INFO: [RomM][startup][2026-09-23 08:39:24] Cleared 2 job(s) left behind by the old scheduler
romm | INFO: [RomM][startup][2026-09-23 08:39:24] Initializing cache with fixtures data
romm | INFO: [RomM][startup][2026-09-23 08:39:24] Startup tasks completed
romm | INFO: [RomM][init][2026-09-23 08:39:25] Starting backend
romm | INFO: [RomM][init][2026-09-23 08:39:25] Starting RQ cron scheduler
romm | INFO: [RomM][init][2026-09-23 08:39:25] Starting RQ worker
romm | INFO: [RomM][init][2026-09-23 08:39:25] Starting RQ scan worker
romm | INFO: [RomM][init][2026-09-23 08:39:28] Starting nginx
romm | 2026/09/23 08:39:28 [notice] 123#123: js vm init njs: 0000759641C76B00
romm | INFO: [RomM][init][2026-09-23 08:39:28] 🚀 RomM is now available at http://0.0.0.0:8080
romm | 08:39:28 Loading cron configuration from tasks.cron_config
romm | 08:39:28 Worker 8819d4ef33764a81a0fb0ff40cdca8d3: started with PID 104, version 2.12.0
romm | 08:39:28 Worker 8819d4ef33764a81a0fb0ff40cdca8d3: subscribing to channel rq:pubsub:8819d4ef33764a81a0fb0ff40cdca8d3
romm | 08:39:28 *** Listening on high, default, low...
romm | 08:39:28 Acquired scheduler lock for high
romm | 08:39:28 Acquired scheduler lock for default
romm | 08:39:28 Acquired scheduler lock for low
romm | 08:39:28 Scheduler for high, default, low started with PID 142
romm-redis | 1:C 23 Sep 2026 08:37:58.125 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
romm | 08:39:28 Worker e80205cfb5aa4cd2b78fd01218b778cf: started with PID 107, version 2.12.0
romm-redis | 1:C 23 Sep 2026 08:37:58.125 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
romm-redis | 1:C 23 Sep 2026 08:37:58.125 * Redis version=7.4.11, bits=64, commit=00000000, modified=0, pid=1, just started
romm-redis | 1:C 23 Sep 2026 08:37:58.125 * Configuration loaded
romm-redis | 1:M 23 Sep 2026 08:37:58.125 * Increased maximum number of open files to 10032 (it was originally set to 1024).
romm-redis | 1:M 23 Sep 2026 08:37:58.125 * monotonic clock: POSIX clock_gettime
romm-redis | 1:M 23 Sep 2026 08:37:58.128 * Running mode=standalone, port=6379.
romm-redis | 1:M 23 Sep 2026 08:37:58.128 * Server initialized
romm-redis | 1:M 23 Sep 2026 08:37:58.136 * Creating AOF base file appendonly.aof.1.base.rdb on server start
romm-redis | 1:M 23 Sep 2026 08:37:58.145 * Creating AOF incr file appendonly.aof.1.incr.aof on server start
romm-redis | 1:M 23 Sep 2026 08:37:58.145 * Ready to accept connections tcp
romm-redis | 1:M 23 Sep 2026 08:38:59.091 * 10000 changes in 60 seconds. Saving...
romm-redis | 1:M 23 Sep 2026 08:38:59.093 * Background saving started by pid 52
romm-redis | 52:C 23 Sep 2026 08:38:59.225 * DB saved on disk
romm-redis | 52:C 23 Sep 2026 08:38:59.226 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 1 MB
romm-redis | 1:M 23 Sep 2026 08:38:59.295 * Background saving terminated with success
romm | 08:39:28 Worker e80205cfb5aa4cd2b78fd01218b778cf: subscribing to channel rq:pubsub:e80205cfb5aa4cd2b78fd01218b778cf
romm | 08:39:28 *** Listening on scans...
romm | 08:39:28 Acquired scheduler lock for scans
romm | 08:39:28 Scheduler for scans started with PID 145
@@ -0,0 +1,20 @@
{
"romm": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
},
"romm-db": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
},
"romm-redis": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
}
}
@@ -0,0 +1,67 @@
{
"harness_version": 2,
"edge": "M1",
"app": "romm",
"note": "catalog move 15f9ebf 5.0.0 -> 5.3.0 on the CURRENT template (768M, 2 workers)",
"from": {
"romm": "rommapp/romm:5.0.0"
},
"to": {
"romm": "rommapp/romm:5.3.0"
},
"verdict": "proven",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"migration_observed": "romm | \u001b[0;32mINFO: \u001b[0;34m[RomM]\u001b[0;95m[init]\u001b[0;36m[2026-09-23 08:38:58]\u001b[0;00m Running database migrations",
"abort": "refuses",
"abort_detail": "to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:49:34 148 [Warning] Aborted connection 148 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:50:01 171 [Warning] Aborted connection 171 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:50:01 165 [Warning] Aborted connection 165 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:50:01 164 [Warning] Aborted connection 164 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:50:01 168 [Warning] Aborted connection 168 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)",
"engine_state_after": null,
"memory": {
"soak_s": 608.5,
"requested_s": 600,
"requests": 11429,
"codes": {
"200": 5712,
"401": 5717
},
"first_kill": null,
"containers": {
"romm": {
"limit": 805306368,
"peak": 651239424,
"peak_pct": 0.809,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
},
"romm-db": {
"limit": 402653184,
"peak": 155947008,
"peak_pct": 0.387,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
},
"romm-redis": {
"limit": 134217728,
"peak": 39243776,
"peak_pct": 0.292,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
}
},
"unmeasured": []
},
"marks": [
"memory_tight"
],
"duration_s": 31.6,
"measured_at": "2026-09-23T06:53:05Z",
"evidence": "evidence/M1",
"total_s": 908.0
}
@@ -0,0 +1,101 @@
romm-redis | 1:C 23 Sep 2026 08:30:39.879 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
romm-db | 2026-09-23 8:30:44 0 [Note] Shutdown completed; log sequence number 45568; transaction id 15
romm | INFO: [RomM][init][2026-09-23 08:35:28]
romm-redis | 1:C 23 Sep 2026 08:30:39.880 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
romm-redis | 1:C 23 Sep 2026 08:30:39.880 * Redis version=7.4.11, bits=64, commit=00000000, modified=0, pid=1, just started
romm-redis | 1:C 23 Sep 2026 08:30:39.880 * Configuration loaded
romm-redis | 1:M 23 Sep 2026 08:30:39.880 * Increased maximum number of open files to 10032 (it was originally set to 1024).
romm-redis | 1:M 23 Sep 2026 08:30:39.880 * monotonic clock: POSIX clock_gettime
romm-redis | 1:M 23 Sep 2026 08:30:39.881 * Running mode=standalone, port=6379.
romm-redis | 1:M 23 Sep 2026 08:30:39.882 * Server initialized
romm | INFO: [RomM][init][2026-09-23 08:35:28] Version: 5.0.0
romm-redis | 1:M 23 Sep 2026 08:30:39.886 * Creating AOF base file appendonly.aof.1.base.rdb on server start
romm | INFO: [RomM][init][2026-09-23 08:35:28]
romm-redis | 1:M 23 Sep 2026 08:30:39.899 * Creating AOF incr file appendonly.aof.1.incr.aof on server start
romm | INFO: [RomM][init][2026-09-23 08:35:28] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm-redis | 1:M 23 Sep 2026 08:30:39.899 * Ready to accept connections tcp
romm | INFO: [RomM][init][2026-09-23 08:35:28] REDIS_HOST is set, not starting internal valkey-server
romm-db | 2026-09-23 8:30:44 0 [Note] mariadbd: Shutdown complete
romm | INFO: [RomM][init][2026-09-23 08:35:28] Running database migrations
romm-redis | 1:M 23 Sep 2026 08:31:40.061 * 10000 changes in 60 seconds. Saving...
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:35:37] Failed to run database migrations
romm-redis | 1:M 23 Sep 2026 08:31:40.062 * Background saving started by pid 46
romm | INFO: [RomM][init][2026-09-23 08:35:50] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:35:50] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:35:50] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:35:50] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:35:50] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:35:50] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:35:50]
romm | INFO: [RomM][init][2026-09-23 08:35:50] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:35:50]
romm | INFO: [RomM][init][2026-09-23 08:35:50] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:35:50]
romm | INFO: [RomM][init][2026-09-23 08:35:50] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Temporary server stopped
romm | INFO: [RomM][init][2026-09-23 08:35:50] REDIS_HOST is set, not starting internal valkey-server
romm-db |
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: MariaDB init process done. Ready for start up.
romm-db |
romm-db | 2026-09-23 8:30:44 0 [Note] Starting MariaDB 11.4.13-MariaDB-ubu2404 source revision 170b1d70737be6f134448f51713cdc1ae215b420 server_uid Psh/IuH2qRBz9PeEZH//qqIAdts= as process 1
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Compressed tables use zlib 1.3
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Number of transaction pools: 1
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
romm-db | 2026-09-23 8:30:44 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-redis | 46:C 23 Sep 2026 08:31:40.211 * DB saved on disk
romm-db | create_uring failed: falling back to libaio
romm-redis | 46:C 23 Sep 2026 08:31:40.212 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 1 MB
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Using Linux native AIO
romm-redis | 1:M 23 Sep 2026 08:31:40.264 * Background saving terminated with success
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: innodb_buffer_pool_size_max=8388608m, innodb_buffer_pool_size=128m
romm | INFO: [RomM][init][2026-09-23 08:35:50] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:35:59] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:36:25] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:36:25] | __ \ | \/ |
romm-redis | 1:M 23 Sep 2026 08:36:41.033 * 100 changes in 300 seconds. Saving...
romm-redis | 1:M 23 Sep 2026 08:36:41.034 * Background saving started by pid 226
romm-redis | 226:C 23 Sep 2026 08:36:41.158 * DB saved on disk
romm-redis | 226:C 23 Sep 2026 08:36:41.159 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 0 MB
romm-redis | 1:M 23 Sep 2026 08:36:41.236 * Background saving terminated with success
romm | INFO: [RomM][init][2026-09-23 08:36:25] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:36:25] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:36:25] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:36:25] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:36:25]
romm | INFO: [RomM][init][2026-09-23 08:36:25] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:36:25]
romm | INFO: [RomM][init][2026-09-23 08:36:25] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:36:25]
romm | INFO: [RomM][init][2026-09-23 08:36:25] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:36:25] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:36:25] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:36:34] Failed to run database migrations
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Completed initialization of buffer pool
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: File system buffers for log disabled (block size=512 bytes)
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: End of log at LSN=45568
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Opened 3 undo tablespaces
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: 128 rollback segments in 3 undo tablespaces are active.
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: log sequence number 45568; transaction id 14
romm-db | 2026-09-23 8:30:44 0 [Note] Plugin 'FEEDBACK' is disabled.
romm-db | 2026-09-23 8:30:44 0 [Note] Plugin 'wsrep-provider' is disabled.
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Buffer pool(s) load completed at 260923 8:30:44
romm-db | 2026-09-23 8:30:48 0 [Note] Server socket created on IP: '0.0.0.0', port: '3306'.
romm-db | 2026-09-23 8:30:48 0 [Note] Server socket created on IP: '::', port: '3306'.
romm-db | 2026-09-23 8:30:48 0 [Note] mariadbd: Event Scheduler: Loaded 0 events
romm-db | 2026-09-23 8:30:48 0 [Note] mariadbd: ready for connections.
romm-db | Version: '11.4.13-MariaDB-ubu2404' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
romm-db | 2026-09-23 8:31:08 5 [Warning] Aborted connection 5 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:31:38 15 [Warning] Aborted connection 15 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:31:54 18 [Warning] Aborted connection 18 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:33:51 33 [Warning] Aborted connection 33 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:33:51 41 [Warning] Aborted connection 41 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:33:51 32 [Warning] Aborted connection 32 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:34:11 36 [Warning] Aborted connection 36 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:34:11 42 [Warning] Aborted connection 42 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:34:11 49 [Warning] Aborted connection 49 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
@@ -0,0 +1,20 @@
{
"romm": {
"status": "restarting",
"health": "unhealthy",
"restarts": 0,
"exit": 1
},
"romm-db": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
},
"romm-redis": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
}
}
@@ -0,0 +1,265 @@
romm-redis | 1:C 23 Sep 2026 08:30:39.879 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
romm-redis | 1:C 23 Sep 2026 08:30:39.880 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
romm-redis | 1:C 23 Sep 2026 08:30:39.880 * Redis version=7.4.11, bits=64, commit=00000000, modified=0, pid=1, just started
romm | INFO: [RomM][init][2026-09-23 08:34:12] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:34:12] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:34:12] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:34:12] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:34:12] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:34:12] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:34:12]
romm | INFO: [RomM][init][2026-09-23 08:34:12] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:34:12]
romm | INFO: [RomM][init][2026-09-23 08:34:12] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:34:12]
romm | INFO: [RomM][init][2026-09-23 08:34:12] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:34:12] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:34:12] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:34:21] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:34:21] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:34:21] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:34:21] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:34:21] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:34:21] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:34:21] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:34:21]
romm | INFO: [RomM][init][2026-09-23 08:34:21] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:34:21]
romm | INFO: [RomM][init][2026-09-23 08:34:21] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:34:21]
romm | INFO: [RomM][init][2026-09-23 08:34:21] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:34:21] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:34:21] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:34:30] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:34:31] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:34:31] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:34:31] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:34:31] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:34:31] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:34:31] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:34:31]
romm | INFO: [RomM][init][2026-09-23 08:34:31] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:34:31]
romm | INFO: [RomM][init][2026-09-23 08:34:31] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:34:31]
romm | INFO: [RomM][init][2026-09-23 08:34:31] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:34:31] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:34:31] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:34:40] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:34:40] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:34:40] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:34:40] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:34:40] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:34:40] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:34:40] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:34:40]
romm | INFO: [RomM][init][2026-09-23 08:34:40] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:34:40]
romm | INFO: [RomM][init][2026-09-23 08:34:40] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:34:40]
romm | INFO: [RomM][init][2026-09-23 08:34:40] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:34:40] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:34:40] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:34:49] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:34:50] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:34:50] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:34:50] | |__) |___ _ __ ___ | \ / |
romm-db | 2026-09-23 08:30:40+02:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:11.4.13+maria~ubu2404 started.
romm | INFO: [RomM][init][2026-09-23 08:34:50] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:34:50] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:34:50] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:34:50]
romm-db | 2026-09-23 08:30:40+02:00 [Warn] [Entrypoint]: /sys/fs/cgroup///memory.pressure not writable, functionality unavailable to MariaDB
romm | INFO: [RomM][init][2026-09-23 08:34:50] The beautiful, powerful, self-hosted Rom manager and player
romm-db | 2026-09-23 08:30:40+02:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
romm-db | 2026-09-23 08:30:40+02:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:11.4.13+maria~ubu2404 started.
romm-db | 2026-09-23 08:30:40+02:00 [Note] [Entrypoint]: Initializing database files
romm-db | 2026-09-23 8:30:40 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 08:30:42+02:00 [Note] [Entrypoint]: Database files initialized
romm-db | 2026-09-23 08:30:42+02:00 [Note] [Entrypoint]: Starting temporary server
romm-db | 2026-09-23 08:30:42+02:00 [Note] [Entrypoint]: Waiting for server startup
romm-db | 2026-09-23 8:30:42 0 [Note] Starting MariaDB 11.4.13-MariaDB-ubu2404 source revision 170b1d70737be6f134448f51713cdc1ae215b420 server_uid Psh/IuH2qRBz9PeEZH//qqIAdts= as process 92
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Compressed tables use zlib 1.3
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Number of transaction pools: 1
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
romm-db | 2026-09-23 8:30:42 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Using Linux native AIO
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: innodb_buffer_pool_size_max=8388608m, innodb_buffer_pool_size=128m
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Completed initialization of buffer pool
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: File system buffers for log disabled (block size=512 bytes)
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: End of log at LSN=45568
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Opened 3 undo tablespaces
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: 128 rollback segments in 3 undo tablespaces are active.
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: log sequence number 45568; transaction id 14
romm-db | 2026-09-23 8:30:42 0 [Note] Plugin 'FEEDBACK' is disabled.
romm-db | 2026-09-23 8:30:42 0 [Note] Plugin 'wsrep-provider' is disabled.
romm-db | 2026-09-23 8:30:43 0 [Note] mariadbd: Event Scheduler: Loaded 0 events
romm-db | 2026-09-23 8:30:43 0 [Note] mariadbd: ready for connections.
romm-db | Version: '11.4.13-MariaDB-ubu2404' socket: '/run/mysqld/mysqld.sock' port: 0 mariadb.org binary distribution
romm-db | 2026-09-23 08:30:43+02:00 [Note] [Entrypoint]: Temporary server started.
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Creating database romm
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Creating user romm
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Giving user romm access to schema romm
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Securing system users (equivalent to running mysql_secure_installation)
romm-db |
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Stopping temporary server
romm-db | 2026-09-23 8:30:44 0 [Note] mariadbd (initiated by: unknown): Normal shutdown
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: FTS optimize thread exiting.
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Starting shutdown...
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Buffer pool(s) dump completed at 260923 8:30:44
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Removed temporary tablespace data file: "./ibtmp1"
romm-db | 2026-09-23 8:30:44 0 [Note] Shutdown completed; log sequence number 45568; transaction id 15
romm-redis | 1:C 23 Sep 2026 08:30:39.880 * Configuration loaded
romm | INFO: [RomM][init][2026-09-23 08:34:50]
romm-redis | 1:M 23 Sep 2026 08:30:39.880 * Increased maximum number of open files to 10032 (it was originally set to 1024).
romm | INFO: [RomM][init][2026-09-23 08:34:50] Version: 5.0.0
romm-redis | 1:M 23 Sep 2026 08:30:39.880 * monotonic clock: POSIX clock_gettime
romm | INFO: [RomM][init][2026-09-23 08:34:50]
romm-redis | 1:M 23 Sep 2026 08:30:39.881 * Running mode=standalone, port=6379.
romm-redis | 1:M 23 Sep 2026 08:30:39.882 * Server initialized
romm-redis | 1:M 23 Sep 2026 08:30:39.886 * Creating AOF base file appendonly.aof.1.base.rdb on server start
romm-redis | 1:M 23 Sep 2026 08:30:39.899 * Creating AOF incr file appendonly.aof.1.incr.aof on server start
romm-db | 2026-09-23 8:30:44 0 [Note] mariadbd: Shutdown complete
romm-redis | 1:M 23 Sep 2026 08:30:39.899 * Ready to accept connections tcp
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Temporary server stopped
romm-redis | 1:M 23 Sep 2026 08:31:40.061 * 10000 changes in 60 seconds. Saving...
romm-db |
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: MariaDB init process done. Ready for start up.
romm-db |
romm | INFO: [RomM][init][2026-09-23 08:34:50] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:34:50] REDIS_HOST is set, not starting internal valkey-server
romm-db | 2026-09-23 8:30:44 0 [Note] Starting MariaDB 11.4.13-MariaDB-ubu2404 source revision 170b1d70737be6f134448f51713cdc1ae215b420 server_uid Psh/IuH2qRBz9PeEZH//qqIAdts= as process 1
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Compressed tables use zlib 1.3
romm-redis | 1:M 23 Sep 2026 08:31:40.062 * Background saving started by pid 46
romm-redis | 46:C 23 Sep 2026 08:31:40.211 * DB saved on disk
romm-redis | 46:C 23 Sep 2026 08:31:40.212 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 1 MB
romm-redis | 1:M 23 Sep 2026 08:31:40.264 * Background saving terminated with success
romm-redis | 1:M 23 Sep 2026 08:36:41.033 * 100 changes in 300 seconds. Saving...
romm | INFO: [RomM][init][2026-09-23 08:34:50] Running database migrations
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Number of transaction pools: 1
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm-db | 2026-09-23 8:30:44 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-redis | 1:M 23 Sep 2026 08:36:41.034 * Background saving started by pid 226
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Using Linux native AIO
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: innodb_buffer_pool_size_max=8388608m, innodb_buffer_pool_size=128m
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Completed initialization of buffer pool
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: File system buffers for log disabled (block size=512 bytes)
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: End of log at LSN=45568
romm | ERROR: [RomM][init][2026-09-23 08:34:59] Failed to run database migrations
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Opened 3 undo tablespaces
romm-redis | 226:C 23 Sep 2026 08:36:41.158 * DB saved on disk
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: 128 rollback segments in 3 undo tablespaces are active.
romm-redis | 226:C 23 Sep 2026 08:36:41.159 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 0 MB
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: log sequence number 45568; transaction id 14
romm-db | 2026-09-23 8:30:44 0 [Note] Plugin 'FEEDBACK' is disabled.
romm-db | 2026-09-23 8:30:44 0 [Note] Plugin 'wsrep-provider' is disabled.
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
romm-redis | 1:M 23 Sep 2026 08:36:41.236 * Background saving terminated with success
romm | INFO: [RomM][init][2026-09-23 08:35:01] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:35:01] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:35:01] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:35:01] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:35:01] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:35:01] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:35:01]
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Buffer pool(s) load completed at 260923 8:30:44
romm-db | 2026-09-23 8:30:48 0 [Note] Server socket created on IP: '0.0.0.0', port: '3306'.
romm-db | 2026-09-23 8:30:48 0 [Note] Server socket created on IP: '::', port: '3306'.
romm-db | 2026-09-23 8:30:48 0 [Note] mariadbd: Event Scheduler: Loaded 0 events
romm-db | 2026-09-23 8:30:48 0 [Note] mariadbd: ready for connections.
romm-db | Version: '11.4.13-MariaDB-ubu2404' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
romm-db | 2026-09-23 8:31:08 5 [Warning] Aborted connection 5 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:31:38 15 [Warning] Aborted connection 15 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm | INFO: [RomM][init][2026-09-23 08:35:01] The beautiful, powerful, self-hosted Rom manager and player
romm-db | 2026-09-23 8:31:54 18 [Warning] Aborted connection 18 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:33:51 33 [Warning] Aborted connection 33 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:33:51 41 [Warning] Aborted connection 41 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:33:51 32 [Warning] Aborted connection 32 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:34:11 36 [Warning] Aborted connection 36 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:34:11 42 [Warning] Aborted connection 42 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:34:11 49 [Warning] Aborted connection 49 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm | INFO: [RomM][init][2026-09-23 08:35:01]
romm | INFO: [RomM][init][2026-09-23 08:35:01] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:35:01]
romm | INFO: [RomM][init][2026-09-23 08:35:01] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:35:01] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:35:01] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:35:09] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:35:13] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:35:13] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:35:13] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:35:13] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:35:13] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:35:13] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:35:13]
romm | INFO: [RomM][init][2026-09-23 08:35:13] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:35:13]
romm | INFO: [RomM][init][2026-09-23 08:35:13] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:35:13]
romm | INFO: [RomM][init][2026-09-23 08:35:13] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:35:13] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:35:13] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:35:22] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:35:28] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:35:28] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:35:28] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:35:28] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:35:28] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:35:28] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:35:28]
romm | INFO: [RomM][init][2026-09-23 08:35:28] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:35:28]
romm | INFO: [RomM][init][2026-09-23 08:35:28] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:35:28]
romm | INFO: [RomM][init][2026-09-23 08:35:28] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:35:28] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:35:28] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:35:37] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:35:50] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:35:50] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:35:50] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:35:50] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:35:50] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:35:50] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:35:50]
romm | INFO: [RomM][init][2026-09-23 08:35:50] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:35:50]
romm | INFO: [RomM][init][2026-09-23 08:35:50] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:35:50]
romm | INFO: [RomM][init][2026-09-23 08:35:50] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:35:50] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:35:50] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:35:59] Failed to run database migrations
romm | INFO: [RomM][init][2026-09-23 08:36:25] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:36:25] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:36:25] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:36:25] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:36:25] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:36:25] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:36:25]
romm | INFO: [RomM][init][2026-09-23 08:36:25] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:36:25]
romm | INFO: [RomM][init][2026-09-23 08:36:25] Version: 5.0.0
romm | INFO: [RomM][init][2026-09-23 08:36:25]
romm | INFO: [RomM][init][2026-09-23 08:36:25] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:36:25] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:36:25] Running database migrations
romm | FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
romm | ERROR: [RomM][init][2026-09-23 08:36:34] Failed to run database migrations
@@ -0,0 +1,182 @@
[
{
"t": 15.2,
"containers": {
"romm": {
"limit": 536870912,
"current": 536096768,
"peak": 536875008,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
},
"romm-db": {
"limit": 402653184,
"current": 146841600,
"peak": 152616960,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
},
"romm-redis": {
"limit": 134217728,
"current": 16109568,
"peak": 32137216,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 286
},
{
"t": 30.4,
"containers": {
"romm": {
"limit": 536870912,
"current": 534298624,
"peak": 536875008,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
},
"romm-db": {
"limit": 402653184,
"current": 147464192,
"peak": 153600000,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
},
"romm-redis": {
"limit": 134217728,
"current": 16093184,
"peak": 32137216,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 575
},
{
"t": 45.6,
"containers": {
"romm": {
"limit": 536870912,
"current": 535674880,
"peak": 536875008,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
},
"romm-db": {
"limit": 402653184,
"current": 147525632,
"peak": 153600000,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
},
"romm-redis": {
"limit": 134217728,
"current": 16617472,
"peak": 32137216,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 864
},
{
"t": 60.8,
"containers": {
"romm": {
"limit": 536870912,
"current": 533225472,
"peak": 536875008,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
},
"romm-db": {
"limit": 402653184,
"current": 147542016,
"peak": 153600000,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
},
"romm-redis": {
"limit": 134217728,
"current": 16547840,
"peak": 32137216,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 1157
},
{
"t": 76.0,
"containers": {
"romm": {
"limit": 536870912,
"current": 534589440,
"peak": 536875008,
"oom_kill": 1,
"restarts": 0,
"oomkilled_flag": true,
"status": "running",
"cgroup": true
},
"romm-db": {
"limit": 402653184,
"current": 147644416,
"peak": 153600000,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
},
"romm-redis": {
"limit": 134217728,
"current": 16531456,
"peak": 32137216,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 1404
}
]
@@ -0,0 +1,2 @@
romm | INFO: [RomM][init][2026-09-23 08:31:39] Running database migrations
romm | INFO: [RomM][init][2026-09-23 08:31:54] Database migrations succeeded
@@ -0,0 +1,22 @@
[06:30:39] M1old: deploying romm at FROM {'romm': 'rommapp/romm:5.0.0'}
[06:31:27] FROM settled=True in 36.7s :: {"romm": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-db": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-redis": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[06:31:34] romm: POST /api/users http=201
[06:31:36] romm: login as the seeded user http=200 ok=True
[06:31:36] C1 (seed reads back BEFORE): True
[06:31:36] M1old: swapping to TO {'romm': 'rommapp/romm:5.3.0'}
[06:31:39] TO up -d rc=0
[06:32:11] TO settled=True in 31.5s :: {"romm": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-db": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}, "romm-redis": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[06:32:11] migration lines observed: 2
[06:32:44] romm: login as the seeded user http=200 ok=True
[06:32:44] RESULT (seed reads back AFTER): True
[06:32:44] memory watch: 600s, 4 callers on 8 path(s) at 172.18.0.6:8080
[06:33:00] + 15s romm=511M/512M peak=512M kills=0 rs=0 romm-db=140M/384M peak=145M kills=0 rs=0 romm-redis=15M/128M peak=30M kills=0 rs=0 reqs=286
[06:33:15] + 30s romm=509M/512M peak=512M kills=0 rs=0 romm-db=140M/384M peak=146M kills=0 rs=0 romm-redis=15M/128M peak=30M kills=0 rs=0 reqs=575
[06:33:30] + 46s romm=510M/512M peak=512M kills=0 rs=0 romm-db=140M/384M peak=146M kills=0 rs=0 romm-redis=15M/128M peak=30M kills=0 rs=0 reqs=864
[06:33:45] + 61s romm=508M/512M peak=512M kills=0 rs=0 romm-db=140M/384M peak=146M kills=0 rs=0 romm-redis=15M/128M peak=30M kills=0 rs=0 reqs=1157
[06:34:00] + 76s romm=509M/512M peak=512M kills=1 rs=0 romm-db=140M/384M peak=146M kills=0 rs=0 romm-redis=15M/128M peak=30M kills=0 rs=0 reqs=1404
[06:34:00] memory watch: STOPPING EARLY — {'t': 76.0, 'container': 'romm', 'oom_kills': 1, 'restarts': 0}
[06:34:01] memory watch: killed=True tight=['romm'] requests=1405 codes={'401': 704, '200': 701}
[06:34:01] VERDICT -> failed: the new version was OOM-killed or restarted under light load
[06:34:01] M1old: ABORT — putting the FROM images back
[06:37:15] ABORT: the app did NOT come back (rc=0, 182.4s)
@@ -0,0 +1,133 @@
romm-db | 2026-09-23 08:30:40+02:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:11.4.13+maria~ubu2404 started.
romm-db | 2026-09-23 08:30:40+02:00 [Warn] [Entrypoint]: /sys/fs/cgroup///memory.pressure not writable, functionality unavailable to MariaDB
romm-db | 2026-09-23 08:30:40+02:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
romm | INFO: [RomM][init][2026-09-23 08:31:39] _____ __ __
romm | INFO: [RomM][init][2026-09-23 08:31:39] | __ \ | \/ |
romm | INFO: [RomM][init][2026-09-23 08:31:39] | |__) |___ _ __ ___ | \ / |
romm | INFO: [RomM][init][2026-09-23 08:31:39] | _ // _ \| '_ ` _ \| |\/| |
romm | INFO: [RomM][init][2026-09-23 08:31:39] | | \ \ (_) | | | | | | | | |
romm | INFO: [RomM][init][2026-09-23 08:31:39] |_| \_\___/|_| |_| |_|_| |_|
romm | INFO: [RomM][init][2026-09-23 08:31:39]
romm | INFO: [RomM][init][2026-09-23 08:31:39] The beautiful, powerful, self-hosted Rom manager and player
romm | INFO: [RomM][init][2026-09-23 08:31:39]
romm | INFO: [RomM][init][2026-09-23 08:31:39] Version: 5.3.0
romm | INFO: [RomM][init][2026-09-23 08:31:39]
romm | INFO: [RomM][init][2026-09-23 08:31:39] No OpenTelemetry environment variables found, disabling OpenTelemetry SDK
romm | INFO: [RomM][init][2026-09-23 08:31:39] REDIS_HOST is set, not starting internal valkey-server
romm | INFO: [RomM][init][2026-09-23 08:31:39] Running database migrations
romm | INFO: [RomM][init][2026-09-23 08:31:54] Database migrations succeeded
romm | INFO: [RomM][startup][2026-09-23 08:32:06] Running startup tasks
romm | INFO: [RomM][startup][2026-09-23 08:32:06] Cleared 2 job(s) left behind by the old scheduler
romm | INFO: [RomM][startup][2026-09-23 08:32:06] Initializing cache with fixtures data
romm | INFO: [RomM][startup][2026-09-23 08:32:06] Startup tasks completed
romm | INFO: [RomM][init][2026-09-23 08:32:07] Starting backend
romm | INFO: [RomM][init][2026-09-23 08:32:07] Starting RQ cron scheduler
romm | INFO: [RomM][init][2026-09-23 08:32:07] Starting RQ worker
romm | INFO: [RomM][init][2026-09-23 08:32:07] Starting RQ scan worker
romm | INFO: [RomM][init][2026-09-23 08:32:09] Starting nginx
romm | 2026/09/23 08:32:09 [notice] 119#119: js vm init njs: 00007E35328F6B00
romm | INFO: [RomM][init][2026-09-23 08:32:09] 🚀 RomM is now available at http://0.0.0.0:8080
romm | 08:32:09 Worker 4e9ae2d061064c5d9b285b68af387d4f: started with PID 107, version 2.12.0
romm | 08:32:09 Worker 4e9ae2d061064c5d9b285b68af387d4f: subscribing to channel rq:pubsub:4e9ae2d061064c5d9b285b68af387d4f
romm | 08:32:09 Loading cron configuration from tasks.cron_config
romm | 08:32:09 *** Listening on scans...
romm | 08:32:09 Worker 55f7c62f88dd43c29e0873eb10c480ad: started with PID 104, version 2.12.0
romm | 08:32:09 Acquired scheduler lock for scans
romm | 08:32:09 Worker 55f7c62f88dd43c29e0873eb10c480ad: subscribing to channel rq:pubsub:55f7c62f88dd43c29e0873eb10c480ad
romm | 08:32:09 *** Listening on high, default, low...
romm | 08:32:09 Acquired scheduler lock for high
romm | 08:32:09 Acquired scheduler lock for default
romm | 08:32:09 Acquired scheduler lock for low
romm | 08:32:09 Scheduler for scans started with PID 145
romm | 08:32:09 Scheduler for high, default, low started with PID 144
romm-db | 2026-09-23 08:30:40+02:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:11.4.13+maria~ubu2404 started.
romm-db | 2026-09-23 08:30:40+02:00 [Note] [Entrypoint]: Initializing database files
romm-db | 2026-09-23 8:30:40 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 08:30:42+02:00 [Note] [Entrypoint]: Database files initialized
romm-db | 2026-09-23 08:30:42+02:00 [Note] [Entrypoint]: Starting temporary server
romm-db | 2026-09-23 08:30:42+02:00 [Note] [Entrypoint]: Waiting for server startup
romm-db | 2026-09-23 8:30:42 0 [Note] Starting MariaDB 11.4.13-MariaDB-ubu2404 source revision 170b1d70737be6f134448f51713cdc1ae215b420 server_uid Psh/IuH2qRBz9PeEZH//qqIAdts= as process 92
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Compressed tables use zlib 1.3
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Number of transaction pools: 1
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
romm-db | 2026-09-23 8:30:42 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Using Linux native AIO
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: innodb_buffer_pool_size_max=8388608m, innodb_buffer_pool_size=128m
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Completed initialization of buffer pool
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: File system buffers for log disabled (block size=512 bytes)
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: End of log at LSN=45568
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Opened 3 undo tablespaces
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: 128 rollback segments in 3 undo tablespaces are active.
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
romm-db | 2026-09-23 8:30:42 0 [Note] InnoDB: log sequence number 45568; transaction id 14
romm-db | 2026-09-23 8:30:42 0 [Note] Plugin 'FEEDBACK' is disabled.
romm-db | 2026-09-23 8:30:42 0 [Note] Plugin 'wsrep-provider' is disabled.
romm-db | 2026-09-23 8:30:43 0 [Note] mariadbd: Event Scheduler: Loaded 0 events
romm-db | 2026-09-23 8:30:43 0 [Note] mariadbd: ready for connections.
romm-db | Version: '11.4.13-MariaDB-ubu2404' socket: '/run/mysqld/mysqld.sock' port: 0 mariadb.org binary distribution
romm-db | 2026-09-23 08:30:43+02:00 [Note] [Entrypoint]: Temporary server started.
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Creating database romm
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Creating user romm
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Giving user romm access to schema romm
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Securing system users (equivalent to running mysql_secure_installation)
romm-db |
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Stopping temporary server
romm-db | 2026-09-23 8:30:44 0 [Note] mariadbd (initiated by: unknown): Normal shutdown
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: FTS optimize thread exiting.
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Starting shutdown...
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Buffer pool(s) dump completed at 260923 8:30:44
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Removed temporary tablespace data file: "./ibtmp1"
romm-db | 2026-09-23 8:30:44 0 [Note] Shutdown completed; log sequence number 45568; transaction id 15
romm-db | 2026-09-23 8:30:44 0 [Note] mariadbd: Shutdown complete
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: Temporary server stopped
romm-db |
romm-db | 2026-09-23 08:30:44+02:00 [Note] [Entrypoint]: MariaDB init process done. Ready for start up.
romm-db |
romm-db | 2026-09-23 8:30:44 0 [Note] Starting MariaDB 11.4.13-MariaDB-ubu2404 source revision 170b1d70737be6f134448f51713cdc1ae215b420 server_uid Psh/IuH2qRBz9PeEZH//qqIAdts= as process 1
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Compressed tables use zlib 1.3
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Number of transaction pools: 1
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
romm-db | 2026-09-23 8:30:44 0 [Warning] mariadbd: io_uring_queue_init() failed with EPERM: sysctl kernel.io_uring_disabled has the value 2, or 1 and the user of the process is not a member of sysctl kernel.io_uring_group. (see man 2 io_uring_setup).
romm-db | create_uring failed: falling back to libaio
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Using Linux native AIO
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: innodb_buffer_pool_size_max=8388608m, innodb_buffer_pool_size=128m
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Completed initialization of buffer pool
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: File system buffers for log disabled (block size=512 bytes)
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: End of log at LSN=45568
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Opened 3 undo tablespaces
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: 128 rollback segments in 3 undo tablespaces are active.
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: log sequence number 45568; transaction id 14
romm-db | 2026-09-23 8:30:44 0 [Note] Plugin 'FEEDBACK' is disabled.
romm-db | 2026-09-23 8:30:44 0 [Note] Plugin 'wsrep-provider' is disabled.
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
romm-db | 2026-09-23 8:30:44 0 [Note] InnoDB: Buffer pool(s) load completed at 260923 8:30:44
romm-db | 2026-09-23 8:30:48 0 [Note] Server socket created on IP: '0.0.0.0', port: '3306'.
romm-db | 2026-09-23 8:30:48 0 [Note] Server socket created on IP: '::', port: '3306'.
romm-db | 2026-09-23 8:30:48 0 [Note] mariadbd: Event Scheduler: Loaded 0 events
romm-db | 2026-09-23 8:30:48 0 [Note] mariadbd: ready for connections.
romm-db | Version: '11.4.13-MariaDB-ubu2404' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
romm-db | 2026-09-23 8:31:08 5 [Warning] Aborted connection 5 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:31:38 15 [Warning] Aborted connection 15 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-db | 2026-09-23 8:31:54 18 [Warning] Aborted connection 18 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)
romm-redis | 1:C 23 Sep 2026 08:30:39.879 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
romm-redis | 1:C 23 Sep 2026 08:30:39.880 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
romm-redis | 1:C 23 Sep 2026 08:30:39.880 * Redis version=7.4.11, bits=64, commit=00000000, modified=0, pid=1, just started
romm-redis | 1:C 23 Sep 2026 08:30:39.880 * Configuration loaded
romm-redis | 1:M 23 Sep 2026 08:30:39.880 * Increased maximum number of open files to 10032 (it was originally set to 1024).
romm-redis | 1:M 23 Sep 2026 08:30:39.880 * monotonic clock: POSIX clock_gettime
romm-redis | 1:M 23 Sep 2026 08:30:39.881 * Running mode=standalone, port=6379.
romm-redis | 1:M 23 Sep 2026 08:30:39.882 * Server initialized
romm-redis | 1:M 23 Sep 2026 08:30:39.886 * Creating AOF base file appendonly.aof.1.base.rdb on server start
romm-redis | 1:M 23 Sep 2026 08:30:39.899 * Creating AOF incr file appendonly.aof.1.incr.aof on server start
romm-redis | 1:M 23 Sep 2026 08:30:39.899 * Ready to accept connections tcp
romm-redis | 1:M 23 Sep 2026 08:31:40.061 * 10000 changes in 60 seconds. Saving...
romm-redis | 1:M 23 Sep 2026 08:31:40.062 * Background saving started by pid 46
romm-redis | 46:C 23 Sep 2026 08:31:40.211 * DB saved on disk
romm-redis | 46:C 23 Sep 2026 08:31:40.212 * Fork CoW for RDB: current 1 MB, peak 1 MB, average 1 MB
romm-redis | 1:M 23 Sep 2026 08:31:40.264 * Background saving terminated with success
@@ -0,0 +1,20 @@
{
"romm": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
},
"romm-db": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
},
"romm-redis": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
}
}
@@ -0,0 +1,70 @@
{
"harness_version": 2,
"edge": "M1old",
"app": "romm",
"note": "the same move on the template AS PROMOTED (512M, 4 workers) \u2014 must FAIL the memory watch",
"from": {
"romm": "rommapp/romm:5.0.0"
},
"to": {
"romm": "rommapp/romm:5.3.0"
},
"verdict": "failed",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"migration_observed": "romm | \u001b[0;32mINFO: \u001b[0;34m[RomM]\u001b[0;95m[init]\u001b[0;36m[2026-09-23 08:31:39]\u001b[0;00m Running database migrations",
"abort": "refuses",
"abort_detail": "ection 33 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:33:51 41 [Warning] Aborted connection 41 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:33:51 32 [Warning] Aborted connection 32 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:34:11 36 [Warning] Aborted connection 36 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:34:11 42 [Warning] Aborted connection 42 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)\nromm-db | 2026-09-23 8:34:11 49 [Warning] Aborted connection 49 to db: 'romm' user: 'romm' host: '172.20.0.4' (Got an error reading communication packets)",
"engine_state_after": null,
"memory": {
"soak_s": 76.5,
"requested_s": 600,
"requests": 1405,
"codes": {
"401": 704,
"200": 701
},
"first_kill": {
"t": 76.0,
"container": "romm",
"oom_kills": 1,
"restarts": 0
},
"containers": {
"romm": {
"limit": 536870912,
"peak": 536875008,
"peak_pct": 1.0,
"oom_kills": 1,
"restarts": 0,
"oomkilled_flag": true,
"measured": true
},
"romm-db": {
"limit": 402653184,
"peak": 153600000,
"peak_pct": 0.381,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
},
"romm-redis": {
"limit": 134217728,
"peak": 32137216,
"peak_pct": 0.239,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
}
},
"unmeasured": []
},
"marks": [],
"duration_s": 31.5,
"measured_at": "2026-09-23T06:37:15Z",
"evidence": "evidence/M1old",
"total_s": 395.7
}
@@ -0,0 +1,60 @@
#!/usr/bin/env python3
"""Point guest 9202 at the drill catalog (and a 90 s health timeout), or restore the saved config.
`09` §6.5: `git.repo_url` alone is INERT (R-615) — the cache dir must go too. The saved copy is
`controller.yaml.pre-rulings` (NOT the older `.pre-28`, which a restore must never pick up).
"""
import re, sys, io
sys.path.insert(0, '.')
import walk as w
VOL = "/var/lib/docker/volumes/felhom-controller-data/_data"
DRILL_REPO = "https://gitea.dooplex.hu/admin/app-catalog-drill.git"
def creds():
for l in io.open("/home/kisfenyo/.git-credentials").read().strip().split("\n"):
m = re.match(r'https://(admin):([^@]+)@gitea\.dooplex\.hu', l)
if m:
return m.group(1), m.group(2)
raise SystemExit("no admin credential")
def to_drill():
u, t = creds()
print(w.guest(f"""
set -e
test -f {VOL}/controller.yaml.pre-rulings || cp -p {VOL}/controller.yaml {VOL}/controller.yaml.pre-rulings
python3 - <<'PY'
import re
p = "{VOL}/controller.yaml"
s = open(p).read()
s = re.sub(r'(^\\s+repo_url: ).*$', r'\\g<1>{DRILL_REPO}', s, count=1, flags=re.M)
s = re.sub(r'(^git:(?:\\n\\s+.*)*?\\n\\s+token: ).*$', r'\\g<1>"{t}"', s, count=1, flags=re.M)
s = re.sub(r'(^git:(?:\\n\\s+.*)*?\\n\\s+username: ).*$', r'\\g<1>"{u}"', s, count=1, flags=re.M)
if not re.search(r'^update:', s, re.M):
s += "update:\\n health_timeout: 90s\\n"
open(p, "w").write(s)
PY
rm -rf {VOL}/catalog-cache {VOL}/data/catalog-cache
docker restart felhom-controller >/dev/null
sleep 15
grep -A6 '^git:' {VOL}/controller.yaml | sed 's/token:.*/token: <redacted>/'
grep -A2 '^update:' {VOL}/controller.yaml
"""))
def restore():
print(w.guest(f"""
set -e
cp -p {VOL}/controller.yaml.pre-rulings {VOL}/controller.yaml
rm -rf {VOL}/catalog-cache {VOL}/data/catalog-cache
docker restart felhom-controller >/dev/null
sleep 15
grep -A6 '^git:' {VOL}/controller.yaml | sed 's/token:.*/token: <redacted>/'
grep -c '^update:' {VOL}/controller.yaml || true
"""))
if __name__ == "__main__":
to_drill() if sys.argv[1] == "drill" else restore()
@@ -0,0 +1,22 @@
08:12:14 [1] made the drive paths this app requires: ['/mnt/felhom-drives/scratch_hdd/userdata/romm']
08:12:14 [1] required fields filled beyond DOMAIN/SUBDOMAIN: ['HDD_PATH']
08:12:14 [1] deploy -> 202 {'ok': True, 'message': 'Telepítés elindítva – az állapot a kártyán követhető'}
08:13:05 [1] deployed, controller state=running, pinned={'romm': 'rommapp/romm:5.0.0', 'romm-db': 'mariadb:11.4', 'romm-redis': 'redis:7-alpine'}
08:13:05 deployed: True
08:13:07 {"pinned_images": {"romm": "rommapp/romm:5.0.0", "romm-db": "mariadb:11.4", "romm-redis": "redis:7-alpine"}, "installed_images": {"romm": "rommapp/romm:5.0.0", "romm-db": "mariadb:11.4", "romm-redis": "redis:7-alpine"}, "catalog_images": null, "live_compose_image_lines": ["image: rommapp/romm:5.0.0", "image: mariadb:11.4", "image: redis:7-alpine"], "docker_inspect": ["romm rommapp/romm:5.0.0 running=true restarts=0", "romm-db mariadb:11.4 running=true restarts=0", "romm-redis redis:7-alpine running=true restarts=0"]}
08:13:09 bind sources: ['/mnt/felhom-drives/scratch_hdd/userdata/romm/userdata/roms', '/mnt/felhom-drives/scratch_hdd/userdata/romm/appdata/romm/resources']
08:13:11 romm: POST /api/users http=201
08:13:13 romm: login as the seeded user http=200 ok=True
08:13:13 C1 A: True
08:13:13 [4] „Mentés most" -> 200 {'ok': True, 'message': 'Mentés elindítva'}
08:14:13 [4] backup idle; last=None
08:14:13 romm seed B: POST /api/users (as the admin) http=404 404 page not found
08:14:13 B reads back: None
08:14:16 /mnt/felhom-drives/scratch_hdd/userdata/romm/userdata/roms: files=0 sum=e3b0c44298fc1c14
/mnt/felhom-drives/scratch_hdd/userdata/romm/appdata/romm/resources: files=0 sum=e3b0c44298fc1c14
08:14:35 seed B retry — the first try met traefik's 404 while the backup's volume dump had the app stopped
08:14:47 romm seed B: POST /api/users (as the admin) http=201 {"id":2,"username":"drillbecef29","email":"drillbecef29@gate.invalid","enabled":true,"role":"user","permission_group_id"
08:14:47 romm B: GET /api/users http=200 seeded-user-listed=True (negative control listed=False)
08:14:47 B reads back: True
@@ -0,0 +1,19 @@
08:15:12 mariadb before update: tables=27 alembic=0095_virtual_collections_source users=2
08:15:13 [5] drill commit 57a4be3d2832: romm rommapp/romm:5.0.0 -> rommapp/romm:5.3.0 (push rc=0)
08:15:18 badge caught up after 4.5 s
08:15:18 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
08:15:18 + 0.0s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None
08:15:19 + 1.0s phase=pulling label=Új verzió letöltése… err=None hold=None
08:15:20 + 2.1s phase=starting label=Indítás az új verzióval… err=None hold=None
08:15:25 + 7.2s phase=verifying label=Működés ellenőrzése… err=None hold=None
08:17:00 + 102.6s phase=failed label=A frissítés nem sikerült err=A(z) romm frissítése 2026-09-23 08:17-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: saját meghajtó, 2026-09-23 08:14 — ez a másolat csak a beállításokat és az adatbázist tartalmazza, a fájlokat nem. hold=A(z) romm frissítése 2026-09-23 08:17-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: saját meghajtó, 2026-09-23 08:14 — ez a másolat csak a beállításokat és az adatbázist tartalmazza, a fájlokat nem.
08:17:01 {"final_phase": "failed", "hold_reason": "A(z) romm frissítése 2026-09-23 08:17-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: saját meghajtó, 2026-09-23 08:14 — ez a másolat csak a beállításokat és az adatbázist tartalmazza, a fájlokat nem.", "state": "stopped", "duration_s": 102.6}
08:17:03 {"pinned_images": {"romm": "rommapp/romm:5.3.0", "romm-db": "mariadb:11.4", "romm-redis": "redis:7-alpine"}, "installed_images": {"romm": "rommapp/romm:5.0.0", "romm-db": "mariadb:11.4", "romm-redis": "redis:7-alpine"}, "catalog_images": {"romm": "rommapp/romm:5.3.0", "romm-db": "mariadb:11.4", "romm-redis": "redis:7-alpine"}, "live_compose_image_lines": ["image: rommapp/romm:5.3.0", "image: mariadb:11.4", "image: redis:7-alpine"], "docker_inspect": []}
08:17:05 /mnt/felhom-drives/scratch_hdd/userdata/romm/userdata/roms: files=0 sum=e3b0c44298fc1c14
/mnt/felhom-drives/scratch_hdd/userdata/romm/appdata/romm/resources: files=0 sum=e3b0c44298fc1c14
08:17:07 20260923T061656Z
3
ls: cannot access '/mnt/sys_drive/felhom-data/backups/primary/romm/db-dumps/': No such file or directory
/mnt/felhom-drives/scratch_hdd/userdata/romm/backups/primary/romm/db-dumps
@@ -0,0 +1,35 @@
=== what the new version printed about its schema (kept hold log)
romm-db | 2026-09-23 08:13:58+02:00 [Note] [Entrypoint]: MariaDB upgrade not required
romm | INFO: [RomM][init][2026-09-23 08:15:25] Running database migrations
romm | INFO: [RomM][init][2026-09-23 08:15:41] Database migrations succeeded
=== step 1: the safety dump
/mnt/felhom-drives/scratch_hdd/userdata/romm/backups/primary/romm/db-dumps:
total 136
drwxr-sr-x 2 root 1000 4096 06:15:18 .
drwxr-sr-x 5 root 1000 4096 06:14:09 ..
-rw-r--r-- 1 root 1000 62943 06:15:18 pre-restore-20260923T061518Z-romm-mariadb.sql
-rw-r--r-- 1 root 1000 62748 06:13:13 romm-mariadb.sql
/mnt/felhom-drives/scratch_hdd/userdata/romm/backups/primary/romm/volume-dumps:
total 170856
drwxr-sr-x 2 root 1000 4096 06:13:57 .
drwxr-sr-x 5 root 1000 4096 06:14:09 ..
-rw-r--r-- 1 root 1000 2560 06:13:56 romm_romm_config.tar
-rw-r--r-- 1 root 1000 160428544 06:13:56 romm_romm_db_data.tar
-rw-r--r-- 1 root 1000 14506496 06:13:57 romm_romm_redis_data.tar
undo copy: /mnt/felhom-drives/scratch_hdd/userdata/romm/backups/primary/romm/db-dumps/pre-restore-20260923T061518Z-romm-mariadb.sql size=62943
holds: CREATE TABLE=24 DROP TABLE IF EXISTS=27 FOREIGN_KEY_CHECKS=0 set: 1 completion marker: 1
seed B in the undo copy: 1; in the tier copy: 0
step 1 0.04s
=== step 2: old definition + pin back (from the unit; the journal's pre-update copies: 0)
image: rommapp/romm:5.0.0
port: 8080
pinned_images:
romm: rommapp/romm:5.0.0
romm-db: mariadb:11.4
romm-redis: redis:7-alpine
step 2 0.04s
=== step 2b: lift the hold (operator CLI) + controller restart
[INFO] [settings] Loaded settings from /opt/docker/felhom-controller/data/settings.json
[INFO] [settings] restore hold CLEARED for romm
restarted
@@ -0,0 +1,16 @@
08:17:47 hold after lift: None
08:17:58 product start -> 200 {'ok': True, 'message': 'Stack romm start completed'}
08:19:01 romm rommapp/romm:5.0.0 Up 2 seconds (health: starting)
romm-db mariadb:11.4 Up About a minute (healthy)
romm-redis redis:7-alpine Up About a minute (healthy)
INFO: [RomM][init][2026-09-23 08:17:58] Running database migrations
FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
ERROR: [RomM][init][2026-09-23 08:18:07] Failed to run database migrations
INFO: [RomM][init][2026-09-23 08:18:07] Running database migrations
FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
ERROR: [RomM][init][2026-09-23 08:18:16] Failed to run database migrations
INFO: [RomM][init][2026-09-23 08:18:17] Running database migrations
FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
08:19:01 front door /api/heartbeat: 404
08:19:03 mariadb now (migrated): tables=39 alembic=0128_hltb_main_story_column users=2
@@ -0,0 +1,15 @@
app container stopped, DB up
before any load (migrated): tables=39 alembic=0128_hltb_main_story_column users=2
=== WRONG CASE: truncated copy (31471 of 62943 bytes), loaded as the product's ImportDump does (mariadb < file)
rc=1 in 0.94s
ERROR 1064 (42000) at line 754: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '`sa' at line 1
after the truncated load: tables=39 alembic=0095_virtual_collections_source users=2
=== RIGHT CASE: the whole copy, same loader
rc=0 in 1.25s
after the whole load: tables=39 alembic=0095_virtual_collections_source users=2
tables the NEW version created that remain (not in the copy):
memory_card_versions memory_cards music_favorite_tracks music_playlist_tracks music_playlists rom_file_doc_meta rom_file_user rom_identity_keys rom_similarity roms_facets roms_metadata sibling_roms streaming_container_adoptions virtual_collection_roms virtual_collections
views now: roms_metadata virtual_collections sibling_roms
views in the copy: 12 lines mention VIEW; CREATE ... VIEW statements: 3
base tables now: 36
@@ -0,0 +1,16 @@
08:20:00 CORRECTION to the listing above: roms_metadata, virtual_collections, sibling_roms are the copy's own VIEWS (not CREATE TABLE lines) — the real leftovers are 12 base tables (36 now vs 24 in the copy)
08:20:03 started
08:20:37 health (the OLD probe's port 8080 via the front door /api/heartbeat) = True after 36.5s
08:20:39 rommapp/romm:5.0.0 running restarts=0
INFO: [RomM][init][2026-09-23 08:19:14] Running database migrations
FAILED: Can't locate revision identified by '0128_hltb_main_story_column'
ERROR: [RomM][init][2026-09-23 08:19:22] Failed to run database migrations
INFO: [RomM][init][2026-09-23 08:20:03] Running database migrations
08:20:41 romm: login as the seeded user http=200 ok=True
08:20:41 romm B: GET /api/users http=200 seeded-user-listed=True (negative control listed=False)
08:20:41 READBACK after the undo: seed A=True seed B (only in the safety dump)=True
08:20:43 /mnt/felhom-drives/scratch_hdd/userdata/romm/userdata/roms: files=0 sum=e3b0c44298fc1c14
/mnt/felhom-drives/scratch_hdd/userdata/romm/appdata/romm/resources: files=0 sum=e3b0c44298fc1c14
@@ -0,0 +1,160 @@
#!/usr/bin/env python3
"""spike.py — Part 1 of the 2026-09-23 brief: the AUTOMATIC UNDO, performed BY HAND on guest 9202.
EVIDENCE, NOT PRODUCT. Every product act goes through the endpoints the UI invokes (deploy, backup,
sync, rescan, update, remove). The UNDO itself has no product path yet (that is what is being
spiked), so it is performed by hand with plain docker/compose inside the guest, using exactly the
steps the product would take, each one timed.
State between stages lives in state-<app>.json so each stage can be run, read, and only then
followed by the next (the hand undo needs a person looking at what the previous step left).
"""
import json, os, sys, time, re
sys.path.insert(0, ".")
import walk as w
import fixtures as fx
HERE = os.path.dirname(os.path.abspath(__file__))
FX = {"docmost": fx.Docmost(), "vikunja": fx.Vikunja(), "romm": fx.Romm()}
SUB = {"docmost": "docs", "vikunja": "tasks", "romm": "arcade"}
def st_path(app):
return os.path.join(HERE, f"state-{app}.json")
def load(app):
return json.load(open(st_path(app))) if os.path.exists(st_path(app)) else {}
def save(app, s):
json.dump(s, open(st_path(app), "w"), indent=2, ensure_ascii=False)
def ts():
return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
# ---- a SECOND seed, written AFTER the backup and BEFORE the update. It is the discriminator: only
# the pre-pin safety dump can hold it — the backup tier copy was taken before it existed. So if it
# reads back after the undo, the undo used the safety dump; if only A reads back, it used the tier.
def docmost_seed_b(sub, A):
jar = "/tmp/dm.jar"
w.app_curl(sub, "/api/auth/login", "-c", jar, "-H", "Content-Type: application/json",
data=json.dumps({"email": A["email"], "password": A["pw"]}), method="POST")
name = "drillB" + os.urandom(3).hex()
rc, code, out = w.app_curl(sub, "/api/spaces/create", "-b", jar, "-H", "Content-Type: application/json",
data=json.dumps({"name": name, "slug": name.lower()}), method="POST")
w.say(f" docmost seed B: /api/spaces/create http={code} {out[:160]}")
return {"space": name} if code in ("200", "201") else None
def docmost_verify_b(sub, A, B):
jar = "/tmp/dm.jar"
rc, code, out = w.app_curl(sub, "/api/auth/login", "-c", jar, "-H", "Content-Type: application/json",
data=json.dumps({"email": A["email"], "password": A["pw"]}), method="POST")
if code not in ("200", "201"):
w.say(f" docmost B: cannot log in (http={code})"); return False
rc, code, out = w.app_curl(sub, "/api/spaces", "-b", jar, "-H", "Content-Type: application/json",
data="{}", method="POST")
ok = code in ("200", "201") and B["space"] in out
neg = "drillBnever" in out
w.say(f" docmost B: /api/spaces http={code} seeded-space-listed={ok} (negative control listed={neg})")
return ok and not neg
def break_edge(app, frm, to, port_from, port_to):
"""The failing edge: a REAL migrating image move, plus — in the DRILL template only — the
health probe pointed at a port the app does not answer. Both in one drill commit."""
fy = f"{w.DRILL}/templates/{app}/.felhom.yml"
f = open(fy).read()
m = re.search(r"(healthcheck:\n(?:.*\n){0,8}?\s+port: )" + str(port_from) + r"\b", f)
assert m, "probe port not found"
f = f[:m.end() - len(str(port_from))] + str(port_to) + f[m.end():]
open(fy, "w").write(f)
h = w.drill_bump(app, frm, to)
return h
def pg_state(container, db, user):
return w.guest(f"docker exec {container} psql -U {user} -d {db} -Atc \"select count(*) from information_schema.tables where table_schema='public'\" 2>&1; "
f"docker exec {container} psql -U {user} -d {db} -Atc \"select name from kysely_migration order by name desc limit 3\" 2>&1; "
f"docker exec {container} psql -U {user} -d {db} -Atc \"select count(*) from kysely_migration\" 2>&1")
def romm_seed_b(sub, A):
"""A SECOND RomM user, created by the first (admin) one — written after the backup."""
jar, tok = FX["romm"]._csrf(w, sub)
user = "drillb" + os.urandom(3).hex()
rc, code, body = w.app_curl(sub, "/api/users", "-b", jar, "-H", f"x-csrftoken: {tok}",
"-u", f"{A['user']}:{A['pw']}", "-H", "Content-Type: application/json",
data=json.dumps({"username": user, "email": f"{user}@gate.invalid",
"password": "Drill-" + os.urandom(8).hex(), "role": "viewer"}),
method="POST")
w.say(f" romm seed B: POST /api/users (as the admin) http={code} {body[:120]}")
return {"user": user} if code in ("200", "201") else None
def romm_verify_b(sub, A, B):
jar, tok = FX["romm"]._csrf(w, sub)
rc, code, body = w.app_curl(sub, "/api/users", "-b", jar, "-H", f"x-csrftoken: {tok}",
"-u", f"{A['user']}:{A['pw']}")
ok = code == "200" and B["user"] in body
neg = "drillbnever" in body
w.say(f" romm B: GET /api/users http={code} seeded-user-listed={ok} (negative control listed={neg})")
return ok and not neg
def tree(paths):
cmd = "; ".join(f"echo \"{p}: files=$(find {p} -type f 2>/dev/null | wc -l) sum=$(find {p} -type f -exec sha256sum {{}} + 2>/dev/null | sort | sha256sum | cut -c1-16)\"" for p in paths)
return w.guest(cmd)
def my_state(container="romm-db", db="romm"):
# The root password is used INSIDE the container from its own env — it never leaves it.
q = lambda sql: f"docker exec {container} sh -c 'mariadb -uroot -p\"$MYSQL_ROOT_PASSWORD\" -N -e \"{sql}\" {db}' 2>&1 | tr '\\n' ' '"
return w.guest(f"""echo -n "tables=$({q("select count(*) from information_schema.tables where table_schema=database()")}) "
echo -n "alembic=$({q("select version_num from alembic_version")}) "
echo -n "users=$({q("select count(*) from users")})"
""")
def vik_seed_b(sub, A):
"""A second project, created AFTER the backup — plus a task with a real ATTACHMENT (a file the
app writes into its files volume), uploaded through the app's own attachment API."""
tok, why = FX["vikunja"]._token(w, sub, A)
title = "drillB-" + os.urandom(4).hex()
rc, code, body = w.app_curl(sub, "/api/v1/projects", "-H", f"Authorization: Bearer {tok}",
"-H", "Content-Type: application/json", data=json.dumps({"title": title}), method="PUT")
if code not in ("200", "201"):
w.say(f" vikunja B: project refused {code} {body[:120]}"); return None
pid = json.loads(body)["id"]
rc, code, body = w.app_curl(sub, f"/api/v1/projects/{pid}/tasks", "-H", f"Authorization: Bearer {tok}",
"-H", "Content-Type: application/json", data=json.dumps({"title": "task-" + title}), method="PUT")
tid = json.loads(body)["id"] if code in ("200", "201") else None
content = "drill attachment " + os.urandom(8).hex()
fn = "/tmp/vik-att.txt"; open(fn, "w").write(content)
rc, code2, body2 = w.app_curl(sub, f"/api/v1/tasks/{tid}/attachments", "-H", f"Authorization: Bearer {tok}",
"-F", f"files=@{fn}", method="PUT")
w.say(f" vikunja seed B: project http=200 task={tid} attachment upload http={code2} {body2[:120]}")
return {"title": title, "pid": pid, "tid": tid, "att": content}
def vik_verify_b(sub, A, B):
tok, why = FX["vikunja"]._token(w, sub, A)
if not tok:
w.say(f" vikunja B: cannot log in {why}"); return {"project": False, "attachment": False}
rc, code, body = w.app_curl(sub, f"/api/v1/projects/{B['pid']}", "-H", f"Authorization: Bearer {tok}")
proj = code == "200" and B["title"] in body
rc, code, body = w.app_curl(sub, f"/api/v1/tasks/{B['tid']}/attachments", "-H", f"Authorization: Bearer {tok}")
att_ok = False
try:
atts = json.loads(body)
if atts:
aid = atts[0]["id"]
rc, c3, b3 = w.app_curl(sub, f"/api/v1/tasks/{B['tid']}/attachments/{aid}", "-H", f"Authorization: Bearer {tok}")
att_ok = c3 == "200" and B["att"] in b3
except Exception as e:
w.say(f" vikunja B: attachments list unreadable http={code} {body[:120]}")
w.say(f" vikunja B: project readback={proj} attachment content readback={att_ok}")
return {"project": proj, "attachment": att_ok}
@@ -0,0 +1,12 @@
08:21:03 [1] deploy -> 202 {'ok': True, 'message': 'Telepítés elindítva – az állapot a kártyán követhető'}
08:21:08 [1] deployed, controller state=running, pinned={'vikunja': 'vikunja/vikunja:2.3.0'}
08:21:08 deployed: True
08:21:11 vikunja: register http=200
08:21:11 vikunja: create project http=201
08:21:11 vikunja: readback of the seeded project http=200 ok=True
08:21:11 C1 A: True
08:21:12 [4] „Mentés most" -> 200 {'ok': True, 'message': 'Mentés elindítva'}
08:22:12 [4] backup idle; last=None
08:22:17 vikunja seed B: project http=200 task=1 attachment upload http=200 {"errors":null,"success":[{"id":1,"task_id":1,"created_by":{"id":1,"name":"","username":"drill44f4ec","created":"2026-09
08:22:17 vikunja B: project readback=True attachment content readback=True
08:22:17 B reads back: {'project': True, 'attachment': True}
@@ -0,0 +1,21 @@
08:22:26 [5] drill commit 88613e2affbe: vikunja vikunja/vikunja:2.3.0 -> vikunja/vikunja:2.6.0 (push rc=0)
08:22:30 badge caught up after 4.5 s
08:22:30 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
08:22:30 + 0.0s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None
08:22:31 + 1.1s phase=pulling label=Új verzió letöltése… err=None hold=None
08:22:32 + 2.1s phase=verifying label=Működés ellenőrzése… err=None hold=None
08:24:04 + 93.3s phase=failed label=A frissítés nem sikerült err=A(z) vikunja frissítése 2026-09-23 08:24-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: saját meghajtó, 2026-09-23 08:22 — ez a másolat a beállításokat, az adatbázist és az adatköteteket tartalmazza. hold=A(z) vikunja frissítése 2026-09-23 08:24-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: saját meghajtó, 2026-09-23 08:22 — ez a másolat a beállításokat, az adatbázist és az adatköteteket tartalmazza.
08:24:04 {"final_phase": "failed", "hold_reason": "A(z) vikunja frissítése 2026-09-23 08:24-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: saját meghajtó, 2026-09-23 08:22 — ez a másolat a beállításokat, az adatbázist és az adatköteteket tartalmazza.", "state": "stopped", "duration_s": 93.3}
08:24:08 vikunja | time=2026-09-23T08:22:32.956+02:00 level=INFO msg="Running migrations…"
vikunja | time=2026-09-23T08:22:33.018+02:00 level=INFO msg="Ran all migrations successfully."
2026/09/23 06:22:30 update_guard.go:452: [INFO] [backup] update safety dump for vikunja: the app has no database — nothing to copy (no-op)
2026/09/23 06:22:30 update.go:655: [INFO] [stacks] update vikunja: safety dump done (0 file(s)) []
unit=/mnt/sys_drive/felhom-data/backups/primary/vikunja
ls: cannot access '/mnt/sys_drive/felhom-data/backups/primary/vikunja/db-dumps': No such file or directory
/mnt/sys_drive/felhom-data/backups/primary/vikunja/volume-dumps:
total 2244
drwxr-xr-x 2 root root 4096 06:22:11 .
drwxr-xr-x 4 root root 4096 06:22:12 ..
-rw-r--r-- 1 root root 1536 06:22:10 vikunja_vikunja_data.tar
-rw-r--r-- 1 root root 2285568 06:22:11 vikunja_vikunja_db.tar
@@ -0,0 +1,6 @@
image: vikunja/vikunja:2.3.0
pinned_images:
vikunja: vikunja/vikunja:2.3.0
step 2 0.02s
[INFO] [settings] restore hold CLEARED for vikunja
restarted
@@ -0,0 +1,10 @@
08:24:39 product start (old 2.3.0 on the 2.6.0-migrated SQLite, NOTHING loaded) -> 200
08:24:39 answers on its own port: True after 0.7s
08:24:41 vikunja/vikunja:2.3.0 running restarts=0
time=2026-09-23T08:24:39.591+02:00 level=INFO msg="Running migrations…"
time=2026-09-23T08:24:39.602+02:00 level=INFO msg="Ran all migrations successfully."
time=2026-09-23T08:24:39.608+02:00 level=INFO msg="Vikunja version v2.3.0"
08:24:42 vikunja: readback of the seeded project http=200 ok=True
08:24:42 vikunja B: project readback=True attachment content readback=True
08:24:42 READBACK: A=True B={'project': True, 'attachment': True}
@@ -0,0 +1,13 @@
drwxr-xr-x root/root 0 2026-09-23 06:21 ./
-rw-r--r-- root/root 2245432 2026-09-23 06:21 ./vikunja.db-wal
-rw-r--r-- root/root 32768 2026-09-23 06:21 ./vikunja.db-shm
-rw-r--r-- root/root 4096 2026-09-23 06:21 ./vikunja.db
-rw-r--r-- 1 root root 4096 Sep 23 06:21 vikunja.db
-rw-r--r-- 1 root root 32768 Sep 23 06:21 vikunja.db-shm
-rw-r--r-- 1 root root 2245432 Sep 23 06:21 vikunja.db-wal
volume put back from the tier copy + start: 0.86s
08:25:01 vikunja: readback of the seeded project http=200 ok=True
08:25:01 vikunja B: attachments list unreadable http=404 {"code":4002,"message":"This task does not exist"}
08:25:01 vikunja B: project readback=False attachment content readback=False
08:25:01 READBACK from the TIER copy (the only copy this app has): A=True B={'project': False, 'attachment': False} <- B was written after the backup
@@ -0,0 +1,493 @@
#!/usr/bin/env python3
"""walk.py — ONE app's full update walk on guest 9202, through the product's own endpoints.
EVIDENCE, NOT PRODUCT. It presses exactly the buttons a person presses:
POST /api/stacks/<n>/deploy · POST /api/backup/run · POST /api/sync · POST /api/stacks/rescan
POST /api/stacks/<n>/update · POST /api/stacks/<n>/remove
and reads GET /api/stacks/<n>. No controller code exists for it.
The walk, per `09` §6.4 and the update-night brief §4:
1 deploy from the DRILL catalog at the LIVE pin
2 seed through the app's OWN front door (R-156: never a volume, never SQL)
3 read the seed back <- control C1; a fixture that cannot prove itself proves nothing
4 „Mentés most"
5 commit the real one-step bump to the DRILL repo, sync, rescan, read the badge in BOTH languages
6 press the guarded Update, record every phase with timestamps
7 read the seed back through the front door
8 the four version observables side by side
9 write the verdict record in `09`'s JSON shape
`inconclusive` is a first-class verdict and is NEVER collapsed into `failed`.
"""
import argparse, json, os, re, subprocess, sys, time
from datetime import datetime, timezone
SC = "/tmp/claude-1000/-mnt-5-hdd-felhom-eu-git/6e5a1a3b-6d8c-4ee1-bc3f-c555eb3f7578/scratchpad"
EV = "/mnt/5_hdd/felhom.eu/git/felhom.eu/documentation/audits/update-rulings-2026-09-23"
DRILL = "/mnt/5_hdd/felhom.eu/drill/app-catalog-drill"
BASE = "https://192.168.0.114"
HOSTHDR = "Host: felhom.enkisfelhom.hu"
DOMAIN = "enkisfelhom.hu"
HP = "demo-hp"
LOG = []
def say(*a):
line = " ".join(str(x) for x in a)
ts = datetime.now().strftime("%H:%M:%S")
print(f"{ts} {line}", flush=True)
LOG.append(f"{ts} {line}")
def sh(args, timeout=300, inp=None):
try:
return subprocess.run(args, capture_output=True, text=True, timeout=timeout, input=inp)
except (subprocess.TimeoutExpired, OSError) as e:
return subprocess.CompletedProcess(args, 124, "", f"{e}")
def guest(script, timeout=600):
"""Run a bash script inside guest 9202. Piped as a file — never as an argument (quoting)."""
r = sh(["ssh", "-o", "ConnectTimeout=20", "-o", "StrictHostKeyChecking=accept-new", HP,
"cat > /tmp/w.sh; pct push 9202 /tmp/w.sh /tmp/w.sh >/dev/null 2>&1; "
"pct exec 9202 -- bash /tmp/w.sh; rm -f /tmp/w.sh"],
timeout=timeout, inp=script)
return r.stdout or ""
def login():
pw = open(f"{SC}/.ctlpw").read().strip()
sh(["curl", "-sk", "-D", f"{SC}/hdr.txt", "-o", "/dev/null", "-H", HOSTHDR,
"-X", "POST", "--data-urlencode", f"password={pw}", f"{BASE}/login"])
h = open(f"{SC}/hdr.txt").read()
m = re.search(r"felhom_session=[A-Za-z0-9._-]+", h, re.I)
if not m:
sys.exit("login failed: no session cookie")
open(f"{SC}/sess.txt", "w").write(m.group(0))
r = sh(["curl", "-sk", "-L", "-H", HOSTHDR, "-H", f"Cookie: {m.group(0)}", f"{BASE}/"])
c = re.search(r'<meta name="csrf-token" content="([^"]+)"', r.stdout or "")
if not c:
sys.exit("login failed: no csrf token")
open(f"{SC}/csrf.txt", "w").write(c.group(1))
def ctl(method, path, data=None, raw=False, tries=2):
"""One controller API call. Re-logs in once on a 302/401 — the controller's session store is
in memory, so any controller restart during the night invalidates it silently."""
for attempt in range(tries):
sess = open(f"{SC}/sess.txt").read().strip()
csrf = open(f"{SC}/csrf.txt").read().strip()
args = ["curl", "-sk", "-H", HOSTHDR, "-H", f"Cookie: {sess}", "-w", "\n%{http_code}"]
if method != "GET":
args += ["-H", f"X-CSRF-Token: {csrf}", "-H", "Content-Type: application/json",
"-X", method]
if data is not None:
args += ["--data", json.dumps(data)]
args.append(f"{BASE}{path}")
r = sh(args)
body, _, code = (r.stdout or "").rpartition("\n")
if code.strip() in ("302", "401") and attempt + 1 < tries:
login()
continue
if raw:
return code.strip(), body
try:
return code.strip(), json.loads(body)
except Exception:
return code.strip(), {"_raw": body[:600]}
return code.strip(), {"_raw": body[:600]}
def page(path):
sess = open(f"{SC}/sess.txt").read().strip()
r = sh(["curl", "-sk", "-H", HOSTHDR, "-H", f"Cookie: {sess}", f"{BASE}{path}"])
return r.stdout or ""
def app_curl(sub, path, *extra, method=None, data=None, timeout=45):
"""A call to the APP's own front door on 9202 — the household's route, not ours."""
args = ["curl", "-sSk", "--max-time", str(timeout), "-H", f"Host: {sub}.{DOMAIN}",
"-w", "\n%{http_code}"]
if method:
args += ["-X", method]
if data is not None:
args += ["--data-binary", "@-"]
args += list(extra) + [f"{BASE}{path}"]
r = sh(args, timeout=timeout + 30, inp=data)
body, _, code = (r.stdout or "").rpartition("\n")
return r.returncode, code.strip(), body
def stack(name):
_, d = ctl("GET", f"/api/stacks/{name}")
return (d.get("data") or {}) if isinstance(d, dict) else {}
def wait_app(sub, path="/", want=("200", "302", "303", "401", "403"), tries=60, delay=5):
"""Settling says the container runs; this says the APP answers. Not the same thing."""
last = None
for _ in range(tries):
rc, code, _ = app_curl(sub, path, timeout=15)
last = (rc, code)
if rc == 0 and code in want:
return True
time.sleep(delay)
say(f" app never answered on {sub}{path} (last rc={last[0]} code={last[1]})")
return False
# ------------------------------------------------------------------ the walk
DRIVE = "/mnt/felhom-drives/scratch_hdd/userdata"
# What THIS run generated for a deploy, per app. Deploy secrets are ENCRYPTED AT REST in
# `app.yaml` (`ENC:…`), which is right and which means a fixture cannot read an app's admin
# password back off the box — the household sees it once. So the value the harness itself
# generated is kept here for the life of the run, and nowhere else.
GENERATED = {}
def deploy_values(name, sub):
"""Fill EVERY required deploy field the way the wizard would, by asking the box what this app
asks for — `GET /api/stacks/<n>/deploy-fields` — instead of assuming DOMAIN+SUBDOMAIN.
Measured 2026-09-21: three apps in one batch refused at the deploy with a correct 400 because
a required field was absent — `HDD_PATH` (navidrome, audiobookshelf) and an admin password
(grafana). The refusals happen BEFORE anything is created (`deploy.go:324`), which is the only
reason this was safe to discover by running it (live-probes rule).
A `path` field must name a directory that ALREADY EXISTS (`deploy.go:330`), so one is made on
the scratch drive first — the same act the drive browser performs for a household.
"""
code, d = ctl("GET", f"/api/stacks/{name}/deploy-fields")
fields = (((d.get("data") or {}).get("metadata") or {}).get("deploy_fields")) or []
values = {"DOMAIN": DOMAIN, "SUBDOMAIN": sub}
made = []
for f in fields:
ev, ty = f.get("env_var"), f.get("type")
if ev in values:
continue
# `type: password` is MANDATORY whatever `required` says — `deploy.go:305-312` refuses
# when the caller sends none, deliberately ("the user needs to know their password"),
# while `.felhom.yml` declares `required: false` and the API serves that verbatim. A
# caller that trusts the contract gets a 400. Measured tonight on grafana; filed.
if not f.get("required") and ty != "password":
continue # the controller generates the optional secrets itself
if ty == "path":
p = f"{DRIVE}/{name}"
values[ev] = p
made.append(p)
elif ty in ("secret", "password"):
import secrets as _s
values[ev] = "Drill-" + _s.token_hex(12)
GENERATED.setdefault(name, {})[ev] = values[ev]
elif f.get("default"):
values[ev] = f["default"]
else:
values[ev] = f"drill-{name}"
if made:
guest("mkdir -p " + " ".join(made) + "; ls -ld " + " ".join(made))
say(f" [1] made the drive paths this app requires: {made}")
extra = [k for k in values if k not in ("DOMAIN", "SUBDOMAIN")]
if extra:
say(f" [1] required fields filled beyond DOMAIN/SUBDOMAIN: {extra}")
return values
def deploy(name, sub, extra_values=None):
st = stack(name)
if st.get("deployed"):
say(f" [1] {name} already deployed — reusing")
return True
values = deploy_values(name, sub)
if extra_values:
values.update(extra_values)
code, d = ctl("POST", f"/api/stacks/{name}/deploy", {"values": values})
say(f" [1] deploy -> {code} {str(d)[:120]}")
if code != "202":
return False
# WAIT FOR `deployed`, NOT FOR `running`. Measured 2026-09-21 on tandoor: docker reported the
# container `healthy` while the controller's own state read `unhealthy` — a gate on `running`
# alone therefore times out on an app that is up. The state is RECORDED rather than required;
# the real gate is the fixture's own `wait_app`, which asks whether the APP answers.
seen = None
for _ in range(90):
time.sleep(5)
st = stack(name)
seen = st.get("state")
# `deployed` alone is NOT enough and `state` alone is NOT right. Measured 2026-09-21:
# tandoor reads `unhealthy` while serving (R-618), so gating on "running" hangs; and romm
# read `deployed=True, state=degraded, pinned_images=None` twenty seconds in, i.e. the
# deploy had not finished writing app.yaml. The PIN is the deploy's own completion mark
# (`runComposeDeploy` writes it), so that is what to wait for.
pins = (st.get("app_config") or {}).get("pinned_images")
if st.get("deployed") and pins and seen in ("running", "unhealthy", "degraded"):
say(f" [1] deployed, controller state={seen}, "
f"pinned={(st.get('app_config') or {}).get('pinned_images')}")
if seen != "running":
say(f" [1] NOTE: the controller's own state is {seen!r}, not 'running' — recorded, "
f"not treated as a failure; the fixture's front-door wait is the real gate")
return True
say(f" [1] never became deployed (last controller state={seen!r})")
return False
def backup_now(name):
code, d = ctl("POST", "/api/backup/run")
say(f" [4] „Mentés most\" -> {code} {str(d)[:160]}")
for _ in range(90):
time.sleep(5)
c2, s = ctl("GET", "/api/backup/status")
dd = s.get("data") or {}
if not dd.get("running", False):
say(f" [4] backup idle; last={dd.get('last_run') or dd.get('last_db_dump')}")
return True
say(" [4] backup still running after 7.5 min — carrying on")
return False
def drill_bump(app, frm, to, service_hint=None):
"""Commit the edge to the DRILL repo. catalog_since set by hand (the drill repo has no gates).
`frm`/`to` may be comma-separated lists of the SAME length: an app whose own version lives in
two images (adventurelog's backend and frontend) moves both in one edge, while its engine
sidecar stays where it is — `09` §3b Q3's rule is per SERVICE, and an app-half edge must move
every service that carries the app's own version and no others.
"""
comp = f"{DRILL}/templates/{app}/docker-compose.yml"
fy = f"{DRILL}/templates/{app}/.felhom.yml"
s = open(comp).read()
froms = [x.strip() for x in frm.split(",") if x.strip()]
tos = [x.strip() for x in to.split(",") if x.strip()]
if len(froms) != len(tos):
say(f" [5] from/to lists differ in length: {froms} vs {tos}")
return None
for f1, t1 in zip(froms, tos):
if f"image: {f1}" not in s:
say(f" [5] FROM ref not found in compose: {f1}")
return None
s = s.replace(f"image: {f1}", f"image: {t1}")
open(comp, "w").write(s)
f = open(fy).read()
today = datetime.now().strftime("%Y-%m-%d")
f = re.sub(r'^catalog_since:.*$', f'catalog_since: "{today}"', f, count=1, flags=re.M)
open(fy, "w").write(f)
sh(["git", "-C", DRILL, "add", "-A"])
sh(["git", "-C", DRILL, "commit", "-q", "-m", f"DRILL {app}: {frm} -> {to}"])
r = sh(["git", "-C", DRILL, "push", "-q", "origin", "main"], timeout=120)
h = sh(["git", "-C", DRILL, "rev-parse", "--short=12", "HEAD"]).stdout.strip()
say(f" [5] drill commit {h}: {app} {frm} -> {to} (push rc={r.returncode})")
return h
def sync_rescan(expect_app=None, expect_ref=None, tries=12, delay=5):
"""Sync, rescan, and — when told what to expect — WAIT FOR THE BADGE TO CATCH UP.
R-607: `POST /api/sync` answers "nincs valtozas" while the catalog HAS moved, and
`catalog_images` stays stale until a separate rescan. Tonight showed the rescan alone is not
enough either: mealie's badge read "Naprakesz" seconds after its bump was pushed, and the
Update that followed moved nothing and still reported "Frissitve". So when the caller knows
which reference should appear, this polls for it and SAYS HOW LONG IT TOOK — which is the
NUMBER R-607 asks for and has never had.
"""
t0 = time.time()
ctl("POST", "/api/sync")
time.sleep(2)
ctl("POST", "/api/stacks/rescan")
time.sleep(2)
if not expect_app or not expect_ref:
return None
for i in range(tries):
cat = stack(expect_app).get("catalog_images") or {}
if expect_ref in cat.values():
waited = round(time.time() - t0, 1)
if i:
say(f" [sync] the badge needed {waited}s and {i+1} sync+rescan rounds to catch up "
f"to {expect_ref} — R-607's window, measured")
return waited
time.sleep(delay)
ctl("POST", "/api/sync")
time.sleep(1)
ctl("POST", "/api/stacks/rescan")
say(f" [sync] the badge NEVER caught up to {expect_ref} in {round(time.time()-t0,1)}s — "
f"catalog_images = {stack(expect_app).get('catalog_images')}")
return None
def badges(name):
out = {}
for lang, suffix in (("hu", ""), ("en", "?lang=en")):
h = page(f"/apps/{name}{suffix}")
m = re.findall(r'<span class="tag tag-[^"]*"[^>]*title="([^"]*)"[^>]*>([^<]*)<', h)
out[lang] = [{"title": a.strip(), "text": b.strip()} for a, b in m][:3]
return out
def press_update(name, poll=1.0, cap_s=1800):
code, d = ctl("POST", f"/api/stacks/{name}/update")
say(f" [6] Update -> {code} {str(d)[:220]}")
if code not in ("202", "200"):
return {"accepted": False, "http": code, "refusal": d, "phases": [], "duration_s": 0}
phases, seen, t0 = [], None, time.time()
while time.time() - t0 < cap_s:
st = stack(name)
ph = st.get("update_phase")
if ph != seen:
seen = ph
rec = {"t": round(time.time() - t0, 1), "phase": ph,
"label": st.get("update_phase_label"), "updating": st.get("updating"),
"error": st.get("update_error"), "hold": st.get("hold_reason")}
phases.append(rec)
say(f" +{rec['t']:>6.1f}s phase={ph} label={rec['label']} "
f"err={rec['error']} hold={rec['hold']}")
if not st.get("updating") and ph in ("done", "failed", None) and time.time() - t0 > 3:
break
time.sleep(poll)
st = stack(name)
return {"accepted": True, "http": code, "phases": phases,
"duration_s": round(time.time() - t0, 1),
"final_phase": st.get("update_phase"), "update_error": st.get("update_error"),
"hold_reason": st.get("hold_reason"), "state": st.get("state")}
def observables(name):
st = stack(name)
ac = st.get("app_config") or {}
live = guest(f"""
grep -E '^\\s+image:' /opt/docker/stacks/{name}/docker-compose.yml 2>/dev/null | sed 's/^ *//'
echo '---inspect---'
for c in $(docker ps -a --filter label=com.docker.compose.project={name} --format '{{{{.Names}}}}'); do
echo -n "$c "; docker inspect "$c" --format '{{{{.Config.Image}}}} running={{{{.State.Running}}}} restarts={{{{.RestartCount}}}}'
done
""")
a, _, b = live.partition("---inspect---")
return {
"pinned_images": ac.get("pinned_images"),
"installed_images": {k: (v.get("ref") if isinstance(v, dict) else v)
for k, v in (ac.get("installed_images") or {}).items()},
"catalog_images": st.get("catalog_images"),
"live_compose_image_lines": [x for x in a.strip().splitlines() if x.strip()],
"docker_inspect": [x for x in b.strip().splitlines() if x.strip()],
}
def app_logs(name, lines=400):
"""The app's own container log, DECODED. The endpoint answers a JSON envelope whose `logs` is
one string with escaped newlines — a scan over the envelope sees a single enormous line and
finds nothing, which reads exactly like "the app printed no migration line" and is not. R-96
rule 3 in a new place: an absent line is not evidence when the instrument cannot see lines."""
code, d = ctl("GET", f"/api/stacks/{name}/logs?lines={lines}")
if isinstance(d, dict):
data = d.get("data")
if isinstance(data, dict) and isinstance(data.get("logs"), str):
return data["logs"]
if isinstance(d.get("_raw"), str):
return d["_raw"]
return str(d)
def write_verdict(rec, appdir):
os.makedirs(appdir, exist_ok=True)
p = os.path.join(appdir, "verdict.json")
json.dump(rec, open(p, "w"), indent=2, ensure_ascii=False)
say(f" [9] verdict {rec['verdict']} -> {p}")
def remove(name):
"""Remove through the PRODUCT, never `docker rm` (live-probes rule). The remove endpoint
refuses a running stack — `409 still running` — so the stop is part of the act, not a tidy-up."""
c1, d1 = ctl("POST", f"/api/stacks/{name}/stop")
say(f" [X] stop -> {c1} {str(d1)[:100]}")
for _ in range(24):
time.sleep(5)
if stack(name).get("state") != "running":
break
code, d = ctl("POST", f"/api/stacks/{name}/remove",
{"remove_hdd_data": True, "remove_backups": True})
say(f" [X] remove (with drive data) -> {code} {str(d)[:160]}")
if code == "409":
# R-442's fail-closed guard: when the storage subsystem cannot RESOLVE the app's drive
# path, the removal is REFUSED and the app is kept rather than half-deleted. On guest 9202
# `/api/disks` answers `agent not configured`, so every app deployed with an HDD_PATH hits
# this. The household's other choice — remove the app, KEEP the data — is accepted, and the
# harness takes it, then tidies its own directory by name at teardown.
say(" [X] refused because the drive path cannot be resolved (R-442, fail-closed and right)"
" — removing the app and KEEPING the drive data instead")
code, d = ctl("POST", f"/api/stacks/{name}/remove",
{"remove_hdd_data": False, "remove_backups": True})
say(f" [X] remove (keeping drive data) -> {code} {str(d)[:160]}")
time.sleep(5)
st = stack(name)
left = guest(f"ls -d /opt/docker/stacks/{name} 2>/dev/null; "
f"docker ps -a --filter label=com.docker.compose.project={name} --format '{{{{.Names}}}}'")
say(f" [X] after remove: deployed={st.get('deployed')} leftovers={left.strip()!r}")
return code
def app_env(name, key):
"""Read one deploy value the CUSTOMER was given (e.g. the generated admin password) from the
app's own `app.yaml`. This is not seeding — it is how the household logs in; the controller
shows them the same value. Data still goes in through the app's own front door."""
out = guest(f"grep -E '^\\s*{key}:' /opt/docker/stacks/{name}/app.yaml 2>/dev/null | head -1")
if ":" in out:
return out.split(":", 1)[1].strip().strip('"').strip("'")
return ""
def snapshots(name):
"""The restorable copies the backups page offers for this app."""
code, d = ctl("GET", f"/api/backup/snapshots?stack={name}")
data = d.get("data") if isinstance(d, dict) else None
if isinstance(data, dict):
for k in ("snapshots", "items", "restore_points"):
if isinstance(data.get(k), list):
return data[k]
return data if isinstance(data, list) else []
def restore(name, snapshot_id=None, wait_s=1200):
"""The household's own way out: the „Visszaállítás a mentésből" button on the backups page.
A FORM post, not an API call — `POST /backup/restore` with `_csrf`, `stack_name`,
`snapshot_id` — because that is the button the sentence tells them to press.
"""
snaps = snapshots(name)
if snapshot_id is None:
if not snaps:
say(f" [R] no restorable copy offered for {name}")
return {"ok": False, "why": "no snapshot offered", "snapshots": snaps}
first = snaps[0]
snapshot_id = first.get("id") or first.get("snapshot_id") or first.get("short_id")
say(f" [R] restoring {name} from snapshot {snapshot_id!r} (of {len(snaps)} offered)")
sess = open(f"{SC}/sess.txt").read().strip()
csrf = open(f"{SC}/csrf.txt").read().strip()
r = sh(["curl", "-sk", "-D", "-", "-o", "/dev/null", "-H", HOSTHDR, "-H", f"Cookie: {sess}",
"-X", "POST",
"--data-urlencode", f"_csrf={csrf}",
"--data-urlencode", f"stack_name={name}",
"--data-urlencode", f"snapshot_id={snapshot_id}",
f"{BASE}/backup/restore"], timeout=180)
head = (r.stdout or "").split("\n")[0].strip()
loc = [l for l in (r.stdout or "").split("\n") if l.lower().startswith("location:")]
say(f" [R] POST /backup/restore -> {head} {loc[:1]}")
t0 = time.time()
last = None
while time.time() - t0 < wait_s:
code, d = ctl("GET", "/api/backup/restore-status")
dd = d.get("data") or {}
cur = (dd.get("running"), dd.get("phase") or dd.get("state"), dd.get("message"))
if cur != last:
say(f" +{round(time.time()-t0,1):>6.1f}s restore {cur}")
last = cur
if not dd.get("running", False) and time.time() - t0 > 5:
break
time.sleep(2)
st = stack(name)
say(f" [R] after restore: state={st.get('state')} hold={st.get('hold_reason')!r} "
f"phase={st.get('update_phase')}")
return {"ok": True, "snapshot_id": snapshot_id, "snapshots": snaps,
"http": head, "location": loc[:1], "seconds": round(time.time() - t0, 1),
"state_after": st.get("state"), "hold_after": st.get("hold_reason"),
"observables_after": observables(name)}
File diff suppressed because one or more lines are too long