07 §6.6 which version a restore brings back; version-travel evidence (A1, A5 red-proofs + live, A7, D1-D4); R-698 filed
gates / gates (push) Successful in 27s

This commit is contained in:
2026-09-27 11:29:30 +02:00
parent af6db38514
commit bff98a81a2
46 changed files with 4494 additions and 1 deletions
@@ -584,6 +584,64 @@ a folder its app owns with mode 0770 (nextcloud, `www-data`) — R-691.
Evidence: `audits/night-2026-09-26/E/` (E1 spike, E5 live proof).
### 6.6 Which version a restore brings back (controller v0.275.0, R-696, D4 option A)
**[DESIGN] The rule: a restore brings an app back at the version its DATA belongs to — never the data of
one version under the definition of another.** When the only copy holds data written by an older version,
the app comes back at that older version with its own data, and the normal guarded update then climbs the
ladder again, one tested step at a time (`09` §3 decision 14). The household's first sentence says so:
„A(z) %s visszaállt a(z) %s-i mentésből, a(z) %s verzióra. Elérhető frissítés: a doboz lépésenként hozza
naprakészre." / "%s is back from the backup of %s, at version %s. An update is available: the box brings it
up to date one step at a time." The version is every image as `name:tag` — a PostgreSQL step leaves the
app's own tag unchanged. D4 option B (restore into a temporary copy, update it there, move the data in) is
NOT built; it would be an add-on to this rule, not a replacement. *D4 is recorded in `STATUS.md`; until it is
ruled, A is in force.*
**[FACT] Why, measured before the fix (9202, 2026-09-26, `audits/version-travel-2026-09-26/A1/`).** The unit's
definition (`compose/`, `image_pins`) was re-captured by the five-minute status refresh as soon as an update
moved the pin, while its data (`db-dumps/`, `volume-dumps/`) is written only by the backup legs — so for up to
a day the unit paired the new definition with the old data. An app step (docmost 0.95.0 → 0.96.0) restored in
that window came back only because docmost migrated the old data forward at its first start — an update step
nobody guarded. An engine step (PostgreSQL 16 → 18) restored in that window poured the 16 datadir back,
`postgres:18` refused it, and **the app was left down**. The off-site restore never wrote a definition at all,
so after any update it mixed versions until the next night's off-site run.
**[DESIGN] How the data carries its version.** Every data file a backup leg writes (the database dump, each
volume tar) gets a stamp at the moment it is written — its size and mtime, the definition's image pins, and
what each service was running as `ref@digest` (`data-stamps.json` in the unit). The unit capture folds the
stamps into the manifest's `data` block (`at`, `image_pins`, `images`, per-file stamps) and **keeps the
definition its data belongs to**: when the pins moved since the data was written, `compose/` is not rewritten
until the next data run replaces the data. The manifest's `image_pins` stays the app's current pins, so it says
both. Files written under different pins (a failed leg) make the unit `mixed`.
**[DESIGN] What each restore does with it.**
| path | the unit's `data` block | what happens |
|---|---|---|
| own unit (Tier 1), second-drive mirror (Tier 2), kept-data Load | present, `compose/` names the data's pins | the data starts under that definition; if it differs from what ran, the restore pages' first sentence names the backup and the version (the kept-data Load has its own sentence and does not add this one) |
| same | present, `compose/` names OTHER pins, or `mixed` | **refused before anything is touched** (`ErrUnitVersionMismatch`): „…ezért a visszaállítás nem indult el. Az alkalmazás érintetlen" |
| off-site (Tier 3) | present, the snapshot's version differs from what runs | the snapshot unit's definition is written into the stack dir (and pinned) right after the stop, before any file, volume or database is touched; the database service is resolved from it |
| any | absent — a unit or snapshot written before v0.275.0, or with an unstamped file | restores **as before** (its captured definition; the off-site path the live one), with a WARN naming it |
**[DESIGN] The jump guard.** An installed version that matches no ladder entry's `from` jumps to the catalog's
current definition when a PERSON presses Update (`ladder.go`, measured live on vikunja 2.5.0, `09` §6.4 part 5);
the AUTOMATIC leg never presses it (`LegSkipOlderThanLadder`, and a template without a ladder is
`LegSkipNoTestRecord`). So a restore to a version older than the ladder — or of an app with no ladder — gets
the other first sentence: „…Ettől a verziótól nem vezet kipróbált frissítési lépés, ezért a doboz magától nem
frissíti." / "…No tested update step leads on from this version, so the box does not update it by itself." A
jump is not a tested step, and the page does not promise one.
**[DESIGN] The times tell the truth (A4).** Every tier's "proven at" is the time of its DATA, never of a
manifest: Tier 1 = `data.at` (else the newest data file, the `pre-restore-*` undo copies excluded, else — for a
unit with no data file — the manifest); Tier 2 = the mirror's data time, capped by its copy time; Tier 3 = the
snapshot time, capped by the data time the box recorded when it pushed it (`settings.offsite_data_at`). The
update's precondition and the release of a kept pre-conversion copy read these times; the release additionally
requires a database dump written after the conversion whose recorded engine is the NEW major.
**[FACT] The limit — the image is not in the backup (R-698).** A unit stores image NAMES and digests; the
image is re-pulled on restore. A version its maker has deleted cannot start. Measured 2026-09-26: the 42 ladder
digests all resolve today (`audits/version-travel-2026-09-26/A7/`). Options are in R-698; nothing is decided.
## 7. The recovery chain (D3) — the reason this document exists
**[DESIGN] 3-2-1 describes copies. It does not describe recovery.**
@@ -0,0 +1 @@
seed reads back through the front door: True
@@ -0,0 +1 @@
seed reads back through the front door: True
@@ -0,0 +1 @@
seed reads back through the front door: True
@@ -0,0 +1,6 @@
# 9202 before: gitea.dooplex.hu/admin/felhom-controller:0.274.0
gitea.dooplex.hu/admin/felhom-controller:0.275.0-rc1
# 9202 after: gitea.dooplex.hu/admin/felhom-controller:0.275.0-rc1 Up 6 seconds (healthy)
2026/09/26 08:36:35 main.go:337: [INFO] felhom-controller 0.275.0-rc1 starting (customer: demo-hp, domain: enkisfelhom.hu)
2026/09/26 08:36:35 info.go:13: [DEBUG] [system] GetInfo starting (hddPath="/mnt/felhom-drives/scratch_hdd", hasCPUCollector=true)
2026/09/26 08:36:35 info.go:13: [DEBUG] [system] GetInfo starting (hddPath="/mnt/felhom-drives/scratch_hdd", hasCPUCollector=true)
@@ -0,0 +1,25 @@
seed: True
seed reads back through the front door: True
# L1-deployed — 2026-09-27T11:25:24+0200; controller gitea.dooplex.hu/admin/felhom-controller:0.275.0-rc1
pinned={'docmost': 'docmost/docmost:0.95.0', 'docmost-postgres': 'postgres:16-alpine', 'docmost-redis': 'redis:7-alpine'}
installed={"docmost": {"ref": "docmost/docmost:0.95.0", "digest": "sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "at": "2026-09-27T09:24:59Z"}, "docmost-postgres": {"ref": "postgres:16-alpine", "digest": "sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "at": "2026-09-27T09:24:59Z"}, "docmost-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-27T09:24:59Z"}}
conversion_copy=None
state=unhealthy phase=None
== unit /mnt/sys_drive/felhom-data/backups/primary/docmost
(absent)
== unit /mnt/felhom-drives/scratch_hdd/backups/secondary/docmost/recovery-unit
(absent)
== live
compose image: docmost/docmost:0.95.0
compose image: postgres:16-alpine
compose image: redis:7-alpine
PGDATA=/var/lib/postgresql/data PG_VERSION=16
docmost docmost/docmost:0.95.0 Up 30 seconds (healthy)
docmost-redis redis:7-alpine Up 41 seconds (healthy)
docmost-postgres postgres:16-alpine Up 41 seconds (healthy)
volume docmost_docmost_postgres_data
volume docmost_docmost_redis_data
volume docmost_docmost_storage
pg volume root:
PG_VERSION base global pg_commit_ts pg_dynshmem pg_hba.conf pg_ident.conf pg_logical pg_multixact pg_notify pg_replslot pg_serial pg_snapshots pg_stat pg_stat_tmp pg_subtrans pg_tblspc pg_twophase pg_wal pg_xact postgresql.auto.conf postgresql.conf postmaster.opts postmaster.pid
restore points offered (GET /api/backup/snapshots): 200 []
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,76 @@
# L2-window-after-night-leg — 2026-09-27T11:19:42+0200; controller gitea.dooplex.hu/admin/felhom-controller:0.275.0-rc1
pinned={'docmost': 'docmost/docmost:0.96.0', 'docmost-postgres': 'postgres:18-alpine', 'docmost-redis': 'redis:7-alpine'}
installed={"docmost": {"ref": "docmost/docmost:0.96.0", "digest": "sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "at": "2026-09-26T07:43:15Z"}, "docmost-postgres": {"ref": "postgres:18-alpine", "digest": "sha256:77f585114c32fbca283dc835b0596f4e52b51b4c6662d7810b2f4084f60a1873", "at": "2026-09-27T02:15:43Z"}, "docmost-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-26T07:43:15Z"}}
conversion_copy={'volume': 'docmost_docmost_postgres_data', 'copy': 'docmost_docmost_postgres_data.pre-update-20260927T021504Z', 'at': '2026-09-27T02:15:43Z', 'from': 16, 'to': 18, 'service': 'docmost-postgres'}
state=running phase=done
== unit /mnt/sys_drive/felhom-data/backups/primary/docmost
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T02:16:35Z"
manifest.image_pins = ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:18-alpine@sha256:77f585114c32fbca283dc835b0596f4e52b51b4c6662d7810b2f4084f60a1873", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T00:30:00Z", "image_pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T00:30:00.433453822Z", "size": 154240, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T00:30:02.890484137Z", "size": 71068672, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T00:30:03.468491268Z", "size": 24741376, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T00:30:02.424674164Z", "size": 1536, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
image: postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T00:30:36.8389029990Z 3998 compose/.felhom.yml
2026-09-27T00:30:36.8389029990Z 447 compose/app.yaml
2026-09-27T00:30:36.8389029990Z 3321 compose/docker-compose.yml
2026-09-27T00:30:03.6854939460Z 3227 data-stamps.json
2026-09-27T00:30:00.4334538220Z 154240 db-dumps/docmost-postgres.sql
2026-09-27T02:16:35.9903943670Z 5733 manifest.json
2026-09-27T00:30:02.8904841370Z 71068672 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T00:30:03.4684912680Z 24741376 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T00:30:02.4246741640Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260926T072557Z-docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260926T073000Z-docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260927T021500Z-docmost-postgres.sql: Dumped from database version 16.15
== unit /mnt/felhom-drives/scratch_hdd/backups/secondary/docmost/recovery-unit
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T00:30:36Z"
manifest.image_pins = ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T00:30:00Z", "image_pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T00:30:00.433453822Z", "size": 154240, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T00:30:02.890484137Z", "size": 71068672, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T00:30:03.468491268Z", "size": 24741376, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T00:30:02.424674164Z", "size": 1536, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
image: postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T00:30:36.8389029990Z 3998 compose/.felhom.yml
2026-09-27T00:30:36.8389029990Z 447 compose/app.yaml
2026-09-27T00:30:36.8389029990Z 3321 compose/docker-compose.yml
2026-09-27T00:30:03.6854939460Z 3227 data-stamps.json
2026-09-27T00:30:00.4334538220Z 154240 db-dumps/docmost-postgres.sql
2026-09-27T00:30:36.8389029990Z 5733 manifest.json
2026-09-27T00:30:02.8904841370Z 71068672 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T00:30:03.4684912680Z 24741376 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T00:30:02.4246741640Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260926T072557Z-docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260926T073000Z-docmost-postgres.sql: Dumped from database version 16.15
== live
compose image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
compose image: postgres:18-alpine@sha256:77f585114c32fbca283dc835b0596f4e52b51b4c6662d7810b2f4084f60a1873
compose image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
PGDATA=/var/lib/postgresql/18/docker PG_VERSION=18
docmost docmost/docmost:0.96.0 Up 7 hours (healthy)
docmost-postgres postgres:18-alpine Up 7 hours (healthy)
docmost-redis redis:7-alpine Up 7 hours (healthy)
volume docmost_docmost_postgres_data
volume docmost_docmost_postgres_data.pre-update-20260926T073003Z
volume docmost_docmost_postgres_data.pre-update-20260927T021504Z
volume docmost_docmost_redis_data
volume docmost_docmost_storage
pg volume root:
18
restore points offered (GET /api/backup/snapshots): 200 [{"time": "2026-09-27T00:30:00Z", "short_id": "helyi", "tier": 1, "drive_label": "Bels\u0151 SSD (rendszer)"}]
@@ -0,0 +1,133 @@
# L3-restore-own-unit-in-window — restore pressed at 2026-09-27T09:20:05Z (own unit, snapshot helyi)
{"ok": true, "snapshot_id": "helyi", "snapshots": [{"time": "2026-09-27T00:30:00Z", "short_id": "helyi", "tier": 1, "drive_label": "Bels\u0151 SSD (rendszer)"}], "http": "HTTP/2 302", "location": ["location: /backups/restore?flash=flash.restore.started"], "seconds": 30.4, "state_after": "running", "hold_after": null}
controller lines:
2026/09/27 09:20:06 handlers.go:1717: [WARN] [web] Restore requested (async): stack=docmost, snapshot=helyi from 172.18.0.6:41330
2026/09/27 09:20:06 restore_unit.go:381: [INFO] [backup] Restore docmost: the data belongs to [docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499] (written 2026-09-27T00:30:00Z); the app ran [docmos
2026/09/27 09:20:06 restore_unit.go:393: [INFO] [backup] Restoring docmost from recovery unit /mnt/sys_drive/felhom-data/backups/primary/docmost: images=3, secrets recovered=2/2, data_keys=0
2026/09/27 09:20:06 manager.go:1305: [INFO] [stacks] Stopping stack: docmost
2026/09/27 09:20:07 manager.go:1314: [INFO] [stacks] Stack docmost stopped successfully (took 0.9s)
2026/09/27 09:20:07 restore.go:152: [INFO] [backup] Restoring Docker volume docmost_docmost_postgres_data for docmost
2026/09/27 09:20:08 restore.go:152: [INFO] [backup] Restoring Docker volume docmost_docmost_redis_data for docmost
2026/09/27 09:20:09 restore.go:152: [INFO] [backup] Restoring Docker volume docmost_docmost_storage for docmost
2026/09/27 09:20:09 restore.go:195: [INFO] [backup] Restored 3 Docker volume(s) for docmost
2026/09/27 09:20:09 [INFO] [stacks] SaveAppConfig: saved config for docmost
2026/09/27 09:20:09 deploy.go:720: [INFO] [stacks] Redeploying docmost from recovery unit with 4 env vars
2026/09/27 09:20:09 pin.go:93: [INFO] [stacks] pin docmost: docmost=docmost/docmost:0.96.0, docmost-postgres=postgres:16-alpine, docmost-redis=redis:7-alpine
2026/09/27 09:20:09 [INFO] [stacks] SaveAppConfig: saved config for docmost
2026/09/27 09:20:09 manager.go:1269: [INFO] [stacks] Starting stack docmost services only: [docmost-postgres]
2026/09/27 09:20:10 manager.go:1280: [INFO] [stacks] Stack docmost services [docmost-postgres] started (took 0.4s)
2026/09/27 09:20:10 restore_db.go:87: [INFO] [backup] Restore docmost: replaying DB dump into docmost-postgres (postgres)
2026/09/27 09:20:12 dbdump.go:801: [INFO] [backup] Imported DB dump docmost-postgres.sql into docmost-postgres (postgres)
2026/09/27 09:20:12 restore_db.go:97: [INFO] [backup] Restore docmost: replayed 1 DB dump(s)
2026/09/27 09:20:12 manager.go:1216: [INFO] [stacks] Starting stack: docmost
2026/09/27 09:20:23 manager.go:1231: [INFO] [stacks] Stack docmost started successfully (took 11.1s)
2026/09/27 09:20:23 [INFO] [stacks] SaveAppConfig: saved config for docmost
2026/09/27 09:20:23 installed.go:420: [INFO] [stacks] installed-images docmost: recorded 3 service(s) (docmost=docmost/docmost:0.96.0 (sha256:b56947fcfd08…), docmost-postgres=postgres:16-alpine (sha256:721873c34ceb…), docmost-redis=redis:7-alpine (sha256:858f009f9709…))
2026/09/27 09:20:26 manager.go:1562: [INFO] [stacks] Stack docmost post-start status:
2026/09/27 09:20:26 manager.go:1565: [INFO] [stacks] docmost docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a running Up 3 seconds (health: starting)
2026/09/27 09:20:26 manager.go:1565: [INFO] [stacks] docmost-postgres postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea running Up 16 seconds (healthy)
2026/09/27 09:20:26 manager.go:1565: [INFO] [stacks] docmost-redis redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499 running Up 14 seconds (healthy)
2026/09/27 09:20:36 restore_unit.go:478: [INFO] [backup] Restore-from-unit completed: docmost — 3 volume(s) of 3 listed, 1 database(s) of 1 listed
2026/09/27 09:20:36 handlers.go:1729: [INFO] [web] Restore completed (async): stack=docmost in 30.044089279s (volumes 3/3, dbs 1/1)
docmost-postgres log (tail):
PostgreSQL Database directory appears to contain a database; Skipping initialization
2026-09-27 11:20:10.365 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
2026-09-27 11:20:10.366 CEST [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2026-09-27 11:20:10.366 CEST [1] LOG: listening on IPv6 address "::", port 5432
2026-09-27 11:20:10.375 CEST [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2026-09-27 11:20:10.385 CEST [29] LOG: database system was shut down at 2026-09-27 02:30:01 CEST
2026-09-27 11:20:10.396 CEST [1] LOG: database system is ready to accept connections
docmost log (tail):
$ pnpm --filter ./apps/server run start:prod
$ cross-env NODE_ENV=production node dist/main
(node:45) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
{"level":"info","time":"2026-09-27T09:20:31.729Z","pid":45,"hostname":"4c4bc3c70f5c","context":"RedisModule","msg":"default: the connection was successfully established"}
{"level":"info","time":"2026-09-27T09:20:31.969Z","pid":45,"hostname":"4c4bc3c70f5c","context":"DatabaseModule","msg":"Establishing database connection"}
{"level":"info","time":"2026-09-27T09:20:32.001Z","pid":45,"hostname":"4c4bc3c70f5c","context":"DatabaseModule","msg":"Database connection successful"}
{"level":"info","time":"2026-09-27T09:20:32.178Z","pid":45,"hostname":"4c4bc3c70f5c","context":"DatabaseMigrationService","msg":"No pending database migrations"}
{"level":"info","time":"2026-09-27T09:20:32.212Z","pid":45,"hostname":"4c4bc3c70f5c","context":"NestApplication","msg":"Nest application successfully started"}
{"level":"info","time":"2026-09-27T09:20:32.224Z","pid":45,"hostname":"4c4bc3c70f5c","context":"NestApplication","msg":"Listening on http://127.0.0.1:3000 / https://c-docs.enkisfelhom.hu"}
seed reads back through the front door: True
# L3-restore-own-unit-in-window — 2026-09-27T11:21:01+0200; controller gitea.dooplex.hu/admin/felhom-controller:0.275.0-rc1
pinned={'docmost': 'docmost/docmost:0.96.0', 'docmost-postgres': 'postgres:16-alpine', 'docmost-redis': 'redis:7-alpine'}
installed={"docmost": {"ref": "docmost/docmost:0.96.0", "digest": "sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "at": "2026-09-27T09:20:23Z"}, "docmost-postgres": {"ref": "postgres:16-alpine", "digest": "sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "at": "2026-09-27T09:20:23Z"}, "docmost-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-27T09:20:23Z"}}
conversion_copy=None
state=running phase=done
== unit /mnt/sys_drive/felhom-data/backups/primary/docmost
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T02:16:35Z"
manifest.image_pins = ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:18-alpine@sha256:77f585114c32fbca283dc835b0596f4e52b51b4c6662d7810b2f4084f60a1873", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T00:30:00Z", "image_pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T00:30:00.433453822Z", "size": 154240, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T00:30:02.890484137Z", "size": 71068672, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T00:30:03.468491268Z", "size": 24741376, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T00:30:02.424674164Z", "size": 1536, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
image: postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T00:30:36.8389029990Z 3998 compose/.felhom.yml
2026-09-27T00:30:36.8389029990Z 447 compose/app.yaml
2026-09-27T00:30:36.8389029990Z 3321 compose/docker-compose.yml
2026-09-27T00:30:03.6854939460Z 3227 data-stamps.json
2026-09-27T00:30:00.4334538220Z 154240 db-dumps/docmost-postgres.sql
2026-09-27T02:16:35.9903943670Z 5733 manifest.json
2026-09-27T00:30:02.8904841370Z 71068672 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T00:30:03.4684912680Z 24741376 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T00:30:02.4246741640Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260926T072557Z-docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260926T073000Z-docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260927T021500Z-docmost-postgres.sql: Dumped from database version 16.15
== unit /mnt/felhom-drives/scratch_hdd/backups/secondary/docmost/recovery-unit
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T00:30:36Z"
manifest.image_pins = ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T00:30:00Z", "image_pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T00:30:00.433453822Z", "size": 154240, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T00:30:02.890484137Z", "size": 71068672, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T00:30:03.468491268Z", "size": 24741376, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T00:30:02.424674164Z", "size": 1536, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
image: postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T00:30:36.8389029990Z 3998 compose/.felhom.yml
2026-09-27T00:30:36.8389029990Z 447 compose/app.yaml
2026-09-27T00:30:36.8389029990Z 3321 compose/docker-compose.yml
2026-09-27T00:30:03.6854939460Z 3227 data-stamps.json
2026-09-27T00:30:00.4334538220Z 154240 db-dumps/docmost-postgres.sql
2026-09-27T00:30:36.8389029990Z 5733 manifest.json
2026-09-27T00:30:02.8904841370Z 71068672 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T00:30:03.4684912680Z 24741376 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T00:30:02.4246741640Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260926T072557Z-docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260926T073000Z-docmost-postgres.sql: Dumped from database version 16.15
== live
compose image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
compose image: postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
compose image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
PGDATA=/var/lib/postgresql/data PG_VERSION=16
docmost docmost/docmost:0.96.0 Up 42 seconds (healthy)
docmost-redis redis:7-alpine Up 53 seconds (healthy)
docmost-postgres postgres:16-alpine Up 56 seconds (healthy)
volume docmost_docmost_postgres_data
volume docmost_docmost_postgres_data.pre-update-20260926T073003Z
volume docmost_docmost_postgres_data.pre-update-20260927T021504Z
volume docmost_docmost_redis_data
volume docmost_docmost_storage
pg volume root:
PG_VERSION base global pg_commit_ts pg_dynshmem pg_hba.conf pg_ident.conf pg_logical pg_multixact pg_notify pg_replslot pg_serial pg_snapshots pg_stat pg_stat_tmp pg_subtrans pg_tblspc pg_twophase pg_wal pg_xact postgresql.auto.conf postgresql.conf postmaster.opts postmaster.pid
restore points offered (GET /api/backup/snapshots): 200 [{"time": "2026-09-27T00:30:00Z", "short_id": "helyi", "tier": 1, "drive_label": "Bels\u0151 SSD (rendszer)"}]
restore-status (the page's sentence): {"running": false, "op": "restore", "stack": "docmost", "started_at": "2026-09-27T09:20:06.81423827Z", "last": {"op": "restore", "stack": "docmost", "ok": true, "message": "A(z) docmost visszaállt a(z) 2026-09-27 02:30-i mentésből, a(z) docmost:0.96.0, postgres:16-alpine, redis:7-alpine verzióra. Elérhető frissítés: a doboz lépésenként hozza naprakészre. A(z) docmost: 3 adatkötet és az adatbázis visszaállítva — az alkalmazás újraindult.", "finished_at": "2026-09-27T09:20:36.859423487Z"}, "last_recent": true}
@@ -0,0 +1,67 @@
{
"accepted": true,
"http": "202",
"phases": [
{
"t": 0.0,
"phase": "backing-up",
"label": "Biztons\u00e1gi ment\u00e9s k\u00e9sz\u00fcl a friss\u00edt\u00e9s el\u0151tt\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 16.4,
"phase": "safety-dump",
"label": "Adatb\u00e1zis pillanatk\u00e9p\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 18.5,
"phase": "copying",
"label": "Az adatok m\u00e1sol\u00e1sa a friss\u00edt\u00e9s el\u0151tt\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 21.6,
"phase": "converting",
"label": "Adatb\u00e1zis \u00e1talak\u00edt\u00e1sa",
"updating": true,
"error": null,
"hold": null
},
{
"t": 28.7,
"phase": "starting",
"label": "Ind\u00edt\u00e1s az \u00faj verzi\u00f3val\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 40.0,
"phase": "verifying",
"label": "M\u0171k\u00f6d\u00e9s ellen\u0151rz\u00e9se\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 55.4,
"phase": "done",
"label": "Friss\u00edtve",
"updating": false,
"error": null,
"hold": null
}
],
"duration_s": 55.4,
"final_phase": "done",
"update_error": null,
"hold_reason": null,
"state": "running"
}
@@ -0,0 +1,79 @@
# L4-climb-again — 2026-09-27T11:22:14+0200; controller gitea.dooplex.hu/admin/felhom-controller:0.275.0-rc1
pinned={'docmost': 'docmost/docmost:0.96.0', 'docmost-postgres': 'postgres:18-alpine', 'docmost-redis': 'redis:7-alpine'}
installed={"docmost": {"ref": "docmost/docmost:0.96.0", "digest": "sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "at": "2026-09-27T09:20:23Z"}, "docmost-postgres": {"ref": "postgres:18-alpine", "digest": "sha256:77f585114c32fbca283dc835b0596f4e52b51b4c6662d7810b2f4084f60a1873", "at": "2026-09-27T09:22:14Z"}, "docmost-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-27T09:20:23Z"}}
conversion_copy={'volume': 'docmost_docmost_postgres_data', 'copy': 'docmost_docmost_postgres_data.pre-update-20260927T092138Z', 'at': '2026-09-27T09:22:14Z', 'from': 16, 'to': 18, 'service': 'docmost-postgres'}
state=running phase=done
== unit /mnt/sys_drive/felhom-data/backups/primary/docmost
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T09:21:34Z"
manifest.image_pins = ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T09:21:19Z", "image_pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T09:21:19.657112845Z", "size": 154467, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T09:21:21.833139563Z", "size": 71175680, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T09:21:22.567148574Z", "size": 24775168, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T09:21:21.364407551Z", "size": 1536, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
image: postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T09:21:34.3042926810Z 3998 compose/.felhom.yml
2026-09-27T09:21:34.3042926810Z 447 compose/app.yaml
2026-09-27T09:21:34.3032926690Z 3321 compose/docker-compose.yml
2026-09-27T09:21:22.8181516560Z 3227 data-stamps.json
2026-09-27T09:21:19.6571128450Z 154467 db-dumps/docmost-postgres.sql
2026-09-27T09:21:34.3053578700Z 5733 manifest.json
2026-09-27T09:21:21.8331395630Z 71175680 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T09:21:22.5671485740Z 24775168 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T09:21:21.3644075510Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260926T072557Z-docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260926T073000Z-docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260927T021500Z-docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260927T092134Z-docmost-postgres.sql: Dumped from database version 16.15
== unit /mnt/felhom-drives/scratch_hdd/backups/secondary/docmost/recovery-unit
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T09:21:34Z"
manifest.image_pins = ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T09:21:19Z", "image_pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T09:21:19.657112845Z", "size": 154467, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T09:21:21.833139563Z", "size": 71175680, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T09:21:22.567148574Z", "size": 24775168, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T09:21:21.364407551Z", "size": 1536, "pins": ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"], "images": {"docmost": "docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
image: postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T09:21:34.3042926810Z 3998 compose/.felhom.yml
2026-09-27T09:21:34.3042926810Z 447 compose/app.yaml
2026-09-27T09:21:34.3032926690Z 3321 compose/docker-compose.yml
2026-09-27T09:21:22.8181516560Z 3227 data-stamps.json
2026-09-27T09:21:19.6571128450Z 154467 db-dumps/docmost-postgres.sql
2026-09-27T09:21:34.3053578700Z 5733 manifest.json
2026-09-27T09:21:21.8331395630Z 71175680 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T09:21:22.5671485740Z 24775168 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T09:21:21.3644075510Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260926T072557Z-docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260926T073000Z-docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260927T021500Z-docmost-postgres.sql: Dumped from database version 16.15
== live
compose image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
compose image: postgres:18-alpine@sha256:77f585114c32fbca283dc835b0596f4e52b51b4c6662d7810b2f4084f60a1873
compose image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
PGDATA=/var/lib/postgresql/18/docker PG_VERSION=18
docmost docmost/docmost:0.96.0 Up 21 seconds (healthy)
docmost-postgres postgres:18-alpine Up 37 seconds (healthy)
docmost-redis redis:7-alpine Up 32 seconds (healthy)
volume docmost_docmost_postgres_data
volume docmost_docmost_postgres_data.pre-update-20260926T073003Z
volume docmost_docmost_postgres_data.pre-update-20260927T021504Z
volume docmost_docmost_postgres_data.pre-update-20260927T092138Z
volume docmost_docmost_redis_data
volume docmost_docmost_storage
pg volume root:
18
restore points offered (GET /api/backup/snapshots): 200 [{"time": "2026-09-27T09:21:19Z", "short_id": "helyi", "tier": 1, "drive_label": "Bels\u0151 SSD (rendszer)"}]
@@ -0,0 +1,8 @@
docmost_docmost_postgres_data
docmost_docmost_postgres_data.pre-update-20260926T073003Z
docmost_docmost_postgres_data.pre-update-20260927T021504Z
docmost_docmost_postgres_data.pre-update-20260927T092138Z
docmost_docmost_redis_data
docmost_docmost_storage
docker-compose.yml
hold-logs
@@ -0,0 +1,67 @@
{
"accepted": true,
"http": "202",
"phases": [
{
"t": 0.0,
"phase": "backing-up",
"label": "Biztons\u00e1gi ment\u00e9s k\u00e9sz\u00fcl a friss\u00edt\u00e9s el\u0151tt\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 14.4,
"phase": "safety-dump",
"label": "Adatb\u00e1zis pillanatk\u00e9p\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 16.4,
"phase": "pulling",
"label": "\u00daj verzi\u00f3 let\u00f6lt\u00e9se\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 17.4,
"phase": "copying",
"label": "Az adatok m\u00e1sol\u00e1sa a friss\u00edt\u00e9s el\u0151tt\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 19.5,
"phase": "starting",
"label": "Ind\u00edt\u00e1s az \u00faj verzi\u00f3val\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 30.8,
"phase": "verifying",
"label": "M\u0171k\u00f6d\u00e9s ellen\u0151rz\u00e9se\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 46.2,
"phase": "done",
"label": "Friss\u00edtve",
"updating": false,
"error": null,
"hold": null
}
],
"duration_s": 46.2,
"final_phase": "done",
"update_error": null,
"hold_reason": null,
"state": "running"
}
@@ -0,0 +1,70 @@
# L5-step-app — 2026-09-27T11:26:28+0200; controller gitea.dooplex.hu/admin/felhom-controller:0.275.0-rc1
pinned={'docmost': 'docmost/docmost:0.96.0', 'docmost-postgres': 'postgres:16-alpine', 'docmost-redis': 'redis:7-alpine'}
installed={"docmost": {"ref": "docmost/docmost:0.96.0", "digest": "sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "at": "2026-09-27T09:26:27Z"}, "docmost-postgres": {"ref": "postgres:16-alpine", "digest": "sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "at": "2026-09-27T09:24:59Z"}, "docmost-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-27T09:24:59Z"}}
conversion_copy=None
state=running phase=done
== unit /mnt/sys_drive/felhom-data/backups/primary/docmost
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T09:25:56Z"
manifest.image_pins = ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T09:25:42Z", "image_pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T09:25:42.669342118Z", "size": 134715, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T09:25:43.909357343Z", "size": 51837440, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T09:25:44.538433114Z", "size": 25600, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T09:25:44.927369842Z", "size": 1536, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.95.0
image: postgres:16-alpine
image: redis:7-alpine
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T09:25:56.5155121220Z 6426 compose/.felhom.yml
2026-09-27T09:25:56.5155121220Z 447 compose/app.yaml
2026-09-27T09:25:56.5145121100Z 3105 compose/docker-compose.yml
2026-09-27T09:25:45.0653715360Z 2360 data-stamps.json
2026-09-27T09:25:42.6693421180Z 134715 db-dumps/docmost-postgres.sql
2026-09-27T09:25:56.5162918310Z 4434 manifest.json
2026-09-27T09:25:43.9093573430Z 51837440 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T09:25:44.5384331140Z 25600 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T09:25:44.9273698420Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260927T092556Z-docmost-postgres.sql: Dumped from database version 16.15
== unit /mnt/felhom-drives/scratch_hdd/backups/secondary/docmost/recovery-unit
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T09:25:56Z"
manifest.image_pins = ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T09:25:42Z", "image_pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T09:25:42.669342118Z", "size": 134715, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T09:25:43.909357343Z", "size": 51837440, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T09:25:44.538433114Z", "size": 25600, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T09:25:44.927369842Z", "size": 1536, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.95.0
image: postgres:16-alpine
image: redis:7-alpine
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T09:25:56.5155121220Z 6426 compose/.felhom.yml
2026-09-27T09:25:56.5155121220Z 447 compose/app.yaml
2026-09-27T09:25:56.5145121100Z 3105 compose/docker-compose.yml
2026-09-27T09:25:45.0653715360Z 2360 data-stamps.json
2026-09-27T09:25:42.6693421180Z 134715 db-dumps/docmost-postgres.sql
2026-09-27T09:25:56.5162918310Z 4434 manifest.json
2026-09-27T09:25:43.9093573430Z 51837440 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T09:25:44.5384331140Z 25600 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T09:25:44.9273698420Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
== live
compose image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
compose image: postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
compose image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
PGDATA=/var/lib/postgresql/data PG_VERSION=16
docmost docmost/docmost:0.96.0 Up 21 seconds (healthy)
docmost-postgres postgres:16-alpine Up 32 seconds (healthy)
docmost-redis redis:7-alpine Up 32 seconds (healthy)
volume docmost_docmost_postgres_data
volume docmost_docmost_redis_data
volume docmost_docmost_storage
pg volume root:
PG_VERSION base global pg_commit_ts pg_dynshmem pg_hba.conf pg_ident.conf pg_logical pg_multixact pg_notify pg_replslot pg_serial pg_snapshots pg_stat pg_stat_tmp pg_subtrans pg_tblspc pg_twophase pg_wal pg_xact postgresql.auto.conf postgresql.conf postmaster.opts postmaster.pid
restore points offered (GET /api/backup/snapshots): 200 [{"time": "2026-09-27T09:25:42Z", "short_id": "helyi", "tier": 1, "drive_label": "Bels\u0151 SSD (rendszer)"}]
@@ -0,0 +1,70 @@
# L6-after-refresh-app-step — 2026-09-27T11:26:38+0200; controller gitea.dooplex.hu/admin/felhom-controller:0.275.0-rc1
pinned={'docmost': 'docmost/docmost:0.96.0', 'docmost-postgres': 'postgres:16-alpine', 'docmost-redis': 'redis:7-alpine'}
installed={"docmost": {"ref": "docmost/docmost:0.96.0", "digest": "sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "at": "2026-09-27T09:26:27Z"}, "docmost-postgres": {"ref": "postgres:16-alpine", "digest": "sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "at": "2026-09-27T09:24:59Z"}, "docmost-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-27T09:24:59Z"}}
conversion_copy=None
state=running phase=done
== unit /mnt/sys_drive/felhom-data/backups/primary/docmost
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T09:26:35Z"
manifest.image_pins = ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T09:25:42Z", "image_pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T09:25:42.669342118Z", "size": 134715, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T09:25:43.909357343Z", "size": 51837440, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T09:25:44.538433114Z", "size": 25600, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T09:25:44.927369842Z", "size": 1536, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.95.0
image: postgres:16-alpine
image: redis:7-alpine
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T09:25:56.5155121220Z 6426 compose/.felhom.yml
2026-09-27T09:25:56.5155121220Z 447 compose/app.yaml
2026-09-27T09:25:56.5145121100Z 3105 compose/docker-compose.yml
2026-09-27T09:25:45.0653715360Z 2360 data-stamps.json
2026-09-27T09:25:42.6693421180Z 134715 db-dumps/docmost-postgres.sql
2026-09-27T09:26:35.9949968540Z 4650 manifest.json
2026-09-27T09:25:43.9093573430Z 51837440 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T09:25:44.5384331140Z 25600 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T09:25:44.9273698420Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260927T092556Z-docmost-postgres.sql: Dumped from database version 16.15
== unit /mnt/felhom-drives/scratch_hdd/backups/secondary/docmost/recovery-unit
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T09:25:56Z"
manifest.image_pins = ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T09:25:42Z", "image_pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T09:25:42.669342118Z", "size": 134715, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T09:25:43.909357343Z", "size": 51837440, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T09:25:44.538433114Z", "size": 25600, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T09:25:44.927369842Z", "size": 1536, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.95.0
image: postgres:16-alpine
image: redis:7-alpine
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T09:25:56.5155121220Z 6426 compose/.felhom.yml
2026-09-27T09:25:56.5155121220Z 447 compose/app.yaml
2026-09-27T09:25:56.5145121100Z 3105 compose/docker-compose.yml
2026-09-27T09:25:45.0653715360Z 2360 data-stamps.json
2026-09-27T09:25:42.6693421180Z 134715 db-dumps/docmost-postgres.sql
2026-09-27T09:25:56.5162918310Z 4434 manifest.json
2026-09-27T09:25:43.9093573430Z 51837440 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T09:25:44.5384331140Z 25600 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T09:25:44.9273698420Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
== live
compose image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
compose image: postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
compose image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
PGDATA=/var/lib/postgresql/data PG_VERSION=16
docmost docmost/docmost:0.96.0 Up 30 seconds (healthy)
docmost-postgres postgres:16-alpine Up 41 seconds (healthy)
docmost-redis redis:7-alpine Up 41 seconds (healthy)
volume docmost_docmost_postgres_data
volume docmost_docmost_redis_data
volume docmost_docmost_storage
pg volume root:
PG_VERSION base global pg_commit_ts pg_dynshmem pg_hba.conf pg_ident.conf pg_logical pg_multixact pg_notify pg_replslot pg_serial pg_snapshots pg_stat pg_stat_tmp pg_subtrans pg_tblspc pg_twophase pg_wal pg_xact postgresql.auto.conf postgresql.conf postmaster.opts postmaster.pid
restore points offered (GET /api/backup/snapshots): 200 [{"time": "2026-09-27T09:25:42Z", "short_id": "helyi", "tier": 1, "drive_label": "Bels\u0151 SSD (rendszer)"}]
@@ -0,0 +1,131 @@
# L7-restore-app-step — restore pressed at 2026-09-27T09:27:02Z (own unit, snapshot helyi)
{"ok": true, "snapshot_id": "helyi", "snapshots": [{"time": "2026-09-27T09:25:42Z", "short_id": "helyi", "tier": 1, "drive_label": "Bels\u0151 SSD (rendszer)"}], "http": "HTTP/2 302", "location": ["location: /backups/restore?flash=flash.restore.started"], "seconds": 30.4, "state_after": "running", "hold_after": null}
controller lines:
2026/09/27 09:27:03 handlers.go:1717: [WARN] [web] Restore requested (async): stack=docmost, snapshot=helyi from 172.18.0.6:41330
2026/09/27 09:27:03 restore_unit.go:381: [INFO] [backup] Restore docmost: the data belongs to [docmost/docmost:0.95.0 postgres:16-alpine redis:7-alpine] (written 2026-09-27T09:25:42Z); the app ran [docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea redis:7-alpine@sha256:858f009f9709ce
2026/09/27 09:27:03 restore_unit.go:393: [INFO] [backup] Restoring docmost from recovery unit /mnt/sys_drive/felhom-data/backups/primary/docmost: images=3, secrets recovered=2/2, data_keys=0
2026/09/27 09:27:03 manager.go:1305: [INFO] [stacks] Stopping stack: docmost
2026/09/27 09:27:04 manager.go:1314: [INFO] [stacks] Stack docmost stopped successfully (took 1.4s)
2026/09/27 09:27:04 restore.go:152: [INFO] [backup] Restoring Docker volume docmost_docmost_postgres_data for docmost
2026/09/27 09:27:06 restore.go:152: [INFO] [backup] Restoring Docker volume docmost_docmost_redis_data for docmost
2026/09/27 09:27:06 restore.go:152: [INFO] [backup] Restoring Docker volume docmost_docmost_storage for docmost
2026/09/27 09:27:06 restore.go:195: [INFO] [backup] Restored 3 Docker volume(s) for docmost
2026/09/27 09:27:06 deploy.go:720: [INFO] [stacks] Redeploying docmost from recovery unit with 4 env vars
2026/09/27 09:27:06 [INFO] [stacks] SaveAppConfig: saved config for docmost
2026/09/27 09:27:06 [INFO] [stacks] SaveAppConfig: saved config for docmost
2026/09/27 09:27:06 pin.go:93: [INFO] [stacks] pin docmost: docmost=docmost/docmost:0.95.0, docmost-postgres=postgres:16-alpine, docmost-redis=redis:7-alpine
2026/09/27 09:27:06 manager.go:1269: [INFO] [stacks] Starting stack docmost services only: [docmost-postgres]
2026/09/27 09:27:07 manager.go:1280: [INFO] [stacks] Stack docmost services [docmost-postgres] started (took 0.4s)
2026/09/27 09:27:07 restore_db.go:87: [INFO] [backup] Restore docmost: replaying DB dump into docmost-postgres (postgres)
2026/09/27 09:27:09 dbdump.go:801: [INFO] [backup] Imported DB dump docmost-postgres.sql into docmost-postgres (postgres)
2026/09/27 09:27:09 restore_db.go:97: [INFO] [backup] Restore docmost: replayed 1 DB dump(s)
2026/09/27 09:27:09 manager.go:1216: [INFO] [stacks] Starting stack: docmost
2026/09/27 09:27:20 manager.go:1231: [INFO] [stacks] Stack docmost started successfully (took 11.2s)
2026/09/27 09:27:20 [INFO] [stacks] SaveAppConfig: saved config for docmost
2026/09/27 09:27:20 installed.go:420: [INFO] [stacks] installed-images docmost: recorded 3 service(s) (docmost=docmost/docmost:0.95.0 (sha256:41c8d777cf23…), docmost-postgres=postgres:16-alpine (sha256:721873c34ceb…), docmost-redis=redis:7-alpine (sha256:858f009f9709…))
2026/09/27 09:27:23 manager.go:1562: [INFO] [stacks] Stack docmost post-start status:
2026/09/27 09:27:23 manager.go:1565: [INFO] [stacks] docmost docmost/docmost:0.95.0 running Up 3 seconds (health: starting)
2026/09/27 09:27:23 manager.go:1565: [INFO] [stacks] docmost-postgres postgres:16-alpine running Up 16 seconds (healthy)
2026/09/27 09:27:23 manager.go:1565: [INFO] [stacks] docmost-redis redis:7-alpine running Up 14 seconds (healthy)
2026/09/27 09:27:33 restore_unit.go:478: [INFO] [backup] Restore-from-unit completed: docmost — 3 volume(s) of 3 listed, 1 database(s) of 1 listed
2026/09/27 09:27:33 handlers.go:1729: [INFO] [web] Restore completed (async): stack=docmost in 30.132493382s (volumes 3/3, dbs 1/1)
docmost-postgres log (tail):
PostgreSQL Database directory appears to contain a database; Skipping initialization
2026-09-27 11:27:07.351 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
2026-09-27 11:27:07.351 CEST [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2026-09-27 11:27:07.351 CEST [1] LOG: listening on IPv6 address "::", port 5432
2026-09-27 11:27:07.357 CEST [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2026-09-27 11:27:07.370 CEST [30] LOG: database system was shut down at 2026-09-27 11:25:43 CEST
2026-09-27 11:27:07.381 CEST [1] LOG: database system is ready to accept connections
docmost log (tail):
> docmost@0.95.0 start /app
> pnpm --filter ./apps/server run start:prod
> server@0.95.0 start:prod /app/apps/server
> cross-env NODE_ENV=production node dist/main
{"level":"info","time":"2026-09-27T09:27:28.397Z","pid":45,"hostname":"1ff3ac5cf461","context":"RedisModule","msg":"default: the connection was successfully established"}
{"level":"info","time":"2026-09-27T09:27:28.643Z","pid":45,"hostname":"1ff3ac5cf461","context":"DatabaseModule","msg":"Establishing database connection"}
{"level":"info","time":"2026-09-27T09:27:28.668Z","pid":45,"hostname":"1ff3ac5cf461","context":"DatabaseModule","msg":"Database connection successful"}
{"level":"info","time":"2026-09-27T09:27:28.848Z","pid":45,"hostname":"1ff3ac5cf461","context":"DatabaseMigrationService","msg":"No pending database migrations"}
{"level":"info","time":"2026-09-27T09:27:28.871Z","pid":45,"hostname":"1ff3ac5cf461","context":"NestApplication","msg":"Nest application successfully started"}
{"level":"info","time":"2026-09-27T09:27:28.903Z","pid":45,"hostname":"1ff3ac5cf461","context":"NestApplication","msg":"Listening on http://127.0.0.1:3000 / https://c-docs.enkisfelhom.hu"}
seed reads back through the front door: True
# L7-restore-app-step — 2026-09-27T11:27:58+0200; controller gitea.dooplex.hu/admin/felhom-controller:0.275.0-rc1
pinned={'docmost': 'docmost/docmost:0.95.0', 'docmost-postgres': 'postgres:16-alpine', 'docmost-redis': 'redis:7-alpine'}
installed={"docmost": {"ref": "docmost/docmost:0.95.0", "digest": "sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "at": "2026-09-27T09:27:20Z"}, "docmost-postgres": {"ref": "postgres:16-alpine", "digest": "sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "at": "2026-09-27T09:27:20Z"}, "docmost-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-27T09:27:20Z"}}
conversion_copy=None
state=running phase=done
== unit /mnt/sys_drive/felhom-data/backups/primary/docmost
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T09:26:35Z"
manifest.image_pins = ["docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T09:25:42Z", "image_pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T09:25:42.669342118Z", "size": 134715, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T09:25:43.909357343Z", "size": 51837440, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T09:25:44.538433114Z", "size": 25600, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T09:25:44.927369842Z", "size": 1536, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.95.0
image: postgres:16-alpine
image: redis:7-alpine
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T09:25:56.5155121220Z 6426 compose/.felhom.yml
2026-09-27T09:25:56.5155121220Z 447 compose/app.yaml
2026-09-27T09:25:56.5145121100Z 3105 compose/docker-compose.yml
2026-09-27T09:25:45.0653715360Z 2360 data-stamps.json
2026-09-27T09:25:42.6693421180Z 134715 db-dumps/docmost-postgres.sql
2026-09-27T09:26:35.9949968540Z 4650 manifest.json
2026-09-27T09:25:43.9093573430Z 51837440 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T09:25:44.5384331140Z 25600 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T09:25:44.9273698420Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260927T092556Z-docmost-postgres.sql: Dumped from database version 16.15
== unit /mnt/felhom-drives/scratch_hdd/backups/secondary/docmost/recovery-unit
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T09:25:56Z"
manifest.image_pins = ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T09:25:42Z", "image_pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T09:25:42.669342118Z", "size": 134715, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T09:25:43.909357343Z", "size": 51837440, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T09:25:44.538433114Z", "size": 25600, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T09:25:44.927369842Z", "size": 1536, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.95.0
image: postgres:16-alpine
image: redis:7-alpine
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T09:25:56.5155121220Z 6426 compose/.felhom.yml
2026-09-27T09:25:56.5155121220Z 447 compose/app.yaml
2026-09-27T09:25:56.5145121100Z 3105 compose/docker-compose.yml
2026-09-27T09:25:45.0653715360Z 2360 data-stamps.json
2026-09-27T09:25:42.6693421180Z 134715 db-dumps/docmost-postgres.sql
2026-09-27T09:25:56.5162918310Z 4434 manifest.json
2026-09-27T09:25:43.9093573430Z 51837440 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T09:25:44.5384331140Z 25600 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T09:25:44.9273698420Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
== live
compose image: docmost/docmost:0.95.0
compose image: postgres:16-alpine
compose image: redis:7-alpine
PGDATA=/var/lib/postgresql/data PG_VERSION=16
docmost docmost/docmost:0.95.0 Up 43 seconds (healthy)
docmost-redis redis:7-alpine Up 53 seconds (healthy)
docmost-postgres postgres:16-alpine Up 56 seconds (healthy)
volume docmost_docmost_postgres_data
volume docmost_docmost_redis_data
volume docmost_docmost_storage
pg volume root:
PG_VERSION base global pg_commit_ts pg_dynshmem pg_hba.conf pg_ident.conf pg_logical pg_multixact pg_notify pg_replslot pg_serial pg_snapshots pg_stat pg_stat_tmp pg_subtrans pg_tblspc pg_twophase pg_wal pg_xact postgresql.auto.conf postgresql.conf postmaster.opts postmaster.pid
restore points offered (GET /api/backup/snapshots): 200 [{"time": "2026-09-27T09:25:42Z", "short_id": "helyi", "tier": 1, "drive_label": "Bels\u0151 SSD (rendszer)"}]
restore-status (the page's sentence): {"running": false, "op": "restore", "stack": "docmost", "started_at": "2026-09-27T09:27:03.461297747Z", "last": {"op": "restore", "stack": "docmost", "ok": true, "message": "A(z) docmost visszaállt a(z) 2026-09-27 11:25-i mentésből, a(z) docmost:0.95.0, postgres:16-alpine, redis:7-alpine verzióra. Elérhető frissítés: a doboz lépésenként hozza naprakészre. A(z) docmost: 3 adatkötet és az adatbázis visszaállítva — az alkalmazás újraindult.", "finished_at": "2026-09-27T09:27:33.594850669Z"}, "last_recent": true}
@@ -0,0 +1,67 @@
{
"accepted": true,
"http": "202",
"phases": [
{
"t": 0.0,
"phase": "backing-up",
"label": "Biztons\u00e1gi ment\u00e9s k\u00e9sz\u00fcl a friss\u00edt\u00e9s el\u0151tt\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 15.4,
"phase": "safety-dump",
"label": "Adatb\u00e1zis pillanatk\u00e9p\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 16.4,
"phase": "pulling",
"label": "\u00daj verzi\u00f3 let\u00f6lt\u00e9se\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 17.4,
"phase": "copying",
"label": "Az adatok m\u00e1sol\u00e1sa a friss\u00edt\u00e9s el\u0151tt\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 19.5,
"phase": "starting",
"label": "Ind\u00edt\u00e1s az \u00faj verzi\u00f3val\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 30.8,
"phase": "verifying",
"label": "M\u0171k\u00f6d\u00e9s ellen\u0151rz\u00e9se\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 46.2,
"phase": "done",
"label": "Friss\u00edtve",
"updating": false,
"error": null,
"hold": null
}
],
"duration_s": 46.2,
"final_phase": "done",
"update_error": null,
"hold_reason": null,
"state": "running"
}
@@ -0,0 +1,72 @@
# L8-climb-app — 2026-09-27T11:28:55+0200; controller gitea.dooplex.hu/admin/felhom-controller:0.275.0-rc1
pinned={'docmost': 'docmost/docmost:0.96.0', 'docmost-postgres': 'postgres:16-alpine', 'docmost-redis': 'redis:7-alpine'}
installed={"docmost": {"ref": "docmost/docmost:0.96.0", "digest": "sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a", "at": "2026-09-27T09:28:54Z"}, "docmost-postgres": {"ref": "postgres:16-alpine", "digest": "sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "at": "2026-09-27T09:27:20Z"}, "docmost-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-27T09:27:20Z"}}
conversion_copy=None
state=running phase=done
== unit /mnt/sys_drive/felhom-data/backups/primary/docmost
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T09:28:23Z"
manifest.image_pins = ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T09:28:09Z", "image_pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T09:28:09.530145285Z", "size": 134942, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T09:28:11.097164525Z", "size": 53069824, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T09:28:11.732172321Z", "size": 38400, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T09:28:10.655382842Z", "size": 1536, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.95.0
image: postgres:16-alpine
image: redis:7-alpine
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T09:28:23.3333147590Z 6426 compose/.felhom.yml
2026-09-27T09:28:23.3333147590Z 447 compose/app.yaml
2026-09-27T09:28:23.3333147590Z 3105 compose/docker-compose.yml
2026-09-27T09:28:11.8891742490Z 2360 data-stamps.json
2026-09-27T09:28:09.5301452850Z 134942 db-dumps/docmost-postgres.sql
2026-09-27T09:28:23.3346389480Z 4434 manifest.json
2026-09-27T09:28:11.0971645250Z 53069824 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T09:28:11.7321723210Z 38400 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T09:28:10.6553828420Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260927T092556Z-docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260927T092823Z-docmost-postgres.sql: Dumped from database version 16.15
== unit /mnt/felhom-drives/scratch_hdd/backups/secondary/docmost/recovery-unit
manifest.controller_version = "0.275.0-rc1"
manifest.created_at = "2026-09-27T09:28:23Z"
manifest.image_pins = ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"]
manifest.db_dumps = ["docmost-postgres.sql"]
manifest.volume_dumps = ["docmost_docmost_postgres_data.tar", "docmost_docmost_redis_data.tar", "docmost_docmost_storage.tar"]
manifest.data = {"at": "2026-09-27T09:28:09Z", "image_pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}, "files": {"db-dumps/docmost-postgres.sql": {"at": "2026-09-27T09:28:09.530145285Z", "size": 134942, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_postgres_data.tar": {"at": "2026-09-27T09:28:11.097164525Z", "size": 53069824, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_redis_data.tar": {"at": "2026-09-27T09:28:11.732172321Z", "size": 38400, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}, "volume-dumps/docmost_docmost_storage.tar": {"at": "2026-09-27T09:28:10.655382842Z", "size": 1536, "pins": ["docmost/docmost:0.95.0", "postgres:16-alpine", "redis:7-alpine"], "images": {"docmost": "docmost/docmost:0.95.0@sha256:41c8d777cf23c74e78f94e676aec328b7d7856f48df5e573543dac68d371e37c", "docmost-postgres": "postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea", "docmost-redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"}}}}
compose/ images:
image: docmost/docmost:0.95.0
image: postgres:16-alpine
image: redis:7-alpine
compose/ postgres mount:
- docmost_postgres_data:/var/lib/postgresql/data
docmost_postgres_data:
mtimes (UTC):
2026-09-27T09:28:23.3333147590Z 6426 compose/.felhom.yml
2026-09-27T09:28:23.3333147590Z 447 compose/app.yaml
2026-09-27T09:28:23.3333147590Z 3105 compose/docker-compose.yml
2026-09-27T09:28:11.8891742490Z 2360 data-stamps.json
2026-09-27T09:28:09.5301452850Z 134942 db-dumps/docmost-postgres.sql
2026-09-27T09:28:23.3346389480Z 4434 manifest.json
2026-09-27T09:28:11.0971645250Z 53069824 volume-dumps/docmost_docmost_postgres_data.tar
2026-09-27T09:28:11.7321723210Z 38400 volume-dumps/docmost_docmost_redis_data.tar
2026-09-27T09:28:10.6553828420Z 1536 volume-dumps/docmost_docmost_storage.tar
docmost-postgres.sql: Dumped from database version 16.15
pre-restore-20260927T092556Z-docmost-postgres.sql: Dumped from database version 16.15
== live
compose image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
compose image: postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
compose image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
PGDATA=/var/lib/postgresql/data PG_VERSION=16
docmost docmost/docmost:0.96.0 Up 21 seconds (healthy)
docmost-postgres postgres:16-alpine Up 32 seconds (healthy)
docmost-redis redis:7-alpine Up 32 seconds (healthy)
volume docmost_docmost_postgres_data
volume docmost_docmost_redis_data
volume docmost_docmost_storage
pg volume root:
PG_VERSION base global pg_commit_ts pg_dynshmem pg_hba.conf pg_ident.conf pg_logical pg_multixact pg_notify pg_replslot pg_serial pg_snapshots pg_stat pg_stat_tmp pg_subtrans pg_tblspc pg_twophase pg_wal pg_xact postgresql.auto.conf postgresql.conf postmaster.opts postmaster.pid
restore points offered (GET /api/backup/snapshots): 200 [{"time": "2026-09-27T09:28:09Z", "short_id": "helyi", "tier": 1, "drive_label": "Bels\u0151 SSD (rendszer)"}]
@@ -0,0 +1,42 @@
# A5 live — Part A on 9202 (controller 0.275.0-rc1, drill catalog = live `main` + one reverted deploy commit)
Method: endpoint level (`POST /api/stacks/docmost/update`, the backups page's `POST /backup/restore` form,
`GET /api/backup/restore-status` for the page's sentence), the unit read off the disk, the seed read back through
docmost's own front door (a user + login, `fixtures.py`). Times UTC unless marked.
## Shape 2 — the engine step, in the box's OWN night (not pressed by me)
`L2-night-leg-log.txt`, `L2-window-after-night-leg.txt`. 00:30 the nightly data run stamped docmost's dump and tars
(PostgreSQL 16). **02:15 the automatic leg converted docmost 16 → 18 by itself** (precondition: "Tier 2 copy from
00:30:00Z" — the data's time). **02:16:35 the refresh re-captured the unit and KEPT the 16 definition:** „the app
now runs [… postgres:18 …]; the unit keeps the definition of its data ([… postgres:16 …], written 00:30:00Z)".
Manifest: `image_pins` = 18 (current), `data.image_pins` = 16, `compose/` = 16; restore point offered **00:30:00Z**
(v0.274.0 offered the refresh's time). The kept pre-conversion copy stayed kept for 7 h (hourly release: no copy
after the conversion — pre-fix it went at the first tick after the refresh, R-696).
`L3-restore-own-unit-in-window.txt` — restore (own unit, `helyi`) at 09:20: „Restore docmost: the data belongs to
[… 16 …]"; 3 volumes + 1 database; **back whole at PostgreSQL 16** (`PG_VERSION` 16, pin `postgres:16-alpine`), the
seed logs in. The page's first sentence: „A(z) docmost visszaállt a(z) 2026-09-27 02:30-i mentésből, a(z)
docmost:0.96.0, postgres:16-alpine, redis:7-alpine verzióra. Elérhető frissítés: a doboz lépésenként hozza
naprakészre." (02:30 CEST = 00:30Z.) Before the fix the same restore left the app down (`A1/S4`).
`L4-climb-again.*` — the guarded Update: backing-up → safety-dump → copying → converting (7 s) → starting →
verifying → done in 55.4 s; `PG_VERSION` 18; the seed logs in.
## Shape 1 — the app step (docmost 0.95.0 → 0.96.0), pressed by me
`L1-deployed.txt` (reinstalled at 0.95.0 via one drill commit, reverted), `L5-step-app.*` (done 46.2 s),
`L6-after-refresh-app-step.txt`: the capture 7 s after the update KEPT `compose/` at 0.95.0; `image_pins` 0.96.0,
`data.image_pins` 0.95.0, restore point 09:25:42Z = the data. `L7-restore-app-step.txt`: back at 0.95.0 whole, the
seed logs in, **docmost logged "No pending database migrations"** (pre-fix it ran four migrations unguarded, `A1/S2`),
sentence as above with 0.95.0. `L8-climb-app.*`: the guarded Update climbed to 0.96.0 in 46.2 s; the seed logs in.
## Not observed live
- The conversion-copy RELEASE on a real 18 dump (needs a nightly data run after a conversion, then an hourly tick):
unit-tested (`TestA5_TheReleaseRefusesAPreConversionDump`), the kept half seen live above.
- Off-site restore (9202 has no off-site target; the boxes that do are fenced): unit-tested
(`TestA3_TheOffsiteRestoreBringsTheSnapshotsVersionBack`).
- The English sentence live (the box is Hungarian): unit-tested both languages.
State left: docmost on 9202 at 0.96.0 / PostgreSQL 16 (the automatic leg may convert it again tonight).
@@ -0,0 +1,7 @@
a_version_travel_test.go:138: Tier 1's time = 2026-09-26T08:01:15Z, want the DATA's time 2026-09-26T06:01:15Z — the refresh 1s made a two-hour-old dump read as new
--- FAIL: TestA5_RefreshAfterAPinChangeDoesNotMoveTier1sTime (0.00s)
a_version_travel_test.go:308: the precondition ACCEPTED tier 1 at 2026-09-26T08:01:15Z (1s old) — the data is from 2026-09-26T06:01:15Z
--- FAIL: TestA5_ThePreconditionRefusesAStaleDumpARefreshMadeLookNew (0.00s)
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/backup 0.020s
FAIL
@@ -0,0 +1,7 @@
a_version_travel_test.go:149: the unit's compose/ names [example/app:0.96.0 postgres:18-alpine] — the refresh paired the 18 definition with the 16 data
--- FAIL: TestA2_TheUnitKeepsTheDefinitionItsDataBelongsTo (0.00s)
a_version_travel_test.go:227: restore: A(z) app mentésében a beállítás (0.96.0) nem ahhoz a verzióhoz tartozik, amelyik az adatokat írta (0.96.0), ezért a visszaállítás nem indult el. Az alkalmazás érintetlen.
--- FAIL: TestA5_ARestoreInTheWindowStartsTheOldVersionWithTheOldData (0.01s)
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/backup 0.030s
FAIL
@@ -0,0 +1,6 @@
# RP2b — BOTH pre-fix shapes (the refresh rewrites compose/, the restore has no version check): the v0.274.0 consequence
a_version_travel_test.go:230: the restore started the 16 data with the definition example/app:0.96.0 postgres:18-alpine — a restore must never mix versions
--- FAIL: TestA5_ARestoreInTheWindowStartsTheOldVersionWithTheOldData (3.00s)
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/backup 3.010s
FAIL
@@ -0,0 +1,8 @@
a_version_travel_test.go:248: err = <nil>, want ErrUnitVersionMismatch
a_version_travel_test.go:269: err = <nil>, want ErrUnitVersionMismatch
--- FAIL: TestA3_AMismatchedOrMixedUnitIsRefusedBeforeAnythingMoves (6.01s)
--- FAIL: TestA3_AMismatchedOrMixedUnitIsRefusedBeforeAnythingMoves/definition-not-the-data's (3.00s)
--- FAIL: TestA3_AMismatchedOrMixedUnitIsRefusedBeforeAnythingMoves/mixed (3.01s)
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/backup 6.017s
FAIL
@@ -0,0 +1,6 @@
# RP4 — the release without the dump check (v0.274.0: a copy proven after the conversion was enough)
pgconvert_test.go:546: a dump written BEFORE the conversion, by 16: released [nextcloud]; copies=0 — the 16 datadir copy went on a backup that holds no 18 dump
--- FAIL: TestA5_TheReleaseRefusesAPreConversionDump (0.01s)
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/stacks 0.020s
FAIL
@@ -0,0 +1,6 @@
# RP5 — the off-site restore without the definition write (v0.274.0 always used the live compose)
a_version_travel_test.go:469: the restore wrote the definition "" — want the snapshot's 16
--- FAIL: TestA3_TheOffsiteRestoreBringsTheSnapshotsVersionBack (3.01s)
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/backup 3.012s
FAIL
@@ -0,0 +1,28 @@
# A7 — a backup stores the image's NAME, not the image: how many of today's digests still resolve
Measured 2026-09-26T08:15:42Z from DooPlex, read-only: `a7head.py` sends one registry **HEAD** per
`ref@digest` (anonymous token; a HEAD is not a pull and does not count against Docker Hub's pull limit).
**The fact.** A recovery unit records `image_pins` and — since v0.275.0 — each data file's running
`ref@digest` (`data.files[*].images`); the manifest's own note says "image NOT stored — re-pulled on restore".
So a restore of a version works only while the registry still serves that version. If a maker deletes an old
tag or digest, a unit of that version cannot start, and v0.275.0's rule (a restore brings the data back at its
own version) makes that dependency sharper: the restore asks for exactly the old version.
**Today.** The catalog records digests only in its ladder entries (`update_ladder[].digest`): **42 distinct
`ref@digest` pairs, all 42 answer 200** (`a7-result.txt`). Negative control: the same instrument answers **404**
for an invented digest on Docker Hub and on ghcr.io (`a7-negative-control.txt`), so a 200 is not the
instrument's only answer. The 66 compose image lines carry no digest in the catalog (the box adds one when it
pins from a ladder entry); a tag can be re-pointed or deleted without any digest to check against, so this
measures what is checkable, not the whole exposure.
**Not measured:** the digests actually recorded on boxes (`installed_images`), which include versions older
than any ladder entry; how often makers delete old versions (no history kept); the `from` side of ladder
entries (no digest recorded there).
**Options, not decided (filed as a row):** (a) keep as is — a restore of a deleted version fails with the pull
error, and the household's route is the next copy or a newer version; (b) mirror every image a box has
INSTALLED into the DooPlex registry (`gitea.dooplex.hu`) and let a restore fall back to the mirror — storage
and bandwidth on DooPlex, and a new moving part on the recovery path; (c) mirror only the versions the ladder
names (bounded by the catalog, not by the fleet) — does not cover a box on a pre-ladder version; (d) store the
image in the unit (`docker save`) — hundreds of MB per app per copy, on every tier including off-site.
@@ -0,0 +1,2 @@
404 postgres:16-alpine@sha256:000000000000 control
404 ghcr.io/advplyr/audiobookshelf:2.36.1@sha256:000000000000 control
@@ -0,0 +1,715 @@
{
"with_digest": [
[
"actualbudget/actual-server:26.9.0",
"sha256:552beab3dec8c93d46b8b9245612d63c3f123b8a45063a474f53e229b17621d3",
[
"actualbudget:ladder"
]
],
[
"ghcr.io/advplyr/audiobookshelf:2.36.1",
"sha256:3528a93b6442ffe54bd46771bbbab7c97084e1101071586d9dc2254f30bb4358",
[
"audiobookshelf:ladder"
]
],
[
"lscr.io/linuxserver/bookstack:26.05.5",
"sha256:189c796273469115cf810e53f450e15b93184018e4728cd65fcaef8aa93584bc",
[
"bookstack:ladder"
]
],
[
"mariadb:12.3",
"sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
[
"bookstack:ladder",
"nextcloud:ladder"
]
],
[
"docmost/docmost:0.96.0",
"sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a",
[
"docmost:ladder"
]
],
[
"postgres:16-alpine",
"sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea",
[
"docmost:ladder",
"tandoor:ladder"
]
],
[
"redis:7-alpine",
"sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499",
[
"docmost:ladder",
"immich:ladder",
"nextcloud:ladder",
"romm:ladder"
]
],
[
"postgres:18-alpine",
"sha256:77f585114c32fbca283dc835b0596f4e52b51b4c6662d7810b2f4084f60a1873",
[
"docmost:ladder"
]
],
[
"emby/embyserver:4.11.0.1",
"sha256:bcc54978db53e333c5b693948447df0ed9dfa7c798a751a9402ff4da4909a6e2",
[
"emby:ladder"
]
],
[
"emby/embyserver:4.11.0.3",
"sha256:2ff130d624a97782474e7de791875d2871d613b2afaddc73b3e11eb0c9caa770",
[
"emby:ladder"
]
],
[
"ghost:6.64.0-alpine",
"sha256:47ecbe856dd06dcd20cb9410e1c4d532fc085eba776cfabc203609c7d15d8320",
[
"ghost:ladder"
]
],
[
"ghost:6.65.0-alpine",
"sha256:65788e5e2c5478319f8fc65ac12816dbc941d1a9c834c87190cf1d2d1b79d4e2",
[
"ghost:ladder"
]
],
[
"grafana/grafana:13.2.2",
"sha256:ac461fb352abc50da10a51c7d02462e9c05488f11f53f14b3ad79a8145f638a0",
[
"grafana:ladder"
]
],
[
"ghcr.io/home-assistant/home-assistant:2026.9.3",
"sha256:d8922685169707fd91e8b9729902d975f06157d005e422874d201e0261dda196",
[
"home-assistant:ladder"
]
],
[
"ghcr.io/immich-app/immich-machine-learning:v3.0.3",
"sha256:d76fe88b69282c09a97eac4f82dafa82cfd77bce274bc742591cde974f87dacb",
[
"immich:ladder"
]
],
[
"ghcr.io/immich-app/postgres:16-vectorchord0.4.3-pgvectors0.2.0",
"sha256:1a078b237c1d9b420b0ee59147386b4aa60d3a07a8e6a402fc84a57e41b043a4",
[
"immich:ladder"
]
],
[
"ghcr.io/immich-app/immich-server:v3.2.2",
"sha256:79cc1623323d5894922686d8743b4780181428f98eecbfb58ce12c41ef02d1ea",
[
"immich:ladder"
]
],
[
"ghcr.io/immich-app/immich-machine-learning:v3.2.2",
"sha256:60dfcf266a9ef3b7376f5678e8c980d4fb61db5fc48c078fe8a326ab1535d60d",
[
"immich:ladder"
]
],
[
"kimai/kimai2:apache-2.57.0",
"sha256:efa66c5eadf948b94d8031e9436feae491d90b2ceaa3d5e45e4d7c1a59dd8c38",
[
"kimai:ladder"
]
],
[
"mariadb:11.8",
"sha256:79d59758afc91b89b120b0a8904d637f5a3b3e1c4900f29b740d6d46c72fef68",
[
"kimai:ladder",
"romm:ladder"
]
],
[
"gotson/komga:1.27.1",
"sha256:9cf102f5fb78e2e020700c53eca757e4f4d4e347121b0a16380822760337cca9",
[
"komga:ladder"
]
],
[
"ghcr.io/mealie-recipes/mealie:v3.27.0",
"sha256:ba24b88462380fb59a6c7d04c6d9e607e0b6b04e31306592181186bcdab1952b",
[
"mealie:ladder"
]
],
[
"ghcr.io/mealie-recipes/mealie:v3.28.0",
"sha256:8b02290f4d1806f02acac6f25f6d48a3c965612fda1f8e914d5af533276f8688",
[
"mealie:ladder"
]
],
[
"n8nio/n8n:2.40.5",
"sha256:9f693fd5565539efd5e75ad168526c8041a6af516d9e50bc4d9cb1c9c5031523",
[
"n8n:ladder"
]
],
[
"n8nio/n8n:2.41.1",
"sha256:52f147bba97908fe58e616738f2f0485696ac7b5670a1baf169ccf1ff3173de7",
[
"n8n:ladder"
]
],
[
"n8nio/n8n:2.41.2",
"sha256:1419c3c665b02531dd43d815ef62f573aa9b1307962162a08a349dc8a452e8bf",
[
"n8n:ladder"
]
],
[
"deluan/navidrome:0.64.0",
"sha256:a384948b81bd1529986c5960169e7fc4fa00f46bde6bd517971a4c36671db2af",
[
"navidrome:ladder"
]
],
[
"deluan/navidrome:0.64.1",
"sha256:df22d661b8d0322c33754d999b567150df9e131a47ae53be71fed0154bf8cef5",
[
"navidrome:ladder"
]
],
[
"nextcloud:34.0.1-apache",
"sha256:b52f7bc0e496f227b0e85e3b88571a42c68b6245ccde29d577e733227715dcf5",
[
"nextcloud:ladder"
]
],
[
"nextcloud:34.0.4-apache",
"sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
[
"nextcloud:ladder"
]
],
[
"ghcr.io/thomiceli/opengist:1.15",
"sha256:7edc91273ee7d10a17406da8a08c803158baaff984c39b789c1313473d068f21",
[
"opengist:ladder"
]
],
[
"ghcr.io/papra-hq/papra:26.6.2-rootless",
"sha256:a281cb44176dbe5323e0f7ea2d6fd34d58914a3a8525c36437a086d1d7c4fef8",
[
"papra:ladder"
]
],
[
"privatebin/pdo:2.0.6",
"sha256:4c141b2326f8b353598ce9ce7507a9cfecf2dad5c60a39fea903d430e296d8f5",
[
"privatebin:ladder"
]
],
[
"lscr.io/linuxserver/radarr:6.4.4",
"sha256:adb6c09d6b729ea5e642c99cea35af72702ef476bf4763f153299ac5db9f0b4f",
[
"radarr:ladder"
]
],
[
"rommapp/romm:5.3.0",
"sha256:dc586cb3a2c7316fcffb3dc273171b1964523f0f409e989295d26d2199df1d4e",
[
"romm:ladder"
]
],
[
"mariadb:11.4",
"sha256:70cc072b29b4a89ae07abb2d4da2c64678a7f2dfe092751bb51c87d67dc1338b",
[
"romm:ladder"
]
],
[
"rommapp/romm:5.3.1",
"sha256:0d66b4ea152a237c7f24b95e87459f46d3c596a7c0b35a82f26bc971487278b3",
[
"romm:ladder"
]
],
[
"lscr.io/linuxserver/sonarr:4.0.20",
"sha256:a5c1a5fecbef946927ab90ad68df319ac5fe644057e5fc18cd993f01ac07b2b2",
[
"sonarr:ladder"
]
],
[
"ghcr.io/tandoorrecipes/recipes:2.6.15",
"sha256:2e759dd1478a2ed119ee474e28522079fb1cfa50b3fd25cba89f6b9a67abad72",
[
"tandoor:ladder"
]
],
[
"ghcr.io/lukegus/termix:2.8.0",
"sha256:25e8a0eb39f45c9ac5e8e7615fd84a0380018ea012317bc665b86458d900b4b9",
[
"termix:ladder"
]
],
[
"vikunja/vikunja:2.6.0",
"sha256:417ada6f94e81f0267aa2f007d0a811fc82d38dd2aa58351e3ea520ca01c2ea5",
[
"vikunja:ladder"
]
],
[
"ghcr.io/cmintey/wishlist:v0.67.1",
"sha256:4b89bfb5b57ffb087c33978d21b09048e5c37f4506326e9ccd2705a0a1d86548",
[
"wishlist:ladder"
]
]
],
"no_digest": [
[
"actualbudget/actual-server:26.9.0",
[
"actualbudget:compose-nodigest"
]
],
[
"ghcr.io/seanmorley15/adventurelog-backend:v0.12.1",
[
"adventurelog:compose-nodigest"
]
],
[
"postgis/postgis:16-3.5-alpine",
[
"adventurelog:compose-nodigest"
]
],
[
"ghcr.io/seanmorley15/adventurelog-frontend:v0.12.1",
[
"adventurelog:compose-nodigest"
]
],
[
"ghcr.io/advplyr/audiobookshelf:2.36.1",
[
"audiobookshelf:compose-nodigest"
]
],
[
"ghcr.io/alam00000/bentopdf:v2.8.6",
[
"bentopdf:compose-nodigest"
]
],
[
"lscr.io/linuxserver/bookstack:26.05.5",
[
"bookstack:compose-nodigest"
]
],
[
"mariadb:12.3",
[
"bookstack:compose-nodigest",
"nextcloud:compose-nodigest"
]
],
[
"calcom/cal.com:v6.2.0",
[
"calcom:compose-nodigest"
]
],
[
"postgres:16-alpine",
[
"calcom:compose-nodigest",
"claper:compose-nodigest",
"outline:compose-nodigest",
"paperless-ngx:compose-nodigest",
"rallly:compose-nodigest",
"tandoor:compose-nodigest",
"zipline:compose-nodigest"
]
],
[
"crocodilestick/calibre-web-automated:v4.0.6",
[
"calibre-web:compose-nodigest"
]
],
[
"ghcr.io/claperco/claper:2.5",
[
"claper:compose-nodigest"
]
],
[
"lscr.io/linuxserver/code-server:4.129.0",
[
"code-server:compose-nodigest"
]
],
[
"registry.gitlab.com/crafty-controller/crafty-4:4.10.7",
[
"crafty-controller:compose-nodigest"
]
],
[
"docmost/docmost:0.96.0",
[
"docmost:compose-nodigest"
]
],
[
"postgres:18-alpine",
[
"docmost:compose-nodigest"
]
],
[
"redis:7-alpine",
[
"docmost:compose-nodigest",
"immich:compose-nodigest",
"nextcloud:compose-nodigest",
"outline:compose-nodigest",
"paperless-ngx:compose-nodigest",
"romm:compose-nodigest"
]
],
[
"emby/embyserver:4.11.0.3",
[
"emby:compose-nodigest"
]
],
[
"ghost:6.65.0-alpine",
[
"ghost:compose-nodigest"
]
],
[
"gitea/gitea:1.27.0",
[
"gitea:compose-nodigest"
]
],
[
"glanceapp/glance:v0.8.5",
[
"glance:compose-nodigest"
]
],
[
"f0rc3/gokapi:v1.9.6",
[
"gokapi:compose-nodigest"
]
],
[
"grafana/grafana:13.2.2",
[
"grafana:compose-nodigest"
]
],
[
"ghcr.io/gramps-project/grampsweb:v25.6.0",
[
"gramps-web:compose-nodigest"
]
],
[
"ghcr.io/home-assistant/home-assistant:2026.9.3",
[
"home-assistant:compose-nodigest"
]
],
[
"ghcr.io/sysadminsmedia/homebox:0.26.2",
[
"homebox:compose-nodigest"
]
],
[
"ghcr.io/gethomepage/homepage:v1.13.2",
[
"homepage:compose-nodigest"
]
],
[
"ghcr.io/immich-app/immich-server:v3.2.2",
[
"immich:compose-nodigest"
]
],
[
"ghcr.io/immich-app/immich-machine-learning:v3.2.2",
[
"immich:compose-nodigest"
]
],
[
"ghcr.io/immich-app/postgres:16-vectorchord0.4.3-pgvectors0.2.0",
[
"immich:compose-nodigest"
]
],
[
"jellyfin/jellyfin:10.11.11",
[
"jellyfin:compose-nodigest"
]
],
[
"kimai/kimai2:apache-2.57.0",
[
"kimai:compose-nodigest"
]
],
[
"mariadb:11.8",
[
"kimai:compose-nodigest",
"romm:compose-nodigest"
]
],
[
"gotson/komga:1.27.1",
[
"komga:compose-nodigest"
]
],
[
"ghcr.io/mealie-recipes/mealie:v3.28.0",
[
"mealie:compose-nodigest"
]
],
[
"n8nio/n8n:2.41.2",
[
"n8n:compose-nodigest"
]
],
[
"deluan/navidrome:0.64.1",
[
"navidrome:compose-nodigest"
]
],
[
"nextcloud:34.0.4-apache",
[
"nextcloud:compose-nodigest"
]
],
[
"onlyoffice/documentserver:9.4.0",
[
"onlyoffice:compose-nodigest"
]
],
[
"ghcr.io/thomiceli/opengist:1.15",
[
"opengist:compose-nodigest"
]
],
[
"outlinewiki/outline:1.9.1",
[
"outline:compose-nodigest"
]
],
[
"ghcr.io/paperless-ngx/paperless-ngx:2.20.15",
[
"paperless-ngx:compose-nodigest"
]
],
[
"ghcr.io/papra-hq/papra:26.6.2-rootless",
[
"papra:compose-nodigest"
]
],
[
"msdeluise/plant-it:0.10.0",
[
"plant-it:compose-nodigest"
]
],
[
"plexinc/pms-docker:1.41.4.9463-630c9f557",
[
"plex:compose-nodigest"
]
],
[
"privatebin/pdo:2.0.6",
[
"privatebin:compose-nodigest"
]
],
[
"lscr.io/linuxserver/radarr:6.4.4",
[
"radarr:compose-nodigest"
]
],
[
"lukevella/rallly:4.11.1",
[
"rallly:compose-nodigest"
]
],
[
"gitea.dooplex.hu/admin/recipe-importer:v0.9.11",
[
"recipe-importer:compose-nodigest"
]
],
[
"rommapp/romm:5.3.1",
[
"romm:compose-nodigest"
]
],
[
"fallenbagel/jellyseerr:2.7.3",
[
"seerr:compose-nodigest"
]
],
[
"lscr.io/linuxserver/sonarr:4.0.20",
[
"sonarr:compose-nodigest"
]
],
[
"postgres:15-alpine",
[
"sparkyfitness:compose-nodigest"
]
],
[
"codewithcj/sparkyfitness_server:v0.17.3",
[
"sparkyfitness:compose-nodigest"
]
],
[
"codewithcj/sparkyfitness:v0.17.3",
[
"sparkyfitness:compose-nodigest"
]
],
[
"ghcr.io/tandoorrecipes/recipes:2.6.15",
[
"tandoor:compose-nodigest"
]
],
[
"ghcr.io/lukegus/termix:2.8.0",
[
"termix:compose-nodigest"
]
],
[
"louislam/uptime-kuma:2.4.0",
[
"uptime-kuma:compose-nodigest"
]
],
[
"vaultwarden/server:1.36.0-alpine",
[
"vaultwarden:compose-nodigest"
]
],
[
"vikunja/vikunja:2.6.0",
[
"vikunja:compose-nodigest"
]
],
[
"flomp/wanderer-web:v0.20.0",
[
"wanderer:compose-nodigest"
]
],
[
"flomp/wanderer-db:v0.20.0",
[
"wanderer:compose-nodigest"
]
],
[
"getmeili/meilisearch:v1.36.0",
[
"wanderer:compose-nodigest"
]
],
[
"wger/server:2.6",
[
"wger:compose-nodigest"
]
],
[
"ghcr.io/cmintey/wishlist:v0.67.1",
[
"wishlist:compose-nodigest"
]
],
[
"ghcr.io/diced/zipline:4.6.1",
[
"zipline:compose-nodigest"
]
]
]
}
@@ -0,0 +1,42 @@
200 actualbudget/actual-server:26.9.0@sha256:552beab3dec8 actualbudget:ladder
200 ghcr.io/advplyr/audiobookshelf:2.36.1@sha256:3528a93b6442 audiobookshelf:ladder
200 lscr.io/linuxserver/bookstack:26.05.5@sha256:189c79627346 bookstack:ladder
200 mariadb:12.3@sha256:805c8e104bd5 bookstack:ladder,nextcloud:ladder
200 docmost/docmost:0.96.0@sha256:b56947fcfd08 docmost:ladder
200 postgres:16-alpine@sha256:721873c34ceb docmost:ladder,tandoor:ladder
200 redis:7-alpine@sha256:858f009f9709 docmost:ladder,immich:ladder,nextcloud:ladder,romm:ladder
200 postgres:18-alpine@sha256:77f585114c32 docmost:ladder
200 emby/embyserver:4.11.0.1@sha256:bcc54978db53 emby:ladder
200 emby/embyserver:4.11.0.3@sha256:2ff130d624a9 emby:ladder
200 ghost:6.64.0-alpine@sha256:47ecbe856dd0 ghost:ladder
200 ghost:6.65.0-alpine@sha256:65788e5e2c54 ghost:ladder
200 grafana/grafana:13.2.2@sha256:ac461fb352ab grafana:ladder
200 ghcr.io/home-assistant/home-assistant:2026.9.3@sha256:d89226851697 home-assistant:ladder
200 ghcr.io/immich-app/immich-machine-learning:v3.0.3@sha256:d76fe88b6928 immich:ladder
200 ghcr.io/immich-app/postgres:16-vectorchord0.4.3-pgvectors0.2.0@sha256:1a078b237c1d immich:ladder
200 ghcr.io/immich-app/immich-server:v3.2.2@sha256:79cc1623323d immich:ladder
200 ghcr.io/immich-app/immich-machine-learning:v3.2.2@sha256:60dfcf266a9e immich:ladder
200 kimai/kimai2:apache-2.57.0@sha256:efa66c5eadf9 kimai:ladder
200 mariadb:11.8@sha256:79d59758afc9 kimai:ladder,romm:ladder
200 gotson/komga:1.27.1@sha256:9cf102f5fb78 komga:ladder
200 ghcr.io/mealie-recipes/mealie:v3.27.0@sha256:ba24b8846238 mealie:ladder
200 ghcr.io/mealie-recipes/mealie:v3.28.0@sha256:8b02290f4d18 mealie:ladder
200 n8nio/n8n:2.40.5@sha256:9f693fd55655 n8n:ladder
200 n8nio/n8n:2.41.1@sha256:52f147bba979 n8n:ladder
200 n8nio/n8n:2.41.2@sha256:1419c3c665b0 n8n:ladder
200 deluan/navidrome:0.64.0@sha256:a384948b81bd navidrome:ladder
200 deluan/navidrome:0.64.1@sha256:df22d661b8d0 navidrome:ladder
200 nextcloud:34.0.1-apache@sha256:b52f7bc0e496 nextcloud:ladder
200 nextcloud:34.0.4-apache@sha256:a5ace30c695a nextcloud:ladder
200 ghcr.io/thomiceli/opengist:1.15@sha256:7edc91273ee7 opengist:ladder
200 ghcr.io/papra-hq/papra:26.6.2-rootless@sha256:a281cb44176d papra:ladder
200 privatebin/pdo:2.0.6@sha256:4c141b2326f8 privatebin:ladder
200 lscr.io/linuxserver/radarr:6.4.4@sha256:adb6c09d6b72 radarr:ladder
200 rommapp/romm:5.3.0@sha256:dc586cb3a2c7 romm:ladder
200 mariadb:11.4@sha256:70cc072b29b4 romm:ladder
200 rommapp/romm:5.3.1@sha256:0d66b4ea152a romm:ladder
200 lscr.io/linuxserver/sonarr:4.0.20@sha256:a5c1a5fecbef sonarr:ladder
200 ghcr.io/tandoorrecipes/recipes:2.6.15@sha256:2e759dd1478a tandoor:ladder
200 ghcr.io/lukegus/termix:2.8.0@sha256:25e8a0eb39f4 termix:ladder
200 vikunja/vikunja:2.6.0@sha256:417ada6f94e8 vikunja:ladder
200 ghcr.io/cmintey/wishlist:v0.67.1@sha256:4b89bfb5b57f wishlist:ladder
@@ -0,0 +1,40 @@
"""HEAD each ref@digest at its registry (anonymous token). HEAD is not a pull and does not count
against Docker Hub's pull limit. Prints one line per ref: status + registry answer."""
import json, sys, urllib.request, urllib.error, re
ACC = "application/vnd.oci.image.index.v1+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.manifest.v1+json"
def split(ref):
parts = ref.split("/")
if len(parts) == 1 or ("." not in parts[0] and ":" not in parts[0] and parts[0] != "localhost"):
reg, repo = "registry-1.docker.io", ref
if "/" not in repo: repo = "library/" + repo
else:
reg, repo = parts[0], "/".join(parts[1:])
if reg == "docker.io": reg = "registry-1.docker.io"
repo = repo.split(":")[0] if ":" in repo.split("/")[-1] else repo
return reg, repo
def head(reg, repo, dig, token=None):
req = urllib.request.Request(f"https://{reg}/v2/{repo}/manifests/{dig}", method="HEAD", headers={"Accept": ACC})
if token: req.add_header("Authorization", "Bearer " + token)
try:
with urllib.request.urlopen(req, timeout=20) as r:
return r.status, r.headers
except urllib.error.HTTPError as e:
return e.code, e.headers
def token_for(hdrs, repo):
a = hdrs.get("www-authenticate") or ""
m = dict(re.findall(r'(\w+)="([^"]*)"', a))
if "realm" not in m: return None
url = f'{m["realm"]}?service={m.get("service","")}&scope=repository:{repo}:pull'
with urllib.request.urlopen(url, timeout=20) as r:
d = json.load(r)
return d.get("token") or d.get("access_token")
data = json.load(open(sys.argv[1]))
for ref, dig, srcs in data["with_digest"]:
reg, repo = split(ref)
try:
st, h = head(reg, repo, dig)
if st == 401:
st, h = head(reg, repo, dig, token_for(h, repo))
print(f"{st}\t{ref}@{dig[:19]}\t{','.join(srcs)}", flush=True)
except Exception as e:
print(f"ERR\t{ref}@{dig[:19]}\t{e}", flush=True)
@@ -0,0 +1 @@
2026-09-26T08:15:42Z
@@ -0,0 +1,6 @@
# R-689 red-proof — without the guest-archive check (v0.134.0)
r689_golden_test.go:35: picked "local:backup/felhom-golden-0.236.0.tar.zst" — the restore test must prove a backup OF A GUEST
--- FAIL: TestR689_TheRestoreTestNeverPicksTheGolden (0.00s)
FAIL
FAIL gitea.dooplex.hu/admin/felhom-agent/internal/backup 0.008s
FAIL
@@ -0,0 +1,11 @@
# R-695 red-proofs (both pre-fix shapes)
kept_test.go:319: listing = [{App:nextcloud DisplayName:nextcloud Path:/tmp/TestR695_AnEmptyDatedKeptFolderIsNeverListed2050451612/001/drive/kept/nextcloud/2026-09-24_101010 Drive:/tmp/TestR695_AnEmptyDatedKeptFolderIsNeverListed2050451612/001/drive Kind:dated Date:2026-09-26 10:11:53.117696514 +0200 CEST SizeBytes:4 UnitDir: Marker:<nil>} {App:nextcloud DisplayName:nextcloud Path:/tmp/TestR695_AnEmptyDatedKeptFolderIsNeverListed2050451612/001/drive/kept/nextcloud/2026-09-25_141014 Drive:/tmp/TestR695_AnEmptyDatedKeptFolderIsNeverListed2050451612/001/drive Kind:dated Date:2026-09-26 10:11:53.117696514 +0200 CEST SizeBytes:0 UnitDir: Marker:<nil>}] — want only the folder that holds something
--- FAIL: TestR695_AnEmptyDatedKeptFolderIsNeverListed (0.01s)
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/stacks 0.015s
FAIL
r695_fb_singleflight_test.go:46: 6 syncs ran for 6 requests (1 running + 5 queued) — want 2: the running one and ONE that re-reads for the queue
--- FAIL: TestR695_QueuedSyncsCoalesceIntoOne (0.10s)
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/web 0.110s
FAIL
@@ -0,0 +1,8 @@
# R-691 red-proofs
r691_kept_view_test.go:42: groups = [], want [33 911]
--- FAIL: TestR691_KeptReadGroups (0.00s)
r691_kept_view_test.go:68: status 302, file-browser syncs 0 — want a redirect and one sync
--- FAIL: TestR691_ALanguageSwitchResyncsTheFileBrowser (0.06s)
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/web 0.075s
FAIL
@@ -0,0 +1,31 @@
# D4 — R-694: what the app page shows as the password after a load or a restore
**The case.** The unit never carries a `type: password` admin login (D5). A restore whose guest has no
app.yaml — "Use my kept data", the restore of a removed app, a rebuilt guest — generates a new value
(`generated replacement for [NEXTCLOUD_ADMIN_PASSWORD]`, `night-2026-09-26/E/E5-5-use.txt`). The app page then
showed that value in the disabled password field, with the hint „Telepítéskor beállított kezdeti jelszó".
**Measured per app (2026-09-26, from each image's entrypoint at the catalog's tag, read-only; sources in
`upstream/`; two claims re-checked by hand: nextcloud `installed_version = 0.0.0.0` gate, code-server `--auth`):**
| app | uses the env value | after such a restore the login is |
|---|---|---|
| code-server | every start (`PASSWORD` → `code-server --auth password`, nothing stored) | the NEW value (shown value works) |
| crafty-controller | admin created only on a fresh install (`installer.is_fresh_install()`) | the OLD password in the data |
| gokapi | template seeds `config.json` only if absent | OLD |
| grafana | "can be changed before first start" (`defaults.ini`) | OLD |
| kimai | `kimai:user:create` every start, but it only creates (unique username) | OLD |
| nextcloud | only inside `if installed_version = 0.0.0.0` (first install) | OLD |
| paperless-ngx | `manage_superuser` skips when the user / a superuser exists | OLD |
**So the shown value was a password that does not work for six of the seven apps.** Not measured live (no
per-app deploy/remove/load cycle); the verdicts are from the upstream sources, confidence high per the table.
**Fix (controller v0.275.0).** `PersistUnitRedeployConfig` (the restore's app.yaml write) records in
`restored_logins` the `type: password` fields the guest held no value for before the write — i.e. the ones the
restore generated — except those in the code register `loginAppliedEveryStart` (code-server `PASSWORD`). The page
renders no value for them and says: „Mentésből töltötted vissza: a belépéshez a mentés idején érvényes jelszavad
kell. Az itt tárolt érték nem az, ezért nem mutatjuk." / "Restored from a backup: log in with the password that
was valid when the backup was taken. The value stored here is not it, so it is not shown." Tests:
`TestR694_ARestoreThatGeneratesTheLoginRecordsIt` (production write, 3 cases, red-proofed `RP-r694.txt`),
`TestR694_TheDeployPageDoesNotOfferAGeneratedLogin` (both languages; the Hungarian parity fixtures unchanged).
@@ -0,0 +1,9 @@
# R-694 red-proof
r694_restored_login_test.go:53: restored_logins = [], want noted=true
--- FAIL: TestR694_ARestoreThatGeneratesTheLoginRecordsIt (0.01s)
--- FAIL: TestR694_ARestoreThatGeneratesTheLoginRecordsIt/nextcloud,_guest_app.yaml_gone (0.00s)
--- PASS: TestR694_ARestoreThatGeneratesTheLoginRecordsIt/nextcloud,_guest_kept_the_household's_value (0.00s)
--- PASS: TestR694_ARestoreThatGeneratesTheLoginRecordsIt/code-server_applies_the_env_at_every_start (0.00s)
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/stacks 0.016s
FAIL
@@ -0,0 +1,71 @@
#!/bin/sh
repair_permissions () {
printf "\033[36mWrapper | \033[35m📋 (1/3) Ensuring root group ownership...\033[0m\n"
find . ! -group root -print0 | xargs -0 -r chgrp root
printf "\033[36mWrapper | \033[35m📋 (2/3) Ensuring group read-write is present on files...\033[0m\n"
find . ! -perm g+rw -print0 | xargs -0 -r chmod g+rw
printf "\033[36mWrapper | \033[35m📋 (3/3) Ensuring sticky bit is present on directories...\033[0m\n"
find . -type d ! -perm g+s -print0 | xargs -0 -r chmod g+s
}
# Notify SteamCMD platform availability based on architecture
case "$(uname -m)" in
x86_64|amd64)
printf "\033[36mWrapper | \033[32m🚂✅ SteamCMD dependencies are available in this image!\033[0m\n"
;;
*)
printf "\033[36mWrapper | \033[33m⚠️ SteamCMD is only available on amd64/x86_64 images.\033[0m\n"
printf "\033[36mWrapper | \033[33m Detected architecture: %s. SteamCMD features are disabled.\033[0m\n" "$(uname -m)"
;;
esac
# Check if config exists taking one from image if needed.
if [ ! "$(ls -A --ignore=.gitkeep ./app/config)" ]; then
printf "\033[36mWrapper | \033[33m🏗️ Config not found, pulling defaults...\033[0m\n"
mkdir ./app/config/ 2> /dev/null
cp -r ./app/config_original/* ./app/config/
if [ $(id -u) -eq 0 ]; then
# We're running as root;
# Look for files & dirs that require group permissions to be fixed
# This will do the full /crafty dir, so will take a miniute.
printf "\033[36mWrapper | \033[35m📋 Looking for problem bind mount permissions globally...\033[0m\n"
repair_permissions
printf "\033[36mWrapper | \033[32m✅ Initialization complete!\033[0m\n"
fi
else
# Keep version file up to date with image
cp -f ./app/config_original/version.json ./app/config/version.json
fi
if [ $(id -u) -eq 0 ]; then
# We're running as root
# If we find files in import directory, we need to ensure all dirs are owned by the root group,
# This fixes bind mounts that may have incorrect perms.
if [ "$(find ./import -type f ! -name '.gitkeep')" ]; then
printf "\033[36mWrapper | \033[35m📋 Files present in import directory, checking/fixing permissions...\033[0m\n"
printf "\033[36mWrapper | \033[33m⏳ Please be patient for larger servers...\033[0m\n"
repair_permissions
printf "\033[36mWrapper | \033[32m✅ Permissions Fixed! (This will happen every boot until /import is empty!)\033[0m\n"
fi
# Switch user, activate our prepared venv and launch crafty
args="$@"
printf "\033[36mWrapper | \033[32m🚀 Launching crafty with [\033[34m%s\033[32m]\033[0m\n" "$args"
exec sudo -u crafty bash -c "source ./.venv/bin/activate && exec python3 main.py $args"
else
# Activate our prepared venv
printf "\033[36mWrapper | \033[32m🚀 Non-root host detected, using normal exec\033[0m\n"
. ./.venv/bin/activate
# Use exec as our perms are already correct
# This is likely if using Kubernetes/OpenShift etc
exec python3 main.py "$@"
fi
@@ -0,0 +1,52 @@
#!/usr/bin/with-contenv bash
# shellcheck shell=bash
if [[ -n "${PASSWORD}" ]] || [[ -n "${HASHED_PASSWORD}" ]]; then
AUTH="password"
else
AUTH="none"
echo "starting with no password"
fi
if [[ -z ${PROXY_DOMAIN+x} ]]; then
PROXY_DOMAIN_ARG=""
else
PROXY_DOMAIN_ARG="--proxy-domain=${PROXY_DOMAIN}"
fi
if [[ -z ${PWA_APPNAME} ]]; then
PWA_APPNAME="code-server"
fi
if test -f /proc/net/if_inet6; then
BIND_ADDR="[::]:8443"
else
BIND_ADDR="0.0.0.0:8443"
fi
if [[ -z ${LSIO_NON_ROOT_USER} ]]; then
exec \
s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z 127.0.0.1 8443" \
s6-setuidgid abc \
/app/code-server/bin/code-server \
--bind-addr "${BIND_ADDR}" \
--user-data-dir /config/data \
--extensions-dir /config/extensions \
--disable-telemetry \
--auth "${AUTH}" \
--app-name "${PWA_APPNAME}" \
"${PROXY_DOMAIN_ARG}" \
"${DEFAULT_WORKSPACE:-/config/workspace}"
else
exec \
s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z 127.0.0.1 8443" \
/app/code-server/bin/code-server \
--bind-addr "${BIND_ADDR}" \
--user-data-dir /config/data \
--extensions-dir /config/extensions \
--disable-telemetry \
--auth "${AUTH}" \
--app-name "${PWA_APPNAME}" \
"${PROXY_DOMAIN_ARG}" \
"${DEFAULT_WORKSPACE:-/config/workspace}"
fi
@@ -0,0 +1,224 @@
package configuration
/**
Loading and saving of the persistent configuration
*/
import (
"bytes"
"crypto/sha1"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"github.com/forceu/gokapi/internal/configuration/cloudconfig"
"github.com/forceu/gokapi/internal/configuration/configupgrade"
"github.com/forceu/gokapi/internal/configuration/database"
"github.com/forceu/gokapi/internal/environment"
"github.com/forceu/gokapi/internal/helper"
log "github.com/forceu/gokapi/internal/logging"
"github.com/forceu/gokapi/internal/models"
"github.com/forceu/gokapi/internal/storage/filesystem"
"io"
"os"
"strings"
)
// MinLengthPassword is the required length of admin password in characters
const MinLengthPassword = 8
// Environment is an object containing the environment variables
var Environment environment.Environment
// ServerSettings is an object containing the server configuration
var serverSettings models.Configuration
var usesHttps bool
// Exists returns true if configuration files are present
func Exists() bool {
configPath, _, _, _ := environment.GetConfigPaths()
return helper.FileExists(configPath)
}
// loadFromFile parses the given file and adds salts, if they are invalid
func loadFromFile(path string) (models.Configuration, error) {
file, err := os.Open(path)
if err != nil {
return models.Configuration{}, err
}
decoder := json.NewDecoder(file)
settings := models.Configuration{}
err = decoder.Decode(&settings)
if err != nil {
return models.Configuration{}, err
}
err = file.Close()
if err != nil {
return models.Configuration{}, err
}
if len(settings.Authentication.SaltFiles) < 20 {
settings.Authentication.SaltFiles = helper.GenerateRandomString(30)
fmt.Println("Warning: Salt for file hash invalid, generating new salt")
}
if len(settings.Authentication.SaltAdmin) < 20 {
settings.Authentication.SaltAdmin = helper.GenerateRandomString(30)
if settings.Authentication.Method == 0 { // == authentication.Internal, but would create import cycle
fmt.Println("Warning: Salt for admin password invalid, generating new salt. You will need to reset the admin password.")
}
}
return settings, nil
}
// Load loads the configuration or creates the folder structure and a default configuration
func Load() {
Environment = environment.New()
// No check if file exists, as this was checked earlier
settings, err := loadFromFile(Environment.ConfigPath)
helper.Check(err)
serverSettings = settings
usesHttps = strings.HasPrefix(strings.ToLower(serverSettings.ServerUrl), "https://")
if configupgrade.DoUpgrade(&serverSettings, &Environment) {
save()
}
if serverSettings.PublicName == "" {
serverSettings.PublicName = "Gokapi"
}
if serverSettings.MaxParallelUploads == 0 {
serverSettings.MaxParallelUploads = 4
}
if serverSettings.ChunkSize == 0 {
serverSettings.ChunkSize = 45
}
helper.CreateDir(serverSettings.DataDir)
filesystem.Init(serverSettings.DataDir)
log.Init(Environment.DataDir)
}
// ConnectDatabase loads the database that is defined in the configuration
func ConnectDatabase() {
dbConfig, err := database.ParseUrl(serverSettings.DatabaseUrl, false)
helper.Check(err)
database.Connect(dbConfig)
database.Upgrade()
}
// UsesHttps returns true if Gokapi URL is set to a secure URL
func UsesHttps() bool {
return usesHttps
}
// Get returns a pointer to the server configuration
func Get() *models.Configuration {
return &serverSettings
}
// Save the configuration as a json file
func save() {
file, err := os.OpenFile(Environment.ConfigPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
fmt.Println("Error writing configuration:", err)
os.Exit(1)
}
defer file.Close()
_, err = io.Copy(file, bytes.NewReader(serverSettings.ToJson()))
if err != nil {
fmt.Println("Error writing configuration:", err)
os.Exit(1)
}
}
// LoadFromSetup creates a new configuration file after a user completed the setup. If cloudConfig is not nil, a new
// cloud config file is created. If it is nil an existing cloud config file will be deleted.
func LoadFromSetup(config models.Configuration, cloudConfig *cloudconfig.CloudConfig, e2eConfig End2EndReconfigParameters) {
Environment = environment.New()
helper.CreateDir(Environment.ConfigDir)
serverSettings = config
if cloudConfig != nil {
err := cloudconfig.Write(*cloudConfig)
if err != nil {
fmt.Println("Error writing cloud configuration:", err)
os.Exit(1)
}
} else {
err := cloudconfig.Delete()
if err != nil {
fmt.Println("Error deleting cloud configuration:", err)
os.Exit(1)
}
}
save()
Load()
ConnectDatabase()
database.DeleteAllSessions()
if e2eConfig.DeleteEnd2EndEncryption {
database.DeleteEnd2EndInfo()
}
if e2eConfig.DeleteEncryptedStorage {
deleteAllEncryptedStorage()
}
}
func deleteAllEncryptedStorage() {
files := database.GetAllMetadata()
for _, file := range files {
if file.Encryption.IsEncrypted {
file.UnlimitedTime = false
file.ExpireAt = 0
database.SaveMetaData(file)
}
}
}
// SetDeploymentPassword sets a new password. This should only be used for non-interactive deployment, but is not enforced
func SetDeploymentPassword(newPassword string) {
if len(newPassword) < MinLengthPassword {
fmt.Printf("Password needs to be at least %d characters long\n", MinLengthPassword)
os.Exit(1)
}
serverSettings.Authentication.SaltAdmin = helper.GenerateRandomString(30)
serverSettings.Authentication.Password = hashUserPassword(newPassword)
database.DeleteAllSessions()
save()
fmt.Println("New password has been set successfully")
os.Exit(0)
}
// HashPassword hashes a string with SHA1 the file salt or admin user salt
func HashPassword(password string, useFileSalt bool) string {
if useFileSalt {
return hashFilePassword(password)
}
return hashUserPassword(password)
}
func hashFilePassword(password string) string {
return HashPasswordCustomSalt(password, serverSettings.Authentication.SaltFiles)
}
func hashUserPassword(password string) string {
return HashPasswordCustomSalt(password, serverSettings.Authentication.SaltAdmin)
}
// HashPasswordCustomSalt hashes a password with SHA1 and the provided salt
func HashPasswordCustomSalt(password, salt string) string {
if password == "" {
return ""
}
if salt == "" {
panic(errors.New("no salt provided"))
}
pwBytes := []byte(password + salt)
hash := sha1.New()
hash.Write(pwBytes)
return hex.EncodeToString(hash.Sum(nil))
}
// End2EndReconfigParameters contains values on how to reset E2E, if requested
type End2EndReconfigParameters struct {
DeleteEnd2EndEncryption bool
DeleteEncryptedStorage bool
}
@@ -0,0 +1,102 @@
#!/bin/bash -x
KIMAI=$(cat /opt/kimai/version.txt)
echo $KIMAI
function waitForDB() {
# Parse sql connection data
DATABASE_USER=$(awk -F '[/:@]' '{print $4}' <<< "$DATABASE_URL")
DATABASE_PASS=$(awk -F '[/:@]' '{print $5}' <<< "$DATABASE_URL")
DATABASE_HOST=$(awk -F '[/:@]' '{print $6}' <<< "$DATABASE_URL")
DATABASE_PORT=$(awk -F '[/:@]' '{print $7}' <<< "$DATABASE_URL")
DATABASE_BASE=$(awk -F '[/?]' '{print $4}' <<< "$DATABASE_URL")
re='^[0-9]+$'
if ! [[ $DATABASE_PORT =~ $re ]] ; then
DATABASE_PORT=3306
fi
echo "Wait for database connection ..."
until php /dbtest.php "$DATABASE_HOST" "$DATABASE_BASE" "$DATABASE_PORT" "$DATABASE_USER" "$DATABASE_PASS"; do
echo Checking DB: $?
sleep 3
done
echo "Connection established"
}
function handleStartup() {
# set mem limits and copy in custom logger config
if [ -z "$memory_limit" ]; then
memory_limit=512M
fi
sed -i "s/memory_limit.*/memory_limit=$memory_limit/g" /usr/local/etc/php/php.ini
cp /assets/monolog.yaml /opt/kimai/config/packages/monolog.yaml
if [ -z "$USER_ID" ]; then
USER_ID=$(id -u www-data)
fi
if [ -z "$GROUP_ID" ]; then
GROUP_ID=$(id -g www-data)
fi
# if group doesn't exist
if grep -w "$GROUP_ID" /etc/group &>/dev/null; then
echo Group already exists
else
echo www-kimai:x:"$GROUP_ID": >> /etc/group
grpconv
fi
# if user doesn't exist
if id "$USER_ID" &>/dev/null; then
echo User already exists
else
echo www-kimai:x:"$USER_ID":"$GROUP_ID":www-kimai:/var/www:/usr/sbin/nologin >> /etc/passwd
pwconv
fi
if [ -e /use_apache ]; then
export APACHE_RUN_USER=$(id -nu "$USER_ID")
# This doesn't _exactly_ run as the specified GID, it runs as the GID of the specified user but WTF
export APACHE_RUN_GROUP=$(id -ng "$USER_ID")
export APACHE_PID_FILE=/var/run/apache2/apache2.pid
export APACHE_RUN_DIR=/var/run/apache2
export APACHE_LOCK_DIR=/var/lock/apache2
export APACHE_LOG_DIR=/var/log/apache2
export LANG=C
elif [ -e /use_fpm ]; then
sed -i "s/user = .*/user = $USER_ID/g" /usr/local/etc/php-fpm.d/www.conf
sed -i "s/group = .*/group = $GROUP_ID/g" /usr/local/etc/php-fpm.d/www.conf
echo "Setting fpm to run as ${USER_ID}:${GROUP_ID}"
else
echo "Error, unknown server type"
fi
}
function prepareKimai() {
# These are idempotent, so we can run them on every start-up
/opt/kimai/bin/console -n kimai:install
if [ ! -z "$ADMINPASS" ] && [ ! -a "$ADMINMAIL" ]; then
/opt/kimai/bin/console kimai:user:create admin "$ADMINMAIL" ROLE_SUPER_ADMIN "$ADMINPASS"
fi
echo "$KIMAI" > /opt/kimai/var/installed
echo "Kimai is ready"
}
function runServer() {
# Just while I'm fixing things
/opt/kimai/bin/console kimai:reload --env="$APP_ENV"
chown -R $USER_ID:$GROUP_ID /opt/kimai/var
if [ -e /use_apache ]; then
exec /usr/sbin/apache2 -D FOREGROUND
elif [ -e /use_fpm ]; then
exec php-fpm
else
echo "Error, unknown server type"
fi
}
waitForDB
handleStartup
prepareKimai
runServer
@@ -0,0 +1,330 @@
#!/bin/sh
set -eu
# version_greater A B returns whether A > B
version_greater() {
[ "$(printf '%s\n' "$@" | sort -t '.' -n -k1,1 -k2,2 -k3,3 -k4,4 | head -n 1)" != "$1" ]
}
# return true if specified directory is empty
directory_empty() {
[ -z "$(ls -A "$1/")" ]
}
run_as() {
if [ "$(id -u)" = 0 ]; then
su -p "$user" -s /bin/sh -c "$1"
else
sh -c "$1"
fi
}
# Execute all executable files in a given directory in alphanumeric order
run_path() {
local hook_folder_path="/docker-entrypoint-hooks.d/$1"
local found=0
echo "=> Searching for hook scripts (*.sh) to run, located in the folder \"${hook_folder_path}\""
if ! [ -d "${hook_folder_path}" ] || directory_empty "${hook_folder_path}"; then
echo "==> Skipped: the \"$1\" folder is empty (or does not exist)"
return 0
fi
find "${hook_folder_path}" -maxdepth 1 -iname '*.sh' '(' -type f -o -type l ')' -print | sort | (
while read -r script_file_path; do
if ! [ -x "${script_file_path}" ]; then
echo "==> The script \"${script_file_path}\" was skipped, because it lacks the executable flag"
continue
fi
echo "==> Running the script (cwd: $(pwd)): \"${script_file_path}\""
found=$((found+1))
run_as "${script_file_path}" || {
return_code="$?"
echo "==> Failed at executing script \"${script_file_path}\". Exit code: ${return_code}"
exit 1
}
echo "==> Finished executing the script: \"${script_file_path}\""
done
if [ "$found" -gt "0" ]; then
echo "=> Completed executing scripts in the \"$1\" folder"
else
echo "==> Skipped: the \"$1\" folder does not contain any valid scripts"
fi
)
}
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//")
local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//")
if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
if [ -n "${varValue}" ]; then
export "$var"="${varValue}"
elif [ -n "${fileVarValue}" ]; then
export "$var"="$(cat "${fileVarValue}")"
elif [ -n "${def}" ]; then
export "$var"="$def"
fi
unset "$fileVar"
}
get_enabled_apps() {
run_as 'php /var/www/html/occ app:list' \
| sed -n '/^Enabled:$/,/^Disabled:$/p' \
| sed '1d;$d' \
| sed -n 's/^ - \([^:]*\):.*/\1/p' \
| sort
}
# Write PHP session config for Redis to /usr/local/etc/php/conf.d/redis-session.ini
configure_redis_session() {
local redis_save_path
local redis_auth=''
echo "=> Configuring PHP session handler..."
if [ -z "${REDIS_HOST:-}" ]; then
echo "==> Using default PHP session handler"
return 0
fi
file_env REDIS_HOST_PASSWORD
case "$REDIS_HOST" in
/*)
redis_save_path="unix://${REDIS_HOST}"
;;
*)
redis_save_path="tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}"
;;
esac
if [ -n "${REDIS_HOST_PASSWORD+x}" ] && [ -n "${REDIS_HOST_USER+x}" ]; then
redis_auth="?auth[]=${REDIS_HOST_USER}&auth[]=${REDIS_HOST_PASSWORD}"
elif [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
redis_auth="?auth=${REDIS_HOST_PASSWORD}"
fi
echo "==> Using Redis as PHP session handler..."
{
echo 'session.save_handler = redis'
echo "session.save_path = \"${redis_save_path}${redis_auth}\""
echo "redis.session.locking_enabled = 1"
echo "redis.session.lock_retries = -1"
# redis.session.lock_wait_time is specified in microseconds.
# Wait 10ms before retrying the lock rather than the default 2ms.
echo "redis.session.lock_wait_time = 10000"
} > /usr/local/etc/php/conf.d/redis-session.ini
}
########################################################################
# Main
########################################################################
if expr "$1" : "apache" 1>/dev/null; then
if [ -n "${APACHE_DISABLE_REWRITE_IP+x}" ]; then
a2disconf remoteip
fi
fi
if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || [ "${NEXTCLOUD_UPDATE:-0}" -eq 1 ]; then
uid="$(id -u)"
gid="$(id -g)"
if [ "$uid" = '0' ]; then
case "$1" in
apache2*)
user="${APACHE_RUN_USER:-www-data}"
group="${APACHE_RUN_GROUP:-www-data}"
# strip off any '#' symbol ('#1000' is valid syntax for Apache)
user="${user#'#'}"
group="${group#'#'}"
;;
*) # php-fpm
user='www-data'
group='www-data'
;;
esac
else
user="$uid"
group="$gid"
fi
configure_redis_session
# If another process is syncing the html folder, wait for
# it to be done, then escape initalization.
(
if ! flock -n 9; then
# If we couldn't get it immediately, show a message, then wait for real
echo "Another process is initializing Nextcloud. Waiting..."
flock 9
fi
installed_version="0.0.0.0"
if [ -f /var/www/html/version.php ]; then
# shellcheck disable=SC2016
installed_version="$(php -r 'require "/var/www/html/version.php"; echo implode(".", $OC_Version);')"
fi
# shellcheck disable=SC2016
image_version="$(php -r 'require "/usr/src/nextcloud/version.php"; echo implode(".", $OC_Version);')"
if version_greater "$installed_version" "$image_version"; then
echo "Can't start Nextcloud because the version of the data ($installed_version) is higher than the docker image version ($image_version) and downgrading is not supported. Are you sure you have pulled the newest image version?"
exit 1
fi
if version_greater "$image_version" "$installed_version"; then
echo "Initializing nextcloud $image_version ..."
if [ "$installed_version" != "0.0.0.0" ]; then
if [ "${image_version%%.*}" -gt "$((${installed_version%%.*} + 1))" ]; then
echo "Can't start Nextcloud because upgrading from $installed_version to $image_version is not supported."
echo "It is only possible to upgrade one major version at a time. For example, if you want to upgrade from version 14 to 16, you will have to upgrade from version 14 to 15, then from 15 to 16."
exit 1
fi
echo "Upgrading nextcloud from $installed_version ..."
get_enabled_apps > /tmp/list_before
fi
if [ "$(id -u)" = 0 ]; then
rsync_options="-rlDog --chown $user:$group"
else
rsync_options="-rlD"
fi
rsync $rsync_options --delete --exclude-from=/upgrade.exclude /usr/src/nextcloud/ /var/www/html/
for dir in config data custom_apps themes; do
if [ ! -d "/var/www/html/$dir" ] || directory_empty "/var/www/html/$dir"; then
rsync $rsync_options --include "/$dir/" --exclude '/*' /usr/src/nextcloud/ /var/www/html/
fi
done
rsync $rsync_options --include '/version.php' --exclude '/*' /usr/src/nextcloud/ /var/www/html/
# Install
if [ "$installed_version" = "0.0.0.0" ]; then
echo "New nextcloud instance"
file_env NEXTCLOUD_ADMIN_PASSWORD
file_env NEXTCLOUD_ADMIN_USER
install=false
if [ -n "${NEXTCLOUD_ADMIN_USER+x}" ] && [ -n "${NEXTCLOUD_ADMIN_PASSWORD+x}" ]; then
# shellcheck disable=SC2016
install_options='-n --admin-user "$NEXTCLOUD_ADMIN_USER" --admin-pass "$NEXTCLOUD_ADMIN_PASSWORD"'
if [ -n "${NEXTCLOUD_DATA_DIR+x}" ]; then
# shellcheck disable=SC2016
install_options=$install_options' --data-dir "$NEXTCLOUD_DATA_DIR"'
fi
file_env MYSQL_DATABASE
file_env MYSQL_PASSWORD
file_env MYSQL_USER
file_env POSTGRES_DB
file_env POSTGRES_PASSWORD
file_env POSTGRES_USER
if [ -n "${SQLITE_DATABASE+x}" ]; then
echo "Installing with SQLite database"
# shellcheck disable=SC2016
install_options=$install_options' --database-name "$SQLITE_DATABASE"'
install=true
elif [ -n "${MYSQL_DATABASE+x}" ] && [ -n "${MYSQL_USER+x}" ] && [ -n "${MYSQL_PASSWORD+x}" ] && [ -n "${MYSQL_HOST+x}" ]; then
echo "Installing with MySQL database"
# shellcheck disable=SC2016
install_options=$install_options' --database mysql --database-name "$MYSQL_DATABASE" --database-user "$MYSQL_USER" --database-pass "$MYSQL_PASSWORD" --database-host "$MYSQL_HOST"'
install=true
elif [ -n "${POSTGRES_DB+x}" ] && [ -n "${POSTGRES_USER+x}" ] && [ -n "${POSTGRES_PASSWORD+x}" ] && [ -n "${POSTGRES_HOST+x}" ]; then
echo "Installing with PostgreSQL database"
# shellcheck disable=SC2016
install_options=$install_options' --database pgsql --database-name "$POSTGRES_DB" --database-user "$POSTGRES_USER" --database-pass "$POSTGRES_PASSWORD" --database-host "$POSTGRES_HOST"'
install=true
fi
if [ "$install" = true ]; then
run_path pre-installation
echo "Starting nextcloud installation"
max_retries=10
try=0
until [ "$try" -gt "$max_retries" ] || run_as "php /var/www/html/occ maintenance:install $install_options"
do
echo "Retrying install..."
try=$((try+1))
sleep 10s
done
if [ "$try" -gt "$max_retries" ]; then
echo "Installing of nextcloud failed!"
exit 1
fi
if [ -n "${NEXTCLOUD_TRUSTED_DOMAINS+x}" ]; then
echo "Setting trusted domains…"
set -f # turn off glob
NC_TRUSTED_DOMAIN_IDX=1
for DOMAIN in ${NEXTCLOUD_TRUSTED_DOMAINS}; do
DOMAIN=$(echo "${DOMAIN}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
run_as "php /var/www/html/occ config:system:set trusted_domains $NC_TRUSTED_DOMAIN_IDX --value=\"${DOMAIN}\""
NC_TRUSTED_DOMAIN_IDX=$((NC_TRUSTED_DOMAIN_IDX+1))
done
set +f # turn glob back on
fi
run_path post-installation
fi
fi
# not enough specified to do a fully automated installation
if [ "$install" = false ]; then
echo "Next step: Access your instance to finish the web-based installation!"
echo "Hint: You can specify NEXTCLOUD_ADMIN_USER and NEXTCLOUD_ADMIN_PASSWORD and the database variables _prior to first launch_ to fully automate initial installation."
fi
# Upgrade
else
run_path pre-upgrade
run_as 'php /var/www/html/occ upgrade'
get_enabled_apps > /tmp/list_after
disabled_apps="$(comm -23 /tmp/list_before /tmp/list_after || true)"
if [ -n "$disabled_apps" ]; then
echo "The following apps have been disabled:"
printf '%s\n' "$disabled_apps"
fi
rm -f /tmp/list_before /tmp/list_after
run_path post-upgrade
fi
echo "Initializing finished"
fi
# Update htaccess after init if requested
if [ -n "${NEXTCLOUD_INIT_HTACCESS+x}" ] && [ "$installed_version" != "0.0.0.0" ]; then
run_as 'php /var/www/html/occ maintenance:update:htaccess'
fi
) 9> /var/www/html/nextcloud-init-sync.lock
# warn if config files on persistent storage differ from the latest version of this image
for cfgPath in /usr/src/nextcloud/config/*.php; do
cfgFile=$(basename "$cfgPath")
if [ "$cfgFile" != "config.sample.php" ] && [ "$cfgFile" != "autoconfig.php" ]; then
if ! cmp -s "/usr/src/nextcloud/config/$cfgFile" "/var/www/html/config/$cfgFile"; then
echo "Warning: /var/www/html/config/$cfgFile differs from the latest version of this image at /usr/src/nextcloud/config/$cfgFile"
fi
fi
done
run_path before-starting
fi
exec "$@"
@@ -0,0 +1,66 @@
import logging
import os
from argparse import RawTextHelpFormatter
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
logger = logging.getLogger("paperless.management.superuser")
class Command(BaseCommand):
help = (
"Creates a Django superuser:\n"
" User named: admin\n"
" Email: root@localhost\n"
" Password: based on env variable PAPERLESS_ADMIN_PASSWORD\n"
"No superuser will be created, when:\n"
" - The username is taken already exists\n"
" - A superuser already exists\n"
" - PAPERLESS_ADMIN_PASSWORD is not set"
)
def create_parser(self, *args, **kwargs):
parser = super().create_parser(*args, **kwargs)
parser.formatter_class = RawTextHelpFormatter
return parser
def handle(self, *args, **options):
username = os.getenv("PAPERLESS_ADMIN_USER", "admin")
mail = os.getenv("PAPERLESS_ADMIN_MAIL", "root@localhost")
password = os.getenv("PAPERLESS_ADMIN_PASSWORD")
# Check if there's already a user called admin
if User.objects.filter(username=username).exists():
self.stdout.write(
self.style.NOTICE(
f"Did not create superuser, a user {username} already exists",
),
)
return
# Check if any superuseruser
# exists already, leave as is if it does
if User.objects.filter(is_superuser=True).count() > 0:
self.stdout.write(
self.style.NOTICE(
"Did not create superuser, the DB already contains superusers",
),
)
return
if password is None:
self.stdout.write(
self.style.ERROR(
"Please check if PAPERLESS_ADMIN_PASSWORD has been"
" set in the environment",
),
)
else:
# Create superuser with password based on env variable
User.objects.create_superuser(username, mail, password)
self.stdout.write(
self.style.SUCCESS(
f'Created superuser "{username}" with provided password.',
),
)
@@ -0,0 +1,20 @@
#!/command/with-contenv /usr/bin/bash
# shellcheck shell=bash
declare -r log_prefix="[init-superuser]"
if [[ -n "${PAPERLESS_ADMIN_USER}" ]]; then
echo "${log_prefix} Creating superuser..."
cd "${PAPERLESS_SRC_DIR}"
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
python3 manage.py manage_superuser
else
s6-setuidgid paperless python3 manage.py manage_superuser
fi
echo "${log_prefix} Superuser creation done"
else
echo "${log_prefix} Not creating superuser"
fi
@@ -11,7 +11,7 @@ import json, os, sys, time
import walk as w, fixtures
APP, SUB = "docmost", "c-docs"
OUT_DIR = f"{w.EV}/A1"
OUT_DIR = f"{w.EV}/" + os.environ.get("A1OUT", "A1")
os.makedirs(OUT_DIR, exist_ok=True)
TOK = w.SC + "/seed-tokens.json"
@@ -0,0 +1,56 @@
"""a5live.py <step> — Part A's live proof on 9202 (0.275.0-rc1, drill catalog), through the buttons' endpoints.
Output lands in A5-live/ (a1.py's helpers with A1OUT=A5-live)."""
import os, sys, json, time, subprocess
os.environ["A1OUT"] = "A5-live"
import walk as w, a1
D = "/mnt/5_hdd/felhom.eu/drill/app-catalog-drill"
LIVE = "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu"
def drill(msg, compose_from_rev=None, revert=False):
subprocess.run(["git", "-C", D, "pull", "-q", "--rebase", "origin", "main"], check=True)
if revert:
subprocess.run(["git", "-C", D, "revert", "--no-edit", "HEAD"], check=True, capture_output=True)
else:
body = subprocess.run(["git", "-C", LIVE, "show", compose_from_rev + ":templates/docmost/docker-compose.yml"], check=True, capture_output=True, text=True).stdout
open(D + "/templates/docmost/docker-compose.yml", "w").write(body)
subprocess.run(["git", "-C", D, "commit", "-q", "-am", msg], check=True)
subprocess.run(["git", "-C", D, "push", "-q", "origin", "main"], check=True, capture_output=True)
print("drill:", subprocess.run(["git", "-C", D, "log", "--oneline", "-1"], capture_output=True, text=True).stdout.strip())
def wait_refresh(expect, label, cap=600):
t0 = time.time()
while time.time() - t0 < cap:
out = w.guest("grep -A3 '\"image_pins\"' /mnt/sys_drive/felhom-data/backups/primary/docmost/manifest.json | head -4; date -u +%T")
if expect in out:
print(f"{label}: manifest image_pins now carry {expect} at {out.split()[-1]}")
return True
time.sleep(20)
print(f"{label}: no refresh with {expect} within {cap}s"); return False
def press(label):
r = w.press_update("docmost", poll=1)
json.dump(r, open(f"{w.EV}/A5-live/{label}.json", "w"), indent=1, default=str)
print(label, {k: v for k, v in r.items() if k != "phases"})
return r
if __name__ == "__main__":
w.login()
step = sys.argv[1]
if step == "deploy095":
drill("LIVE A5: docmost deployable at 0.95.0 / postgres 16 (reverted after the deploy)", "a2115b2")
w.sync_rescan("docmost", "docmost/docmost:0.95.0")
print(w.deploy("docmost", "c-docs"))
a1.seed("L1-deployed"); a1.read("L1-deployed")
drill(None, revert=True)
w.sync_rescan("docmost", "postgres:18-alpine")
a1.unit("L1-deployed")
elif step == "press":
w.sync_rescan("docmost", "postgres:18-alpine")
press(sys.argv[2]); a1.unit(sys.argv[2])
elif step == "refresh":
wait_refresh(sys.argv[3], sys.argv[2]); a1.unit(sys.argv[2])
elif step == "restore":
a1.restore(sys.argv[2], tier2=len(sys.argv) > 3); a1.read(sys.argv[2]); a1.unit(sys.argv[2])
code, d = w.ctl("GET", "/api/backup/restore-status")
open(f"{w.EV}/A5-live/{sys.argv[2]}.txt", "a").write("restore-status (the page's sentence): " + json.dumps(d.get("data"), ensure_ascii=False) + "\n")
print(json.dumps((d.get("data") or {}).get("last"), ensure_ascii=False))
+1
View File
@@ -816,6 +816,7 @@ class (an image `VOLUME` at an unmounted path) is still live — `immich-server`
| **R-695** | **[P3-LOW] Two kept-data Deletes in the same second can leave a self-perpetuating empty kept folder.** Seen 2026-09-25 on 9202 (v0.274.0, teardown): two Deletes at 13:35:16 each started `SyncFileBrowserMounts` in a goroutine; one restarted the file browser with the OLD bind list, Docker recreated the deleted folder `kept/nextcloud/2026-09-25_141014` EMPTY (root, 13:35:17), and the next sync LISTED that empty folder as a kept item and kept binding it — so the bind recreated the folder and the folder kept the bind. Broken by removing the folder and one controller restart. Harm: an empty 0-byte row and a stale empty source in the view; no data. **Fix direction:** single-flight the file-browser sync (the second waits and re-reads), and never list or bind an EMPTY dated kept folder. `audits/night-2026-09-26/G/T1-teardown-9202.txt` | **OPEN — P3; owner: CC** |
| **R-696** | **[P2-MEDIUM] Tier 1's "proven at" is the unit MANIFEST's refresh time, not its data's — so the kept pre-conversion copy was released on a backup taken BEFORE the conversion.** Seen 2026-09-26 on demo-hp (v0.274.0, the automatic leg): docmost converted 16 → 18 at 02:18:52Z; at 02:20:16Z the recovery unit was re-captured (its pins changed) — `manifest.json` `created_at` 02:20:16Z — while its `db-dumps/docmost-postgres.sql` is from **02:15:01Z, on PostgreSQL 16**. `UpdateRestorePoints` reads Tier 1's time from `ListRestorePoints` (the unit's time), so at 02:30:16Z `ReleaseConversionCopies` logged "a backup proven on 18: Tier 1 at 02:20:16Z" and removed the 16 datadir copy. **Harm tonight: low** — the 02:15 logical dump holds the rows the conversion's check proved equal, and the next night's dump is on 18. **The class is wider:** the update's own precondition reads the same time, and a unit is re-captured on every controller release or pin change (`CaptureRecoveryUnit`), so a stale dump can read as minutes old (9202 2026-09-25 11:06: "Tier 1 copy 2m0s old" from the 11:04 restart, dumps older). On 9202 the release was right by luck (dump 11:57 > conversion 11:13). **Fix direction:** Tier 1's time = the newest DATA in the unit (its db/volume dumps' own times), never the manifest's; the release additionally requires a dump of the converted service written after the conversion. Presence-is-not-success, `CLAUDE.md`. `audits/night-2026-09-26/G/G4-demo-hp-docmost-after.txt` **-- A1 SPIKE 2026-09-26 (9202, controller 0.274.0, `audits/version-travel-2026-09-26/A1/README.md`) — the class is WIDER than the time: the refresh re-captures the unit's DEFINITION too, so the unit pairs new pins with old data.** Measured both shapes: an app step (docmost 0.95.0 → 0.96.0) — the refresh 2 min after the update wrote 0.96.0 into `compose/` over 0.95.0's dump; a restore in that window came back whole only because docmost migrated the old data forward at its first start (four migrations, no guard, no undo). An engine step (PostgreSQL 16 → 18) — the refresh wrote the 18 definition over the 16 dump and 16 datadir tar; a restore in that window poured the 16 datadir back, `postgres:18` REFUSED it, the replay timed out and **the app was left DOWN**. The second-drive mirror, written before the update, brought it back whole at 16. From source: the OFF-SITE restore never writes the definition at all (it uses the live compose), so after any update it mixes versions until the next night's off-site run. Being fixed as Part A of the version-travel brief (controller v0.275.0). | **OPEN — P2; owner: CC** |
| **R-697** | **[P3-LOW] A restore drops the `conversion_copy` record but not the kept pre-conversion volume — the copy is then never released.** Seen 2026-09-26 on 9202 (A1, controller 0.274.0): after docmost's 16 → 18 conversion `app.yaml` held `conversion_copy` (`docmost_docmost_postgres_data.pre-update-20260926T073003Z`); a restore from the own unit, then one from the second drive, both left `conversion_copy=None` while the volume stayed. `PersistUnitRedeployConfig` builds a fresh `AppConfig` (Deployed, DeployedAt, Env, LockedFields), so every record kept beside the env is dropped by a restore — the hourly release reads the record, so the volume is orphaned. **Harm: disk only** (the size of the old datadir), never data. **Fix direction:** carry `conversion_copy` across the restore's app.yaml rewrite (the release then removes it when a backup on the new major is proven), and say in the log when a restore supersedes one. `audits/version-travel-2026-09-26/A1/S4-restore-window-step2.txt`, `S5-restore-tier2-window.txt` | **OPEN — P3; owner: CC** |
| **R-698** | **[P3-LOW] A backup stores the image's NAME, not the image — a restore of a version its maker has deleted cannot start.** `RecoveryManifest.image_pins` ("image NOT stored — re-pulled on restore"); since controller v0.275.0 each data file also records its running `ref@digest`, and a restore brings the data back AT ITS OWN VERSION (`07` §6.6) — so a restore asks for exactly the old image. **Measured 2026-09-26** (`audits/version-travel-2026-09-26/A7/`, registry HEADs, no pulls): the catalog's 42 ladder `ref@digest` pairs all resolve (200); an invented digest answers 404 on Docker Hub and ghcr.io (negative control). Not measured: the digests recorded on boxes (older than any ladder entry), how often makers delete versions, the catalog's 66 digest-less compose lines. **Options (decide nothing yet):** (a) keep — a restore of a deleted version fails at the pull and the household uses the next copy or a newer version; (b) mirror every INSTALLED image into the DooPlex registry, restore falls back to it — storage + bandwidth on DooPlex, a new part on the recovery path; (c) mirror only ladder-named versions — bounded, misses pre-ladder boxes; (d) `docker save` into the unit — hundreds of MB per app per copy on every tier. | **OPEN — P3; owner: operator (a decision), CC measures** |
<!-- DUE-CHECKS-BEGIN — machine-readable. Parsed by scripts/due_checks_gate.py.
One row per dated check. The R-number must have a row above. Dates are UTC.