persistence sweep: 53 templates measured; gramps-web + wishlist fixed; runtime gate added

Campaign 10's R-156 found papra writing its database into the container's writable layer while the
volume the template preserves stayed empty — a backup that completes, verifies, and contains
nothing. papra was never the point: nothing anywhere checked that the folder a template preserves
is the folder the app writes to. All 53 templates have now been measured live.

43 CLEAN / 3 BROKEN / 7 UNDETERMINED. UNDETERMINED is counted separately, each with its reason,
and never folded into CLEAN.

FIXED (neither app is deployed anywhere, so nothing was stranded):
- gramps-web mounted /app/data, /app/media, /tmp — and /app/data is a path the application never
  writes. Its accounts database and ITS FAMILY TREE both landed in the writable layer while
  gramps_data was tarred nightly as an empty directory. Now persists the eight paths the image's
  own environment names, matching upstream's reference compose. Proven: users.sqlite and the
  family-tree files survive a redeploy byte-identical, same inode.
- wishlist mounted wishlist_data:/data, another path the app never writes; prod.db landed in the
  ANONYMOUS volume from the image's VOLUME directive — absent from ResolveDockerVolumeNames, so
  never backed up, and orphaned by a redeploy. Now mounts /usr/src/app/data + /usr/src/app/uploads.
  Proven: prod.db byte-identical, same inode, across a redeploy.

Every corrected path confirmed by two independent sources — the shipped image's own
environment/Config.Volumes and upstream's reference compose — never inferred from a directory name.

papra is NOT fixed. It is live on one box, and changing the mount target makes the next compose up
recreate the container and destroy the writable layer its documents live in. The fix is prepared
and proven in the scratch guest (current: db.sqlite differs after a redeploy, so a real account
created via the API is lost; fixed: byte-identical, it survives). Referred to the operator with the
two options; no migration written.

NEW GATE scripts/check-volume-persistence.py — the third catalog gate and the only RUNTIME one.
This class is invisible to static analysis, measured not assumed: a static audit of all 53 composes
reports the catalog clean AND reports papra clean. Exit 0 clean / 1 REFUSED / 2 undecided. It
refuses to report at all unless it has just re-proven itself in both directions against two canary
templates that differ only in which path the volume mounts at, so every run carries a live
demonstration of R-156 and of its fix. No docker exec anywhere (Campaign 7 §1.1). 44 fixture tests
driving check(), the function __main__ calls; every rule red-proofed.

Enforcement is convention, not CI — this repo has no CI. Stated plainly in the report; raising it
is proposed as R-160.

Report, per-app evidence, proofs and proposed register entries (R-158..R-161, NOT filed — felhom.eu
is fenced this session): audits/persistence-sweep-2026-08-02/
This commit is contained in:
2026-08-02 12:21:30 +02:00
parent 4252121519
commit 2b22a23d60
92 changed files with 29956 additions and 53 deletions
@@ -0,0 +1,54 @@
{
"probe": {
"app": "actualbudget",
"containers": [
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "actualbudget/actual-server:26.7.0",
"mounts": [
{
"class": "named-declared",
"files": 2,
"name": "volgate-actualbudget_actualbudget_data",
"sample": [
".migrate",
"server-files/account.sqlite"
],
"source": "/var/lib/docker/volumes/volgate-actualbudget_actualbudget_data/_data",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "actualbudget",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"actualbudget_data"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,222 @@
{
"probe": {
"app": "adventurelog",
"containers": [
{
"diff_added": 8,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 3,
"db_signature": false,
"dir": "/",
"files": [
"run",
"var",
"code"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/var",
"files": [
"lib"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/var/lib",
"files": [
"nginx"
]
}
],
"diff_token_dirs": [],
"diff_total": 14,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/seanmorley15/adventurelog-backend:v0.12.1",
"mounts": [
{
"class": "named-declared",
"files": 251,
"name": "volgate-adventurelog_adventurelog_media",
"sample": [
"countries+regions+states-v3.1.json",
"flags/ca.png",
"flags/gg.png",
"flags/at.png",
"flags/ck.png",
"flags/eh.png",
"flags/qa.png",
"flags/lc.png",
"flags/io.png",
"flags/es.png",
"flags/gf.png",
"flags/tz.png",
"flags/mx.png",
"flags/vi.png",
"flags/tw.png",
"flags/il.png",
"flags/mk.png",
"flags/bo.png",
"flags/sa.png",
"flags/ly.png",
"flags/bb.png",
"flags/kg.png",
"flags/hr.png",
"flags/tn.png",
"flags/bj.png",
"flags/sh.png",
"flags/eg.png",
"flags/kw.png",
"flags/gn.png",
"flags/vg.png",
"flags/af.png",
"flags/jm.png",
"flags/ug.png",
"flags/je.png",
"flags/ms.png",
"flags/nl.png",
"flags/lv.png",
"flags/pg.png",
"flags/lr.png",
"flags/bl.png"
],
"source": "/var/lib/docker/volumes/volgate-adventurelog_adventurelog_media/_data",
"target": "/code/media",
"writable_by_app": "yes"
}
],
"name": "adventurelog",
"restarts": null,
"status": "running",
"uid": 0
},
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 65532,
"health": "healthy",
"image": "ghcr.io/seanmorley15/adventurelog-frontend:v0.12.1",
"mounts": [],
"name": "adventurelog-frontend",
"restarts": null,
"status": "running",
"uid": 65532
},
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 70,
"health": "healthy",
"image": "postgis/postgis:16-3.5-alpine",
"mounts": [
{
"class": "named-declared",
"files": 2287,
"name": "volgate-adventurelog_adventurelog_postgres_data",
"sample": [
"postmaster.opts",
"postgresql.conf",
"postgresql.auto.conf",
"pg_ident.conf",
"pg_hba.conf",
"postmaster.pid",
"PG_VERSION",
"base/1/826",
"base/1/2996",
"base/1/3764",
"base/1/2610_fsm",
"base/1/3603_fsm",
"base/1/1249_vm",
"base/1/3600_fsm",
"base/1/13512",
"base/1/3602",
"base/1/6228",
"base/1/4174",
"base/1/4157",
"base/1/4146",
"base/1/2611",
"base/1/2657",
"base/1/3079_vm",
"base/1/1247_vm",
"base/1/1259",
"base/1/3601_fsm",
"base/1/1417",
"base/1/4155",
"base/1/2668",
"base/1/2831",
"base/1/2841",
"base/1/3607",
"base/1/2836",
"base/1/1255_fsm",
"base/1/2615_vm",
"base/1/3575",
"base/1/2605_vm",
"base/1/2670",
"base/1/6106",
"base/1/4163"
],
"source": "/var/lib/docker/volumes/volgate-adventurelog_adventurelog_postgres_data/_data",
"target": "/var/lib/postgresql/data",
"writable_by_app": "yes"
}
],
"name": "adventurelog-postgres",
"restarts": null,
"status": "running",
"uid": 70
}
],
"declared_volumes": [
"adventurelog_media",
"adventurelog_postgres_data"
],
"env_keys": [
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SECRET_KEY",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,116 @@
{
"probe": {
"app": "audiobookshelf",
"containers": [
{
"diff_added": 4,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"metadata",
"audiobooks",
"podcasts",
"config"
],
"changed_count": 0,
"db_signature": false,
"dir": "/",
"files": [
"metadata",
"audiobooks",
"podcasts",
"config"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/advplyr/audiobookshelf:2.35.1",
"mounts": [
{
"class": "named-declared",
"files": 16,
"name": "volgate-audiobookshelf_audiobookshelf_config",
"sample": [
"absdatabase.sqlite",
"migrations/v2.17.5-remove-host-from-feed-urls.js",
"migrations/v2.17.4-use-subfolder-for-oidc-redirect-uris.js",
"migrations/v2.17.0-uuid-replacement.js",
"migrations/v2.19.1-copy-title-to-library-items.js",
"migrations/v2.15.0-series-column-unique.js",
"migrations/v2.19.4-improve-podcast-queries.js",
"migrations/v2.26.0-create-auth-tables.js",
"migrations/v2.33.0-add-discover-query-indexes.js",
"migrations/v2.17.7-add-indices.js",
"migrations/v2.35.0-add-last-refresh-token.js",
"migrations/v2.20.0-improve-author-sort-queries.js",
"migrations/v2.17.6-share-add-isdownloadable.js",
"migrations/v2.15.1-reindex-nocase.js",
"migrations/v2.17.3-fk-constraints.js",
"migrations/v2.15.2-index-creation.js"
],
"source": "/var/lib/docker/volumes/volgate-audiobookshelf_audiobookshelf_config/_data",
"target": "/config",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 1,
"name": "volgate-audiobookshelf_audiobookshelf_metadata",
"sample": [
"logs/daily/2026-08-02.txt"
],
"source": "/var/lib/docker/volumes/volgate-audiobookshelf_audiobookshelf_metadata/_data",
"target": "/metadata",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/hdd/userdata/media/audiobooks",
"target": "/audiobooks",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/hdd/userdata/media/podcasts",
"target": "/podcasts",
"writable_by_app": "yes"
}
],
"name": "audiobookshelf",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"audiobookshelf_config",
"audiobookshelf_metadata"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,70 @@
{
"probe": {
"app": "bentopdf",
"containers": [
{
"diff_added": 6,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/",
"files": [
"var",
"etc"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc",
"files": [
"nginx"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/var",
"files": [
"cache"
]
}
],
"diff_token_dirs": [],
"diff_total": 14,
"diff_unresolved": [],
"exit": 0,
"gid": 101,
"health": "healthy",
"image": "ghcr.io/alam00000/bentopdf:v2.8.6",
"mounts": [],
"name": "bentopdf",
"restarts": null,
"status": "running",
"uid": 101
}
],
"declared_volumes": [],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"nothing was written to any mount and nothing data-classified in any writable layer \u2014 the app produced no data to locate. Health is not data: this is UNDETERMINED, not CLEAN"
],
"verdict": "UNDETERMINED",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,246 @@
{
"probe": {
"app": "bookstack",
"containers": [
{
"diff_added": 247,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 6,
"db_signature": false,
"dir": "/",
"files": [
"app",
"etc",
"usr",
"defaults",
"run",
"var"
]
},
{
"added": [],
"changed_count": 5,
"db_signature": false,
"dir": "/etc",
"files": [
"passwd-",
"group-",
"crontabs",
"logrotate.d",
"s6-overlay"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/crontabs",
"files": [
"root"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/s6-overlay",
"files": [
"s6-rc.d"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/s6-overlay/s6-rc.d",
"files": [
"init-adduser"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/s6-overlay/s6-rc.d/init-adduser",
"files": [
"branding"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr",
"files": [
"lib"
]
},
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/var",
"files": [
"lib",
"log"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/var/lib",
"files": [
"nginx"
]
}
],
"diff_token_dirs": [],
"diff_total": 277,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "lscr.io/linuxserver/bookstack:26.05.2",
"mounts": [
{
"class": "named-declared",
"files": 20,
"name": "volgate-bookstack_bookstack_config",
"sample": [
".migrations",
"log/php/error.log",
"log/nginx/access.log",
"log/nginx/error.log",
"keys/cert.key",
"keys/cert.crt",
"php/www2.conf",
"php/php-local.ini",
"www/.env",
"www/index.html",
"www/framework/sessions/t9vuOg4XNVgyKgaD1xXXg5Bums6HCmTSiBGnhjPu",
"www/framework/sessions/GTO4GD6UJW2fK5ABAye7PVZKui376YILkTqU0I0e",
"nginx/resolver.conf",
"nginx/worker_processes.conf",
"nginx/nginx.conf.sample",
"nginx/nginx.conf",
"nginx/ssl.conf.sample",
"nginx/ssl.conf",
"nginx/site-confs/default.conf",
"nginx/site-confs/default.conf.sample"
],
"source": "/var/lib/docker/volumes/volgate-bookstack_bookstack_config/_data",
"target": "/config",
"writable_by_app": "yes"
}
],
"name": "bookstack",
"restarts": null,
"status": "running",
"uid": 0
},
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 999,
"health": "healthy",
"image": "mariadb:12.3",
"mounts": [
{
"class": "named-declared",
"files": 291,
"name": "volgate-bookstack_bookstack_db_data",
"sample": [
"undo002",
"tc.log",
"mariadb_upgrade_info",
"ibtmp1",
"aria_log.00000001",
"multi-master.info",
"ddl_recovery.log",
"ib_logfile0",
"undo003",
"ibdata1",
".my-healthcheck.cnf",
"aria_log_control",
"undo001",
"ib_buffer_pool",
"bookstack/api_tokens.ibd",
"bookstack/password_resets.ibd",
"bookstack/entity_page_data.frm",
"bookstack/settings.ibd",
"bookstack/email_confirmations.ibd",
"bookstack/views.ibd",
"bookstack/references.ibd",
"bookstack/attachments.frm",
"bookstack/entity_container_data.frm",
"bookstack/deletions.ibd",
"bookstack/permission_role.frm",
"bookstack/favourites.ibd",
"bookstack/deletions.frm",
"bookstack/page_revisions.ibd",
"bookstack/user_invites.frm",
"bookstack/joint_permissions.ibd",
"bookstack/bookshelves_books.frm",
"bookstack/activities.frm",
"bookstack/entity_container_data.ibd",
"bookstack/comments.ibd",
"bookstack/entity_permissions.frm",
"bookstack/email_confirmations.frm",
"bookstack/password_resets.frm",
"bookstack/settings.frm",
"bookstack/cache.ibd",
"bookstack/attachments.ibd"
],
"source": "/var/lib/docker/volumes/volgate-bookstack_bookstack_db_data/_data",
"target": "/var/lib/mysql",
"writable_by_app": "yes"
}
],
"name": "bookstack-db",
"restarts": null,
"status": "running",
"uid": 999
}
],
"declared_volumes": [
"bookstack_config",
"bookstack_db_data"
],
"env_keys": [
"APP_KEY",
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,177 @@
{
"probe": {
"app": "claper",
"containers": [
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"app"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app",
"files": [
"priv"
]
},
{
"added": [
"static"
],
"changed_count": 0,
"db_signature": false,
"dir": "/app/priv",
"files": [
"static"
]
},
{
"added": [
"uploads"
],
"changed_count": 0,
"db_signature": false,
"dir": "/app/priv/static",
"files": [
"uploads"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/claperco/claper:2.5",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-claper_claper_uploads",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-claper_claper_uploads/_data",
"target": "/app/priv/static/uploads",
"writable_by_app": "yes"
}
],
"name": "claper",
"restarts": null,
"status": "running",
"uid": 0
},
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 70,
"health": "healthy",
"image": "postgres:16-alpine",
"mounts": [
{
"class": "named-declared",
"files": 1470,
"name": "volgate-claper_claper_postgres_data",
"sample": [
"postmaster.opts",
"postgresql.conf",
"postgresql.auto.conf",
"pg_ident.conf",
"pg_hba.conf",
"postmaster.pid",
"PG_VERSION",
"base/1/826",
"base/1/2996",
"base/1/3764",
"base/1/2610_fsm",
"base/1/3603_fsm",
"base/1/1249_vm",
"base/1/3600_fsm",
"base/1/13512",
"base/1/3602",
"base/1/6228",
"base/1/4174",
"base/1/4157",
"base/1/4146",
"base/1/2611",
"base/1/2657",
"base/1/3079_vm",
"base/1/1247_vm",
"base/1/1259",
"base/1/3601_fsm",
"base/1/1417",
"base/1/4155",
"base/1/2668",
"base/1/2831",
"base/1/2841",
"base/1/3607",
"base/1/2836",
"base/1/1255_fsm",
"base/1/2615_vm",
"base/1/3575",
"base/1/2605_vm",
"base/1/2670",
"base/1/6106",
"base/1/4163"
],
"source": "/var/lib/docker/volumes/volgate-claper_claper_postgres_data/_data",
"target": "/var/lib/postgresql/data",
"writable_by_app": "yes"
}
],
"name": "claper-postgres",
"restarts": null,
"status": "running",
"uid": 70
}
],
"declared_volumes": [
"claper_postgres_data",
"claper_uploads"
],
"env_keys": [
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SECRET_KEY_BASE",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"claper: this container's mounts are all empty while it created entries in ['/app/priv', '/app/priv/static'] \u2014 benign when a sibling container holds the state, worth a look when none does",
"claper: declared volume /app/priv/static/uploads is EMPTY"
],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,110 @@
{
"probe": {
"app": "code-server",
"containers": [
{
"diff_added": 196,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 4,
"db_signature": false,
"dir": "/",
"files": [
"run",
"app",
"etc",
"defaults"
]
},
{
"added": [],
"changed_count": 3,
"db_signature": false,
"dir": "/etc",
"files": [
"passwd-",
"group-",
"s6-overlay"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/s6-overlay",
"files": [
"s6-rc.d"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/s6-overlay/s6-rc.d",
"files": [
"init-adduser"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/s6-overlay/s6-rc.d/init-adduser",
"files": [
"branding"
]
}
],
"diff_token_dirs": [],
"diff_total": 208,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "lscr.io/linuxserver/code-server:4.129.0",
"mounts": [
{
"class": "named-declared",
"files": 6,
"name": "volgate-codeserver_codeserver_config",
"sample": [
".profile",
".bashrc",
".config/code-server/config.yaml",
"data/code-server-ipc.sock",
".local/share/code-server/coder-logs/code-server-stderr.log",
".local/share/code-server/coder-logs/code-server-stdout.log"
],
"source": "/var/lib/docker/volumes/volgate-codeserver_codeserver_config/_data",
"target": "/config",
"writable_by_app": "yes"
}
],
"name": "code-server",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"codeserver_config"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"PASSWORD",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,217 @@
{
"probe": {
"app": "docmost",
"containers": [
{
"diff_added": 1,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"app"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app",
"files": [
"apps"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app/apps",
"files": [
"client"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app/apps/client",
"files": [
"dist"
]
},
{
"added": [
"index-template.html"
],
"changed_count": 1,
"db_signature": false,
"dir": "/app/apps/client/dist",
"files": [
"index-template.html"
]
}
],
"diff_token_dirs": [],
"diff_total": 6,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "docmost/docmost:0.95.0",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-docmost_docmost_storage",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-docmost_docmost_storage/_data",
"target": "/app/data/storage",
"writable_by_app": "yes"
}
],
"name": "docmost",
"restarts": null,
"status": "running",
"uid": 1000
},
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 70,
"health": "healthy",
"image": "postgres:16-alpine",
"mounts": [
{
"class": "named-declared",
"files": 1540,
"name": "volgate-docmost_docmost_postgres_data",
"sample": [
"postmaster.opts",
"postgresql.conf",
"postgresql.auto.conf",
"pg_ident.conf",
"pg_hba.conf",
"postmaster.pid",
"PG_VERSION",
"base/1/826",
"base/1/2996",
"base/1/3764",
"base/1/2610_fsm",
"base/1/3603_fsm",
"base/1/1249_vm",
"base/1/3600_fsm",
"base/1/13512",
"base/1/3602",
"base/1/6228",
"base/1/4174",
"base/1/4157",
"base/1/4146",
"base/1/2611",
"base/1/2657",
"base/1/3079_vm",
"base/1/1247_vm",
"base/1/1259",
"base/1/3601_fsm",
"base/1/1417",
"base/1/4155",
"base/1/2668",
"base/1/2831",
"base/1/2841",
"base/1/3607",
"base/1/2836",
"base/1/1255_fsm",
"base/1/2615_vm",
"base/1/3575",
"base/1/2605_vm",
"base/1/2670",
"base/1/6106",
"base/1/4163"
],
"source": "/var/lib/docker/volumes/volgate-docmost_docmost_postgres_data/_data",
"target": "/var/lib/postgresql/data",
"writable_by_app": "yes"
}
],
"name": "docmost-postgres",
"restarts": null,
"status": "running",
"uid": 70
},
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "redis:7-alpine",
"mounts": [
{
"class": "named-declared",
"files": 3,
"name": "volgate-docmost_docmost_redis_data",
"sample": [
"appendonlydir/appendonly.aof.1.base.rdb",
"appendonlydir/appendonly.aof.1.incr.aof",
"appendonlydir/appendonly.aof.manifest"
],
"source": "/var/lib/docker/volumes/volgate-docmost_docmost_redis_data/_data",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "docmost-redis",
"restarts": null,
"status": "running",
"uid": 999
}
],
"declared_volumes": [
"docmost_postgres_data",
"docmost_redis_data",
"docmost_storage"
],
"env_keys": [
"APP_SECRET",
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"docmost: this container's mounts are all empty while it created entries in ['/app/apps/client/dist'] \u2014 benign when a sibling container holds the state, worth a look when none does",
"docmost: declared volume /app/data/storage is EMPTY"
],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,119 @@
{
"probe": {
"app": "emby",
"containers": [
{
"diff_added": 205,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"config",
"media"
],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"config",
"media"
]
}
],
"diff_token_dirs": [],
"diff_total": 207,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "emby/embyserver:4.10.0.20",
"mounts": [
{
"class": "named-declared",
"files": 46,
"name": "volgate-emby_emby_config",
"sample": [
"cache/ffmpeg/filters_4.10.0.20.txt",
"cache/ffmpeg/version_4.10.0.20.txt",
"cache/ffmpeg/decoders_4.10.0.20.txt",
"cache/ffmpeg/encoders_4.10.0.20.txt",
"cache/ffmpeg/protocols_4.10.0.20.txt",
"cache/ffmpeg/hwaccels_4.10.0.20.txt",
"cache/httpclient/0fb243ded9649ae6d18059c674a4ae00_1",
"config/system.xml",
"config/users/a7acc67887ba440f9db1312c97475098/policy.xml",
"plugins/DvdMounter.dll",
"plugins/OMDb.dll",
"plugins/Emby.PortMapper.dll",
"plugins/EmbyGuideData.dll",
"plugins/MusicBrainz.dll",
"plugins/AudioDb.dll",
"plugins/MovieDb.dll",
"plugins/Emby.Server.CinemaMode.dll",
"plugins/Emby.M3UTuner.dll",
"plugins/Emby.Dlna.dll",
"plugins/Fanart.dll",
"plugins/Tvdb.dll",
"plugins/NfoMetadata.dll",
"plugins/StudioImages.dll",
"plugins/Emby.Webhooks.dll",
"plugins/MBBackup.dll",
"plugins/OpenSubtitles.dll",
"plugins/Emby.XmlTV.dll",
"plugins/BlurayMounter.dll",
"data/lastversion.txt",
"data/wan.dat",
"data/library.db",
"data/authentication.db-wal",
"data/device.txt",
"data/activitylog.db-shm",
"data/authentication.db",
"data/users.db-shm",
"data/library.db-shm",
"data/users.db-wal",
"data/authentication.db-shm",
"data/activitylog.db"
],
"source": "/var/lib/docker/volumes/volgate-emby_emby_config/_data",
"target": "/config",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 3,
"name": null,
"sample": [
"books/metadata.db",
"books/metadata.db-shm",
"books/metadata.db-wal"
],
"source": "/srv/felhom-gate/hdd/userdata/media",
"target": "/media",
"writable_by_app": "yes"
}
],
"name": "emby",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"emby_config"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,59 @@
{
"probe": {
"app": "ghost",
"containers": [
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "ghost:6.53.0-alpine",
"mounts": [
{
"class": "named-declared",
"files": 7,
"name": "volgate-ghost_ghost_content",
"sample": [
"themes/casper",
"themes/source",
"data/ghost.db",
"logs/https___blog_gate_invalid_production.error.log",
"logs/https___blog_gate_invalid_production.log",
"public/admin-auth/index.html",
"public/.well-known/recommendations.json"
],
"source": "/var/lib/docker/volumes/volgate-ghost_ghost_content/_data",
"target": "/var/lib/ghost/content",
"writable_by_app": "yes"
}
],
"name": "ghost",
"restarts": null,
"status": "running",
"uid": 1000
}
],
"declared_volumes": [
"ghost_content"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,193 @@
{
"probe": {
"app": "gitea",
"containers": [
{
"diff_added": 16,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"data"
],
"changed_count": 3,
"db_signature": false,
"dir": "/",
"files": [
"data"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app",
"files": [
"gitea"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app/gitea",
"files": [
"gitea"
]
},
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/etc",
"files": [
"ssh",
"s6"
]
},
{
"added": [],
"changed_count": 3,
"db_signature": false,
"dir": "/etc/s6",
"files": [
"openssh",
".s6-svscan",
"gitea"
]
},
{
"added": [
"control",
"lock"
],
"changed_count": 0,
"db_signature": false,
"dir": "/etc/s6/.s6-svscan",
"files": [
"control",
"lock"
]
},
{
"added": [
"supervise",
"event"
],
"changed_count": 0,
"db_signature": false,
"dir": "/etc/s6/gitea",
"files": [
"supervise",
"event"
]
},
{
"added": [
"lock",
"status",
"control",
"death_tally"
],
"changed_count": 0,
"db_signature": false,
"dir": "/etc/s6/gitea/supervise",
"files": [
"lock",
"status",
"control",
"death_tally"
]
},
{
"added": [
"event",
"supervise"
],
"changed_count": 0,
"db_signature": false,
"dir": "/etc/s6/openssh",
"files": [
"event",
"supervise"
]
},
{
"added": [
"death_tally",
"lock",
"status",
"control"
],
"changed_count": 0,
"db_signature": false,
"dir": "/etc/s6/openssh/supervise",
"files": [
"death_tally",
"lock",
"status",
"control"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/ssh",
"files": [
"sshd_config"
]
}
],
"diff_token_dirs": [],
"diff_total": 27,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "gitea/gitea:1.27.0",
"mounts": [
{
"class": "named-declared",
"files": 8,
"name": "volgate-gitea_gitea_data",
"sample": [
"git/.ssh/environment",
"gitea/conf/app.ini",
"ssh/ssh_host_ecdsa_key.pub",
"ssh/ssh_host_ed25519_key",
"ssh/ssh_host_ed25519_key.pub",
"ssh/ssh_host_ecdsa_key",
"ssh/ssh_host_rsa_key",
"ssh/ssh_host_rsa_key.pub"
],
"source": "/var/lib/docker/volumes/volgate-gitea_gitea_data/_data",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "gitea",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"gitea_data"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,74 @@
{
"probe": {
"app": "glance",
"containers": [
{
"diff_added": 1,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"app"
]
},
{
"added": [
"config"
],
"changed_count": 0,
"db_signature": false,
"dir": "/app",
"files": [
"config"
]
}
],
"diff_token_dirs": [],
"diff_total": 2,
"diff_unresolved": [],
"exit": 1,
"gid": null,
"health": "unhealthy",
"image": "glanceapp/glance:v0.8.5",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-glance_glance_config",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-glance_glance_config/_data",
"target": "/app/config",
"writable_by_app": "unknown-uid"
}
],
"name": "glance",
"restarts": null,
"status": "restarting",
"uid": null
}
],
"declared_volumes": [
"glance_config"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"glance: not running (status=restarting exit=1 restarts=None)"
],
"verdict": "UNDETERMINED",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,92 @@
{
"probe": {
"app": "gokapi",
"containers": [
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"app"
]
},
{
"added": [
"config",
"data"
],
"changed_count": 0,
"db_signature": false,
"dir": "/app",
"files": [
"config",
"data"
]
}
],
"diff_token_dirs": [],
"diff_total": 3,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "f0rc3/gokapi:v1.9.6",
"mounts": [
{
"class": "named-declared",
"files": 4,
"name": "volgate-gokapi_gokapi_data",
"sample": [
"log.txt",
"gokapi.sqlite-shm",
"gokapi.sqlite",
"gokapi.sqlite-wal"
],
"source": "/var/lib/docker/volumes/volgate-gokapi_gokapi_data/_data",
"target": "/app/data",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 1,
"name": "volgate-gokapi_gokapi_config",
"sample": [
"config.json"
],
"source": "/var/lib/docker/volumes/volgate-gokapi_gokapi_config/_data",
"target": "/app/config",
"writable_by_app": "yes"
}
],
"name": "gokapi",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"gokapi_config",
"gokapi_data"
],
"env_keys": [
"DOMAIN",
"GOKAPI_PASSWORD",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,93 @@
{
"probe": {
"app": "grafana",
"containers": [
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "grafana/grafana:13.1.0",
"mounts": [
{
"class": "named-declared",
"files": 543,
"name": "volgate-grafana_grafana_data",
"sample": [
"grafana.db",
"plugins/grafana-exploretraces-app/775.js.map",
"plugins/grafana-exploretraces-app/892.js",
"plugins/grafana-exploretraces-app/102.js",
"plugins/grafana-exploretraces-app/892.js.map",
"plugins/grafana-exploretraces-app/926.js",
"plugins/grafana-exploretraces-app/14.js",
"plugins/grafana-exploretraces-app/766.js.map",
"plugins/grafana-exploretraces-app/941.js",
"plugins/grafana-exploretraces-app/4.js",
"plugins/grafana-exploretraces-app/153.js",
"plugins/grafana-exploretraces-app/145.js",
"plugins/grafana-exploretraces-app/304.js",
"plugins/grafana-exploretraces-app/477.js.map",
"plugins/grafana-exploretraces-app/54.js",
"plugins/grafana-exploretraces-app/914.js.map",
"plugins/grafana-exploretraces-app/903.js",
"plugins/grafana-exploretraces-app/24.js",
"plugins/grafana-exploretraces-app/638.js",
"plugins/grafana-exploretraces-app/24.js.map",
"plugins/grafana-exploretraces-app/24.js.LICENSE.txt",
"plugins/grafana-exploretraces-app/257.js",
"plugins/grafana-exploretraces-app/315.js",
"plugins/grafana-exploretraces-app/397.js",
"plugins/grafana-exploretraces-app/453.js",
"plugins/grafana-exploretraces-app/980.js",
"plugins/grafana-exploretraces-app/944c737f589d02ecf603.svg",
"plugins/grafana-exploretraces-app/485.js",
"plugins/grafana-exploretraces-app/plugin.json",
"plugins/grafana-exploretraces-app/477.js",
"plugins/grafana-exploretraces-app/317.js",
"plugins/grafana-exploretraces-app/276.js",
"plugins/grafana-exploretraces-app/196.js",
"plugins/grafana-exploretraces-app/193.js",
"plugins/grafana-exploretraces-app/397.js.map",
"plugins/grafana-exploretraces-app/684.js",
"plugins/grafana-exploretraces-app/531.js",
"plugins/grafana-exploretraces-app/499.js",
"plugins/grafana-exploretraces-app/276.js.map",
"plugins/grafana-exploretraces-app/LICENSE"
],
"source": "/var/lib/docker/volumes/volgate-grafana_grafana_data/_data",
"target": "/var/lib/grafana",
"writable_by_app": "yes"
}
],
"name": "grafana",
"restarts": null,
"status": "running",
"uid": 472
}
],
"declared_volumes": [
"grafana_data"
],
"env_keys": [
"DOMAIN",
"GF_SECURITY_ADMIN_PASSWORD",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,266 @@
{
"probe": {
"app": "gramps-web",
"containers": [
{
"diff_added": 127,
"diff_benign_db_touches": [],
"diff_data_dirs": [
{
"added": [
"users.sqlite"
],
"changed_count": 0,
"db_signature": true,
"dir": "/app/users",
"files": [
"users.sqlite"
]
}
],
"diff_other_dirs": [
{
"added": [],
"changed_count": 3,
"db_signature": false,
"dir": "/",
"files": [
"usr",
"app",
"root"
]
},
{
"added": [
"data"
],
"changed_count": 4,
"db_signature": false,
"dir": "/app",
"files": [
"data"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app/cache",
"files": [
"request_cache"
]
},
{
"added": [
"2029240f6d1128be89ddc32729463129"
],
"changed_count": 0,
"db_signature": false,
"dir": "/app/cache/request_cache",
"files": [
"2029240f6d1128be89ddc32729463129"
]
},
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/app/src",
"files": [
"alembic_users",
"gramps_webapi"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app/src/alembic_users",
"files": [
"versions"
]
},
{
"added": [],
"changed_count": 3,
"db_signature": false,
"dir": "/app/src/gramps_webapi",
"files": [
"api",
"auth",
"util"
]
},
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/app/src/gramps_webapi/api",
"files": [
"resources",
"search"
]
},
{
"added": [
"2029240f6d1128be89ddc32729463129"
],
"changed_count": 0,
"db_signature": false,
"dir": "/app/thumbnail_cache",
"files": [
"2029240f6d1128be89ddc32729463129"
]
},
{
"added": [
".gramps"
],
"changed_count": 1,
"db_signature": false,
"dir": "/root",
"files": [
".gramps"
]
},
{
"added": [
"grampsdb"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root/.gramps",
"files": [
"grampsdb"
]
},
{
"added": [
"61411b9e-fed7-485a-ab76-6e8ea7326c3b"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root/.gramps/grampsdb",
"files": [
"61411b9e-fed7-485a-ab76-6e8ea7326c3b"
]
},
{
"added": [
"name.txt",
"database.txt"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root/.gramps/grampsdb/61411b9e-fed7-485a-ab76-6e8ea7326c3b",
"files": [
"name.txt",
"database.txt"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/root/gramps",
"files": [
"gramps60"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/root/gramps/gramps60",
"files": [
"plugins"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/root/gramps/gramps60/plugins",
"files": [
"FilterRules"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr",
"files": [
"lib"
]
}
],
"diff_token_dirs": [],
"diff_total": 153,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/gramps-project/grampsweb:v25.6.0",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-grampsweb_gramps_data",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-grampsweb_gramps_data/_data",
"target": "/app/data",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 0,
"name": "volgate-grampsweb_gramps_media",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-grampsweb_gramps_media/_data",
"target": "/app/media",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 0,
"name": "volgate-grampsweb_gramps_tmp",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-grampsweb_gramps_tmp/_data",
"target": "/tmp",
"writable_by_app": "yes"
}
],
"name": "gramps-web",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"gramps_data",
"gramps_media",
"gramps_tmp"
],
"env_keys": [
"DOMAIN",
"GRAMPSWEB_SECRET_KEY",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"gramps-web: DATA in the writable layer at /app/users (db_signature=True, e.g. ['users.sqlite'])",
"NOTHING this app wrote landed in ANY folder the template preserves: all 2 mount(s) across 1 container(s) are empty, yet entries were created in ['/app', '/app/cache/request_cache', '/app/thumbnail_cache', '/root']. Needs adjudication.",
"gramps-web: this container's mounts are all empty while it created entries in ['/app', '/app/cache/request_cache', '/app/thumbnail_cache'] \u2014 benign when a sibling container holds the state, worth a look when none does",
"gramps-web: declared volume /app/data is EMPTY",
"gramps-web: declared volume /app/media is EMPTY"
],
"verdict": "BROKEN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,114 @@
{
"probe": {
"app": "home-assistant",
"containers": [
{
"diff_added": 2267,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 3,
"db_signature": false,
"dir": "/",
"files": [
"run",
"root",
"usr"
]
},
{
"added": [
".config"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root",
"files": [
".config"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr",
"files": [
"local"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr/local",
"files": [
"lib"
]
}
],
"diff_token_dirs": [],
"diff_total": 2561,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/home-assistant/home-assistant:2026.7.2",
"mounts": [
{
"class": "named-declared",
"files": 21,
"name": "volgate-homeassistant_homeassistant_config",
"sample": [
"home-assistant.log",
"home-assistant_v2.db-wal",
"configuration.yaml",
"home-assistant.log.fault",
".HA_VERSION",
"home-assistant.log.1",
"home-assistant_v2.db",
"home-assistant_v2.db-shm",
".ha_run.lock",
".storage/core.config_entries",
".storage/core.restore_state",
".storage/auth",
".storage/http.auth",
".storage/assist_pipeline.pipelines",
".storage/core.device_registry",
".storage/homeassistant.exposed_entities",
".storage/core.uuid",
".storage/core.entity_registry",
"blueprints/script/homeassistant/confirmable_notification.yaml",
"blueprints/automation/homeassistant/notify_leaving_zone.yaml",
"blueprints/automation/homeassistant/motion_light.yaml"
],
"source": "/var/lib/docker/volumes/volgate-homeassistant_homeassistant_config/_data",
"target": "/config",
"writable_by_app": "yes"
}
],
"name": "home-assistant",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"homeassistant_config"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,68 @@
{
"probe": {
"app": "homebox",
"containers": [
{
"diff_added": 1,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"data"
],
"changed_count": 0,
"db_signature": false,
"dir": "/",
"files": [
"data"
]
}
],
"diff_token_dirs": [],
"diff_total": 1,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/sysadminsmedia/homebox:0.26.2",
"mounts": [
{
"class": "named-declared",
"files": 3,
"name": "volgate-homebox_homebox_data",
"sample": [
"homebox.db-shm",
"homebox.db",
"homebox.db-wal"
],
"source": "/var/lib/docker/volumes/volgate-homebox_homebox_data/_data",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "homebox",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"homebox_data"
],
"env_keys": [
"DOMAIN",
"HBOX_AUTH_API_KEY_PEPPER",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,86 @@
{
"probe": {
"app": "homepage",
"containers": [
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/",
"files": [
"run",
"app"
]
},
{
"added": [
"config"
],
"changed_count": 0,
"db_signature": false,
"dir": "/app",
"files": [
"config"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/gethomepage/homepage:v1.13.2",
"mounts": [
{
"class": "named-declared",
"files": 3,
"name": "volgate-homepage_homepage_config",
"sample": [
"kubernetes.yaml",
"settings.yaml",
"logs/homepage.log"
],
"source": "/var/lib/docker/volumes/volgate-homepage_homepage_config/_data",
"target": "/app/config",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": -1,
"name": null,
"sample": [],
"source": "/var/run/docker.sock",
"target": "/var/run/docker.sock",
"writable_by_app": "no-source"
}
],
"name": "homepage",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"homepage_config"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,330 @@
{
"probe": {
"app": "immich",
"containers": [
{
"diff_added": 6,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"cache"
],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"cache"
]
},
{
"added": [
".config"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root",
"files": [
".config"
]
},
{
"added": [
"matplotlib"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root/.config",
"files": [
"matplotlib"
]
}
],
"diff_token_dirs": [],
"diff_total": 7,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/immich-app/immich-machine-learning:v3.0.3",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-immich_immich_ml_cache",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-immich_immich_ml_cache/_data",
"target": "/cache",
"writable_by_app": "yes"
}
],
"name": "immich-machine-learning",
"restarts": null,
"status": "running",
"uid": 0
},
{
"diff_added": 3,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/",
"files": [
"etc",
"run"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc",
"files": [
"postgresql"
]
},
{
"added": [
"postgresql.conf"
],
"changed_count": 0,
"db_signature": false,
"dir": "/etc/postgresql",
"files": [
"postgresql.conf"
]
}
],
"diff_token_dirs": [],
"diff_total": 7,
"diff_unresolved": [],
"exit": 0,
"gid": 999,
"health": "healthy",
"image": "ghcr.io/immich-app/postgres:16-vectorchord0.4.3-pgvectors0.2.0",
"mounts": [
{
"class": "named-declared",
"files": 1833,
"name": "volgate-immich_immich_postgres_data",
"sample": [
"postmaster.opts",
"postgresql.conf",
"postgresql.auto.conf",
"pg_ident.conf",
"pg_hba.conf",
"postmaster.pid",
"PG_VERSION",
"base/1/826",
"base/1/2996",
"base/1/3764",
"base/1/2610_fsm",
"base/1/3603_fsm",
"base/1/1249_vm",
"base/1/3600_fsm",
"base/1/3602",
"base/1/6228",
"base/1/4174",
"base/1/4157",
"base/1/4146",
"base/1/2611",
"base/1/2657",
"base/1/3079_vm",
"base/1/1247_vm",
"base/1/13406",
"base/1/1259",
"base/1/3601_fsm",
"base/1/1417",
"base/1/4155",
"base/1/2668",
"base/1/2831",
"base/1/2841",
"base/1/13414",
"base/1/3607",
"base/1/2836",
"base/1/1255_fsm",
"base/1/2615_vm",
"base/1/3575",
"base/1/2605_vm",
"base/1/2670",
"base/1/6106"
],
"source": "/var/lib/docker/volumes/volgate-immich_immich_postgres_data/_data",
"target": "/var/lib/postgresql/data",
"writable_by_app": "yes"
}
],
"name": "immich-postgres",
"restarts": null,
"status": "running",
"uid": 999
},
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "redis:7-alpine",
"mounts": [
{
"class": "named-declared",
"files": 3,
"name": "volgate-immich_immich_redis_data",
"sample": [
"appendonlydir/appendonly.aof.1.base.rdb",
"appendonlydir/appendonly.aof.1.incr.aof",
"appendonlydir/appendonly.aof.manifest"
],
"source": "/var/lib/docker/volumes/volgate-immich_immich_redis_data/_data",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "immich-redis",
"restarts": null,
"status": "running",
"uid": 999
},
{
"diff_added": 4,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"data",
"external"
],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"data",
"external"
]
},
{
"added": [
"photos"
],
"changed_count": 0,
"db_signature": false,
"dir": "/external",
"files": [
"photos"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr",
"files": [
"src"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr/src",
"files": [
"app"
]
},
{
"added": [
"upload"
],
"changed_count": 0,
"db_signature": false,
"dir": "/usr/src/app",
"files": [
"upload"
]
}
],
"diff_token_dirs": [],
"diff_total": 7,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/immich-app/immich-server:v3.0.3",
"mounts": [
{
"class": "bind",
"files": 6,
"name": null,
"sample": [
"library/.immich",
"upload/.immich",
"profile/.immich",
"encoded-video/.immich",
"thumbs/.immich",
"backups/.immich"
],
"source": "/srv/felhom-gate/hdd/appdata/immich",
"target": "/usr/src/app/upload",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/hdd/userdata/media/photos",
"target": "/external/photos",
"writable_by_app": "yes"
},
{
"class": "anonymous",
"files": 0,
"name": "8a33371900fd8f325c75733c4486ad225939fc62a80ae67ee333a598a34b665f",
"sample": [],
"source": "/var/lib/docker/volumes/8a33371900fd8f325c75733c4486ad225939fc62a80ae67ee333a598a34b665f/_data",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "immich-server",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"immich_ml_cache",
"immich_postgres_data",
"immich_redis_data"
],
"env_keys": [
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"immich-machine-learning: this container's mounts are all empty while it created entries in ['/', '/root', '/root/.config'] \u2014 benign when a sibling container holds the state, worth a look when none does",
"immich-machine-learning: declared volume /cache is EMPTY"
],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,153 @@
{
"probe": {
"app": "jellyfin",
"containers": [
{
"diff_added": 7,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/",
"files": [
"jellyfin",
"root"
]
},
{
"added": [
"Dictionaries"
],
"changed_count": 0,
"db_signature": false,
"dir": "/jellyfin",
"files": [
"Dictionaries"
]
},
{
"added": [
".aspnet"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root",
"files": [
".aspnet"
]
},
{
"added": [
"DataProtection-Keys"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root/.aspnet",
"files": [
"DataProtection-Keys"
]
},
{
"added": [
"key-b1c34edb-e295-4345-a61a-db5f11d4fb0f.xml"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root/.aspnet/DataProtection-Keys",
"files": [
"key-b1c34edb-e295-4345-a61a-db5f11d4fb0f.xml"
]
}
],
"diff_token_dirs": [],
"diff_total": 10,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "jellyfin/jellyfin:10.11.11",
"mounts": [
{
"class": "named-declared",
"files": 20,
"name": "volgate-jellyfin_jellyfin_config",
"sample": [
".jellyfin-data",
"root/.jellyfin-root",
"log/.jellyfin-log",
"log/log_20260802.log",
"config/logging.default.json",
"config/system.xml",
"config/encoding.xml",
"config/.jellyfin-config",
"config/database.xml",
"plugins/.jellyfin-plugin",
"plugins/configurations/Jellyfin.Plugin.Tmdb.xml",
"plugins/configurations/Jellyfin.Plugin.MusicBrainz.xml",
"data/device.txt",
"data/jellyfin.db-wal",
"data/.jellyfin-data",
"data/jellyfin.db",
"data/jellyfin.db-shm",
"data/ScheduledTasks/7d8088c1-0902-f1bf-4072-ded42437bcfb.js",
"data/ScheduledTasks/3a025083-141d-3c17-dd96-d5f9b951287b.js",
"data/ScheduledTasks/f9b057c0-54e9-e6da-ee4a-88ffd146a403.js"
],
"source": "/var/lib/docker/volumes/volgate-jellyfin_jellyfin_config/_data",
"target": "/config",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 2,
"name": "volgate-jellyfin_jellyfin_cache",
"sample": [
".jellyfin-cache",
"transcodes/.jellyfin-transcode"
],
"source": "/var/lib/docker/volumes/volgate-jellyfin_jellyfin_cache/_data",
"target": "/cache",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 3,
"name": null,
"sample": [
"books/metadata.db",
"books/metadata.db-shm",
"books/metadata.db-wal"
],
"source": "/srv/felhom-gate/hdd/userdata/media",
"target": "/media",
"writable_by_app": "yes"
}
],
"name": "jellyfin",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"jellyfin_cache",
"jellyfin_config"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,259 @@
{
"probe": {
"app": "kimai",
"containers": [
{
"diff_added": 1,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 3,
"db_signature": false,
"dir": "/",
"files": [
"usr",
"opt",
"run"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/opt",
"files": [
"kimai"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/opt/kimai",
"files": [
"config"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/opt/kimai/config",
"files": [
"packages"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/opt/kimai/config/packages",
"files": [
"monolog.yaml"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr",
"files": [
"local"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr/local",
"files": [
"etc"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr/local/etc",
"files": [
"php"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr/local/etc/php",
"files": [
"php.ini"
]
}
],
"diff_token_dirs": [],
"diff_total": 13,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "kimai/kimai2:apache-2.57.0",
"mounts": [
{
"class": "named-declared",
"files": 2547,
"name": "volgate-kimai_kimai_var",
"sample": [
"installed",
"cache/.gitkeep",
"cache/pro_/url_generating_routes.php",
"cache/pro_/url_matching_routes.php",
"cache/pro_/url_matching_routes.php.meta",
"cache/pro_/url_generating_routes.php.meta",
"cache/pro_/Symfony/Config/TwigExtraConfig.php",
"cache/pro_/Symfony/Config/DoctrineMigrationsConfig.php",
"cache/pro_/Symfony/Config/MonologConfig.php",
"cache/pro_/Symfony/Config/NelmioCorsConfig.php",
"cache/pro_/Symfony/Config/WebpackEncoreConfig.php",
"cache/pro_/Symfony/Config/NelmioApiDocConfig.php",
"cache/pro_/Symfony/Config/TablerConfig.php",
"cache/pro_/Symfony/Config/FrameworkConfig.php",
"cache/pro_/Symfony/Config/SchebTwoFactorConfig.php",
"cache/pro_/Symfony/Config/TwigConfig.php",
"cache/pro_/Symfony/Config/SecurityConfig.php",
"cache/pro_/Symfony/Config/DoctrineConfig.php",
"cache/pro_/Symfony/Config/FosRestConfig.php",
"cache/pro_/Symfony/Config/JmsSerializerConfig.php",
"cache/pro_/Symfony/Config/Tabler/RoutesConfig.php",
"cache/pro_/Symfony/Config/Tabler/KnpMenuConfig.php",
"cache/pro_/Symfony/Config/Tabler/OptionsConfig.php",
"cache/pro_/Symfony/Config/SchebTwoFactor/TotpConfig.php",
"cache/pro_/Symfony/Config/SchebTwoFactor/BackupCodesConfig.php",
"cache/pro_/Symfony/Config/DoctrineMigrations/StorageConfig.php",
"cache/pro_/Symfony/Config/DoctrineMigrations/Storage/TableStorageConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/VisitorsConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/InstancesConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/HandlersConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/PropertyNamingConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/MetadataConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/DefaultContextConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/ObjectConstructorsConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/SubscribersConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/ExpressionEvaluatorConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/ObjectConstructors/DoctrineConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/Subscribers/DoctrineProxyConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/InstancesConfig/VisitorsConfig.php",
"cache/pro_/Symfony/Config/JmsSerializer/InstancesConfig/HandlersConfig.php"
],
"source": "/var/lib/docker/volumes/volgate-kimai_kimai_var/_data",
"target": "/opt/kimai/var",
"writable_by_app": "yes"
}
],
"name": "kimai",
"restarts": null,
"status": "running",
"uid": 0
},
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 999,
"health": "healthy",
"image": "mariadb:11.6",
"mounts": [
{
"class": "named-declared",
"files": 279,
"name": "volgate-kimai_kimai_db_data",
"sample": [
"undo002",
"tc.log",
"mariadb_upgrade_info",
"ibtmp1",
"aria_log.00000001",
"multi-master.info",
"ddl_recovery.log",
"ib_logfile0",
"undo003",
"ibdata1",
".my-healthcheck.cnf",
"aria_log_control",
"undo001",
"ib_buffer_pool",
"sys/x@0024wait_classes_global_by_latency.frm",
"sys/processlist.frm",
"sys/session.frm",
"sys/memory_by_host_by_current_bytes.frm",
"sys/user_summary.frm",
"sys/waits_global_by_latency.frm",
"sys/x@0024statement_analysis.frm",
"sys/x@0024host_summary.frm",
"sys/schema_unused_indexes.frm",
"sys/user_summary_by_file_io_type.frm",
"sys/memory_by_thread_by_current_bytes.frm",
"sys/x@0024statements_with_full_table_scans.frm",
"sys/wait_classes_global_by_avg_latency.frm",
"sys/x@0024schema_table_statistics.frm",
"sys/x@0024statements_with_temp_tables.frm",
"sys/schema_auto_increment_columns.frm",
"sys/x@0024ps_schema_table_statistics_io.frm",
"sys/x@0024memory_by_host_by_current_bytes.frm",
"sys/statements_with_runtimes_in_95th_percentile.frm",
"sys/x@0024statements_with_errors_or_warnings.frm",
"sys/waits_by_user_by_latency.frm",
"sys/x@0024io_global_by_file_by_bytes.frm",
"sys/innodb_buffer_stats_by_table.frm",
"sys/user_summary_by_statement_type.frm",
"sys/statements_with_errors_or_warnings.frm",
"sys/sys_config.MAD"
],
"source": "/var/lib/docker/volumes/volgate-kimai_kimai_db_data/_data",
"target": "/var/lib/mysql",
"writable_by_app": "yes"
}
],
"name": "kimai-db",
"restarts": null,
"status": "running",
"uid": 999
}
],
"declared_volumes": [
"kimai_db_data",
"kimai_var"
],
"env_keys": [
"ADMIN_EMAIL",
"ADMIN_PASSWORD",
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,86 @@
{
"probe": {
"app": "komga",
"containers": [
{
"diff_added": 12,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"data",
"config"
],
"changed_count": 0,
"db_signature": false,
"dir": "/",
"files": [
"data",
"config"
]
}
],
"diff_token_dirs": [],
"diff_total": 13,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "gotson/komga:1.25.0",
"mounts": [
{
"class": "named-declared",
"files": 11,
"name": "volgate-komga_komga_config",
"sample": [
"database.sqlite-shm",
"database.sqlite-wal",
"tasks.sqlite-shm",
"database.sqlite",
"tasks.sqlite-wal",
"tasks.sqlite",
"lucene/_0.cfe",
"lucene/_0.si",
"lucene/segments_1",
"lucene/_0.cfs",
"logs/komga.log"
],
"source": "/var/lib/docker/volumes/volgate-komga_komga_config/_data",
"target": "/config",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/hdd/userdata/media/comics",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "komga",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"komga_config"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,89 @@
{
"probe": {
"app": "mealie",
"containers": [
{
"diff_added": 1,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/",
"files": [
"etc",
"app"
]
},
{
"added": [
"data"
],
"changed_count": 2,
"db_signature": false,
"dir": "/app",
"files": [
"data"
]
},
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/etc",
"files": [
"passwd-",
"group-"
]
}
],
"diff_token_dirs": [],
"diff_total": 9,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "ghcr.io/mealie-recipes/mealie:v3.20.1",
"mounts": [
{
"class": "named-declared",
"files": 5,
"name": "volgate-mealie_mealie_data",
"sample": [
".session_secret",
"mealie.db",
"mealie.log",
".secret",
"users/6b1f2b18-68e0-468f-9db1-0431546240bd/profile.webp"
],
"source": "/var/lib/docker/volumes/volgate-mealie_mealie_data/_data",
"target": "/app/data",
"writable_by_app": "yes"
}
],
"name": "mealie",
"restarts": null,
"status": "running",
"uid": 1000
}
],
"declared_volumes": [
"mealie_data"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,79 @@
{
"probe": {
"app": "n8n",
"containers": [
{
"diff_added": 1094,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"home"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/home",
"files": [
"node"
]
}
],
"diff_token_dirs": [],
"diff_total": 1097,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "n8nio/n8n:2.31.3",
"mounts": [
{
"class": "named-declared",
"files": 7,
"name": "volgate-n8n_n8n_data",
"sample": [
"database.sqlite-shm",
"database.sqlite-wal",
"config",
"database.sqlite",
"n8nEventLog.log",
"crash.journal",
"nodes/package.json"
],
"source": "/var/lib/docker/volumes/volgate-n8n_n8n_data/_data",
"target": "/home/node/.n8n",
"writable_by_app": "yes"
}
],
"name": "n8n",
"restarts": null,
"status": "running",
"uid": 1000
}
],
"declared_volumes": [
"n8n_data"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"N8N_ENCRYPTION_KEY",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,81 @@
{
"probe": {
"app": "navidrome",
"containers": [
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"data",
"music"
],
"changed_count": 0,
"db_signature": false,
"dir": "/",
"files": [
"data",
"music"
]
}
],
"diff_token_dirs": [],
"diff_total": 2,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "deluan/navidrome:0.63.2",
"mounts": [
{
"class": "named-declared",
"files": 6,
"name": "volgate-navidrome_navidrome_data",
"sample": [
"navidrome.db-wal",
"navidrome.db",
"navidrome.db-shm",
"cache/transcoding/.nd-migrated",
"cache/images/.nd-migrated",
"cache/backgrounds/.nd-migrated"
],
"source": "/var/lib/docker/volumes/volgate-navidrome_navidrome_data/_data",
"target": "/data",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/hdd/userdata/media/music",
"target": "/music",
"writable_by_app": "yes"
}
],
"name": "navidrome",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"navidrome_data"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,317 @@
{
"probe": {
"app": "nextcloud",
"containers": [
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/",
"files": [
"run",
"usr"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr",
"files": [
"local"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr/local",
"files": [
"etc"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr/local/etc",
"files": [
"php"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr/local/etc/php",
"files": [
"conf.d"
]
},
{
"added": [
"redis-session.ini"
],
"changed_count": 0,
"db_signature": false,
"dir": "/usr/local/etc/php/conf.d",
"files": [
"redis-session.ini"
]
}
],
"diff_token_dirs": [],
"diff_total": 9,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "nextcloud:34.0.1-apache",
"mounts": [
{
"class": "bind",
"files": 69,
"name": null,
"sample": [
".htaccess",
".ncdata",
"nextcloud.log",
"index.html",
"admin/files/Nextcloud intro.mp4",
"admin/files/Templates credits.md",
"admin/files/Nextcloud Manual.pdf",
"admin/files/Nextcloud.png",
"admin/files/Reasons to use Nextcloud.pdf",
"admin/files/Readme.md",
"admin/files/Photos/Frog.jpg",
"admin/files/Photos/Vineyard.jpg",
"admin/files/Photos/Library.jpg",
"admin/files/Photos/Nextcloud community.jpg",
"admin/files/Photos/Birdie.jpg",
"admin/files/Photos/Toucan.jpg",
"admin/files/Photos/Steps.jpg",
"admin/files/Photos/Readme.md",
"admin/files/Photos/Gorilla.jpg",
"admin/files/Documents/Welcome to Nextcloud Hub.docx",
"admin/files/Documents/Nextcloud flyer.pdf",
"admin/files/Documents/Example.md",
"admin/files/Documents/Readme.md",
"admin/files/Templates/Kanban board.whiteboard",
"admin/files/Templates/Meeting agenda.whiteboard",
"admin/files/Templates/Org chart.odg",
"admin/files/Templates/Invoice.ods",
"admin/files/Templates/Resume.odt",
"admin/files/Templates/Certificate.odt",
"admin/files/Templates/Brainstorming.whiteboard",
"admin/files/Templates/Letter.odt",
"admin/files/Templates/Gotong royong.odp",
"admin/files/Templates/Business model canvas.odg",
"admin/files/Templates/Sticky notes.whiteboard",
"admin/files/Templates/Security.odp",
"admin/files/Templates/Onboarding.odp",
"admin/files/Templates/Mind map.whiteboard",
"admin/files/Templates/Elegant.odp",
"admin/files/Templates/Expense report.ods",
"admin/files/Templates/Simple.odp"
],
"source": "/srv/felhom-gate/hdd/appdata/nextcloud",
"target": "/var/www/html/data",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 4001,
"name": "volgate-nextcloud_nextcloud_html",
"sample": [
"status.php",
".htaccess",
"AUTHORS",
"public.php",
"occ",
"index.php",
"composer.json",
"version.php",
"package-lock.json",
"nextcloud-init-sync.lock",
".user.ini",
"remote.php",
"cron.php",
"console.php",
"COPYING",
"REUSE.toml",
"index.html",
"package.json",
"robots.txt",
"composer.lock",
"lib/versioncheck.php",
"lib/base.php",
"lib/l10n/he.json",
"lib/l10n/bs.js",
"lib/l10n/es_PA.js",
"lib/l10n/hsb.json",
"lib/l10n/fo.json",
"lib/l10n/mk.json",
"lib/l10n/ru.js",
"lib/l10n/th.json",
"lib/l10n/es_GT.json",
"lib/l10n/eo.js",
"lib/l10n/pt_PT.json",
"lib/l10n/bn_BD.js",
"lib/l10n/ast.json",
"lib/l10n/kab.json",
"lib/l10n/fo.js",
"lib/l10n/km.js",
"lib/l10n/mn.js",
"lib/l10n/ig.json"
],
"source": "/var/lib/docker/volumes/volgate-nextcloud_nextcloud_html/_data",
"target": "/var/www/html",
"writable_by_app": "yes"
}
],
"name": "nextcloud",
"restarts": null,
"status": "running",
"uid": 0
},
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 999,
"health": "healthy",
"image": "mariadb:11.6",
"mounts": [
{
"class": "named-declared",
"files": 311,
"name": "volgate-nextcloud_nextcloud_db_data",
"sample": [
"undo002",
"tc.log",
"mariadb_upgrade_info",
"ibtmp1",
"aria_log.00000001",
"multi-master.info",
"ddl_recovery.log",
"ib_logfile0",
"undo003",
"ibdata1",
".my-healthcheck.cnf",
"aria_log_control",
"undo001",
"ib_buffer_pool",
"sys/x@0024wait_classes_global_by_latency.frm",
"sys/processlist.frm",
"sys/session.frm",
"sys/memory_by_host_by_current_bytes.frm",
"sys/user_summary.frm",
"sys/waits_global_by_latency.frm",
"sys/x@0024statement_analysis.frm",
"sys/x@0024host_summary.frm",
"sys/schema_unused_indexes.frm",
"sys/user_summary_by_file_io_type.frm",
"sys/memory_by_thread_by_current_bytes.frm",
"sys/x@0024statements_with_full_table_scans.frm",
"sys/wait_classes_global_by_avg_latency.frm",
"sys/x@0024schema_table_statistics.frm",
"sys/x@0024statements_with_temp_tables.frm",
"sys/schema_auto_increment_columns.frm",
"sys/x@0024ps_schema_table_statistics_io.frm",
"sys/x@0024memory_by_host_by_current_bytes.frm",
"sys/statements_with_runtimes_in_95th_percentile.frm",
"sys/x@0024statements_with_errors_or_warnings.frm",
"sys/waits_by_user_by_latency.frm",
"sys/x@0024io_global_by_file_by_bytes.frm",
"sys/innodb_buffer_stats_by_table.frm",
"sys/user_summary_by_statement_type.frm",
"sys/statements_with_errors_or_warnings.frm",
"sys/sys_config.MAD"
],
"source": "/var/lib/docker/volumes/volgate-nextcloud_nextcloud_db_data/_data",
"target": "/var/lib/mysql",
"writable_by_app": "yes"
}
],
"name": "nextcloud-db",
"restarts": null,
"status": "running",
"uid": 999
},
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "redis:7-alpine",
"mounts": [
{
"class": "named-declared",
"files": 3,
"name": "volgate-nextcloud_nextcloud_redis_data",
"sample": [
"appendonlydir/appendonly.aof.1.base.rdb",
"appendonlydir/appendonly.aof.1.incr.aof",
"appendonlydir/appendonly.aof.manifest"
],
"source": "/var/lib/docker/volumes/volgate-nextcloud_nextcloud_redis_data/_data",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "nextcloud-redis",
"restarts": null,
"status": "running",
"uid": 999
}
],
"declared_volumes": [
"nextcloud_db_data",
"nextcloud_html",
"nextcloud_redis_data"
],
"env_keys": [
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"MYSQL_ROOT_PASSWORD",
"NEXTCLOUD_ADMIN_PASSWORD",
"NEXTCLOUD_ADMIN_USER",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,103 @@
{
"probe": {
"app": "opengist",
"containers": [
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"opengist"
],
"changed_count": 3,
"db_signature": false,
"dir": "/",
"files": [
"opengist"
]
},
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/etc",
"files": [
"group-",
"passwd-"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/home",
"files": [
"opengist"
]
},
{
"added": [
".gitconfig"
],
"changed_count": 0,
"db_signature": false,
"dir": "/home/opengist",
"files": [
".gitconfig"
]
}
],
"diff_token_dirs": [],
"diff_total": 10,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "ghcr.io/thomiceli/opengist:1.13",
"mounts": [
{
"class": "named-declared",
"files": 9,
"name": "volgate-opengist_opengist_data",
"sample": [
"opengist-secret.key",
"opengist.db",
"sessions/session-encrypt.key",
"log/opengist.log",
"symlinks/opengist",
"symlinks/config.yml",
"opengist.index/index_meta.json",
"opengist.index/store/root.bolt",
"ssh/opengist-ed25519"
],
"source": "/var/lib/docker/volumes/volgate-opengist_opengist_data/_data",
"target": "/opengist",
"writable_by_app": "yes"
}
],
"name": "opengist",
"restarts": null,
"status": "running",
"uid": 1000
}
],
"declared_volumes": [
"opengist_data"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,166 @@
{
"probe": {
"app": "outline",
"containers": [
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 1001,
"health": "healthy",
"image": "outlinewiki/outline:1.9.1",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-outline_outline_data",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-outline_outline_data/_data",
"target": "/var/lib/outline/data",
"writable_by_app": "yes"
}
],
"name": "outline",
"restarts": null,
"status": "running",
"uid": 1001
},
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 70,
"health": "healthy",
"image": "postgres:16-alpine",
"mounts": [
{
"class": "named-declared",
"files": 1655,
"name": "volgate-outline_outline_postgres_data",
"sample": [
"postmaster.opts",
"postgresql.conf",
"postgresql.auto.conf",
"pg_ident.conf",
"pg_hba.conf",
"postmaster.pid",
"PG_VERSION",
"base/1/826",
"base/1/2996",
"base/1/3764",
"base/1/2610_fsm",
"base/1/3603_fsm",
"base/1/1249_vm",
"base/1/3600_fsm",
"base/1/13512",
"base/1/3602",
"base/1/6228",
"base/1/4174",
"base/1/4157",
"base/1/4146",
"base/1/2611",
"base/1/2657",
"base/1/3079_vm",
"base/1/1247_vm",
"base/1/1259",
"base/1/3601_fsm",
"base/1/1417",
"base/1/4155",
"base/1/2668",
"base/1/2831",
"base/1/2841",
"base/1/3607",
"base/1/2836",
"base/1/1255_fsm",
"base/1/2615_vm",
"base/1/3575",
"base/1/2605_vm",
"base/1/2670",
"base/1/6106",
"base/1/4163"
],
"source": "/var/lib/docker/volumes/volgate-outline_outline_postgres_data/_data",
"target": "/var/lib/postgresql/data",
"writable_by_app": "yes"
}
],
"name": "outline-postgres",
"restarts": null,
"status": "running",
"uid": 70
},
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "redis:7-alpine",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-outline_outline_redis_data",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-outline_outline_redis_data/_data",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "outline-redis",
"restarts": null,
"status": "running",
"uid": 999
}
],
"declared_volumes": [
"outline_data",
"outline_postgres_data",
"outline_redis_data"
],
"env_keys": [
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SECRET_KEY",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH",
"UTILS_SECRET"
],
"exercise": [],
"ports": []
},
"reasons": [
"outline: declared volume /var/lib/outline/data is EMPTY",
"outline-redis: declared volume /data is EMPTY"
],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,250 @@
{
"probe": {
"app": "paperless-ngx",
"containers": [
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 70,
"health": "healthy",
"image": "postgres:16-alpine",
"mounts": [
{
"class": "named-declared",
"files": 1927,
"name": "volgate-paperlessngx_paperless_postgres_data",
"sample": [
"postmaster.opts",
"postgresql.conf",
"postgresql.auto.conf",
"pg_ident.conf",
"pg_hba.conf",
"postmaster.pid",
"PG_VERSION",
"base/1/826",
"base/1/2996",
"base/1/3764",
"base/1/2610_fsm",
"base/1/3603_fsm",
"base/1/1249_vm",
"base/1/3600_fsm",
"base/1/13512",
"base/1/3602",
"base/1/6228",
"base/1/4174",
"base/1/4157",
"base/1/4146",
"base/1/2611",
"base/1/2657",
"base/1/3079_vm",
"base/1/1247_vm",
"base/1/1259",
"base/1/3601_fsm",
"base/1/1417",
"base/1/4155",
"base/1/2668",
"base/1/2831",
"base/1/2841",
"base/1/3607",
"base/1/2836",
"base/1/1255_fsm",
"base/1/2615_vm",
"base/1/3575",
"base/1/2605_vm",
"base/1/2670",
"base/1/6106",
"base/1/4163"
],
"source": "/var/lib/docker/volumes/volgate-paperlessngx_paperless_postgres_data/_data",
"target": "/var/lib/postgresql/data",
"writable_by_app": "yes"
}
],
"name": "paperless-postgres",
"restarts": null,
"status": "running",
"uid": 70
},
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "redis:7-alpine",
"mounts": [
{
"class": "named-declared",
"files": 3,
"name": "volgate-paperlessngx_paperless_redis_data",
"sample": [
"appendonlydir/appendonly.aof.1.base.rdb",
"appendonlydir/appendonly.aof.1.incr.aof",
"appendonlydir/appendonly.aof.manifest"
],
"source": "/var/lib/docker/volumes/volgate-paperlessngx_paperless_redis_data/_data",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "paperless-redis",
"restarts": null,
"status": "running",
"uid": 999
},
{
"diff_added": 265,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 3,
"db_signature": false,
"dir": "/",
"files": [
"usr",
"var",
"run"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr",
"files": [
"share"
]
},
{
"added": [],
"changed_count": 3,
"db_signature": false,
"dir": "/var",
"files": [
"log",
"cache",
"lib"
]
},
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/var/lib",
"files": [
"apt",
"dpkg"
]
}
],
"diff_token_dirs": [],
"diff_total": 294,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/paperless-ngx/paperless-ngx:2.20.15",
"mounts": [
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/hdd/appdata/paperless/export",
"target": "/usr/src/paperless/export",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 9,
"name": "volgate-paperlessngx_paperless_data",
"sample": [
"migration_lock",
".index_version",
"celerybeat-schedule.db",
"index/_MAIN_1.toc",
"index/MAIN_WRITELOCK",
"log/paperless.log",
"log/celery.log",
"log/.__paperless.lock",
"log/.__celery.lock"
],
"source": "/var/lib/docker/volumes/volgate-paperlessngx_paperless_data/_data",
"target": "/usr/src/paperless/data",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 1,
"name": null,
"sample": [
"media.lock"
],
"source": "/srv/felhom-gate/hdd/appdata/paperless/media",
"target": "/usr/src/paperless/media",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/import/paperless",
"target": "/usr/src/paperless/consume",
"writable_by_app": "yes"
}
],
"name": "paperless-webserver",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"paperless_data",
"paperless_postgres_data",
"paperless_redis_data"
],
"env_keys": [
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"PAPERLESS_ADMIN_PASSWORD",
"PAPERLESS_ADMIN_USER",
"PAPERLESS_OCR_LANGUAGE",
"PAPERLESS_SECRET_KEY",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,100 @@
{
"probe": {
"app": "papra",
"containers": [
{
"diff_added": 173,
"diff_benign_db_touches": [],
"diff_data_dirs": [
{
"added": [
"db.sqlite"
],
"changed_count": 0,
"db_signature": true,
"dir": "/app/app-data/db",
"files": [
"db.sqlite"
]
}
],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"app"
]
},
{
"added": [
"data"
],
"changed_count": 1,
"db_signature": false,
"dir": "/app",
"files": [
"data"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app/app-data",
"files": [
"db"
]
}
],
"diff_token_dirs": [],
"diff_total": 177,
"diff_unresolved": [],
"exit": 0,
"gid": 999,
"health": "healthy",
"image": "ghcr.io/papra-hq/papra:26.6.1-rootless",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-papra_papra_data",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-papra_papra_data/_data",
"target": "/app/data",
"writable_by_app": "NO"
}
],
"name": "papra",
"restarts": null,
"status": "running",
"uid": 999
}
],
"declared_volumes": [
"papra_data"
],
"env_keys": [
"AUTH_SECRET",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"papra: mount /app/data is NOT writable by the app's own uid=999 gid=999",
"papra: DATA in the writable layer at /app/app-data/db (db_signature=True, e.g. ['db.sqlite'])",
"NOTHING this app wrote landed in ANY folder the template preserves: all 1 mount(s) across 1 container(s) are empty, yet entries were created in ['/app']. Needs adjudication.",
"papra: this container's mounts are all empty while it created entries in ['/app'] \u2014 benign when a sibling container holds the state, worth a look when none does",
"papra: declared volume /app/data is EMPTY"
],
"verdict": "BROKEN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,11 @@
{
"probe": {
"app": "plant-it",
"error": "no containers created (compose up rc=1: msdeluise/plant-it:0.10.0 Pulling \n Image msdeluise/plant-it:0.10.0 Error pull access denied for msdeluise/plant-it, repository does not exist or may require 'docker login'\nError response from daemon: pull access denied for msdeluise/plant-it, repository does not exist or may require 'docker login'\n)"
},
"reasons": [
"no containers created (compose up rc=1: msdeluise/plant-it:0.10.0 Pulling \n Image msdeluise/plant-it:0.10.0 Error pull access denied for msdeluise/plant-it, repository does not exist or may require 'docker login'\nError response from daemon: pull access denied for msdeluise/plant-it, repository does not exist or may require 'docker login'\n)"
],
"verdict": "UNDETERMINED",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,170 @@
{
"probe": {
"app": "plex",
"containers": [
{
"diff_added": 63,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
".firstRunComplete"
],
"changed_count": 2,
"db_signature": false,
"dir": "/",
"files": [
".firstRunComplete"
]
},
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/etc",
"files": [
"cont-init.d",
"services.d"
]
},
{
"added": [],
"changed_count": 3,
"db_signature": false,
"dir": "/etc/cont-init.d",
"files": [
"45-plex-hw-transcode-and-connected-tuner",
"50-plex-update",
"40-plex-first-run"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/services.d",
"files": [
"plex"
]
},
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/etc/services.d/plex",
"files": [
"finish",
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 74,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "plexinc/pms-docker:1.41.4.9463-630c9f557",
"mounts": [
{
"class": "bind",
"files": 3,
"name": null,
"sample": [
"books/metadata.db",
"books/metadata.db-shm",
"books/metadata.db-wal"
],
"source": "/srv/felhom-gate/hdd/userdata/media",
"target": "/media",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 82,
"name": "volgate-plex_plex_config",
"sample": [
"Library/Application Support/Plex Media Server/.LocalAdminToken",
"Library/Application Support/Plex Media Server/plexmediaserver.pid",
"Library/Application Support/Plex Media Server/Preferences.xml",
"Library/Application Support/Plex Media Server/Setup Plex.html",
"Library/Application Support/Plex Media Server/Cache/Flags.dat",
"Library/Application Support/Plex Media Server/Cache/UpdateChannels.dat",
"Library/Application Support/Plex Media Server/Cache/Privacy.dat",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.themoviedb/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.themoviedb/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.plexthememusic/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.plexthememusic/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.lastfm/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.lastfm/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.imdb/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.imdb/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.none/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.none/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.thetvdb/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.thetvdb/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.movieposterdb/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.movieposterdb/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/org.musicbrainz.agents.music/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/org.musicbrainz.agents.music/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.fanarttv/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.fanarttv/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.htbackdrops/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.htbackdrops/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.localmedia/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.localmedia/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.system/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.system/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.system/Dict",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.lyricfind/HTTPCookies",
"Library/Application Support/Plex Media Server/Plug-in Support/Data/com.plexapp.agents.lyricfind/StoredValues",
"Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db-shm",
"Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.blobs.db",
"Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db-wal",
"Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.blobs.db-shm",
"Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.blobs.db-wal",
"Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db"
],
"source": "/var/lib/docker/volumes/volgate-plex_plex_config/_data",
"target": "/config",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 0,
"name": "volgate-plex_plex_transcode",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-plex_plex_transcode/_data",
"target": "/transcode",
"writable_by_app": "yes"
}
],
"name": "plex",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"plex_config",
"plex_transcode"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"PLEX_CLAIM",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"plex: declared volume /transcode is EMPTY"
],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,96 @@
{
"probe": {
"app": "privatebin",
"containers": [
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 82,
"health": "healthy",
"image": "privatebin/pdo:2.0.5",
"mounts": [
{
"class": "anonymous",
"files": 0,
"name": "1588c34a1374a5d4ae265cb892ff0059e87ae07e11a14ac1e17879c54b7b1ce2",
"sample": [],
"source": "/var/lib/docker/volumes/1588c34a1374a5d4ae265cb892ff0059e87ae07e11a14ac1e17879c54b7b1ce2/_data",
"target": "/tmp",
"writable_by_app": "yes"
},
{
"class": "anonymous",
"files": 0,
"name": "08447e377c7efaba21791de7813d6799c785ee1a7e72216608c72e01a5a40d69",
"sample": [],
"source": "/var/lib/docker/volumes/08447e377c7efaba21791de7813d6799c785ee1a7e72216608c72e01a5a40d69/_data",
"target": "/var/lib/nginx/tmp",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 0,
"name": "volgate-privatebin_privatebin_data",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-privatebin_privatebin_data/_data",
"target": "/srv/data",
"writable_by_app": "yes"
},
{
"class": "anonymous",
"files": 14,
"name": "ebd9667e81ace0d084e3f07b25360ca806df2a98294ec192d6afd674b70a790b",
"sample": [
"nginx.pid",
"php-fpm.sock",
"services/.s6-svscan/control",
"services/.s6-svscan/lock",
"services/php-fpm85/run",
"services/php-fpm85/supervise/control",
"services/php-fpm85/supervise/death_tally",
"services/php-fpm85/supervise/status",
"services/php-fpm85/supervise/lock",
"services/nginx/run",
"services/nginx/supervise/control",
"services/nginx/supervise/death_tally",
"services/nginx/supervise/status",
"services/nginx/supervise/lock"
],
"source": "/var/lib/docker/volumes/ebd9667e81ace0d084e3f07b25360ca806df2a98294ec192d6afd674b70a790b/_data",
"target": "/run",
"writable_by_app": "yes"
}
],
"name": "privatebin",
"restarts": null,
"status": "running",
"uid": 65534
}
],
"declared_volumes": [
"privatebin_data"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"nothing was written to any mount and nothing data-classified in any writable layer \u2014 the app produced no data to locate. Health is not data: this is UNDETERMINED, not CLEAN",
"privatebin: declared volume /srv/data is EMPTY"
],
"verdict": "UNDETERMINED",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,155 @@
{
"probe": {
"app": "radarr",
"containers": [
{
"diff_added": 207,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"downloads"
],
"changed_count": 5,
"db_signature": false,
"dir": "/",
"files": [
"downloads"
]
},
{
"added": [],
"changed_count": 4,
"db_signature": false,
"dir": "/etc",
"files": [
"group-",
"passwd-",
"s6-overlay",
"crontabs"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/crontabs",
"files": [
"root"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/s6-overlay",
"files": [
"s6-rc.d"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/s6-overlay/s6-rc.d",
"files": [
"init-adduser"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/s6-overlay/s6-rc.d/init-adduser",
"files": [
"branding"
]
}
],
"diff_token_dirs": [
{
"added": [
"movies"
],
"changed_count": 0,
"db_signature": false,
"dir": "/media",
"files": [
"movies"
]
}
],
"diff_total": 222,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "lscr.io/linuxserver/radarr:6.3.0",
"mounts": [
{
"class": "named-declared",
"files": 11,
"name": "volgate-radarr_radarr_config",
"sample": [
"radarr.pid",
"logs.db-shm",
"logs.db",
"radarr.db",
"radarr.db-wal",
"radarr.db-shm",
"logs.db-wal",
"config.xml",
"logs/radarr.txt",
"logs/radarr.debug.txt",
"asp/key-08e6d4a9-fe58-4059-ae41-87f0c8d018e5.xml"
],
"source": "/var/lib/docker/volumes/volgate-radarr_radarr_config/_data",
"target": "/config",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/hdd/userdata/media/movies",
"target": "/media/movies",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/hdd/userdata/downloads",
"target": "/downloads",
"writable_by_app": "yes"
}
],
"name": "radarr",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"radarr_config"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"radarr: writable-layer writes at /media (path suggests state, no database signature \u2014 judgement needed): ['movies']"
],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,159 @@
{
"probe": {
"app": "rallly",
"containers": [
{
"diff_added": 6,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"app"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app",
"files": [
"apps"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app/apps",
"files": [
"web"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app/apps/web",
"files": [
".next"
]
}
],
"diff_token_dirs": [],
"diff_total": 11,
"diff_unresolved": [],
"exit": 0,
"gid": 101,
"health": "healthy",
"image": "lukevella/rallly:4.11.1",
"mounts": [],
"name": "rallly",
"restarts": null,
"status": "running",
"uid": 100
},
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 70,
"health": "healthy",
"image": "postgres:16-alpine",
"mounts": [
{
"class": "named-declared",
"files": 1580,
"name": "volgate-rallly_rallly_postgres_data",
"sample": [
"postmaster.opts",
"postgresql.conf",
"postgresql.auto.conf",
"pg_ident.conf",
"pg_hba.conf",
"postmaster.pid",
"PG_VERSION",
"base/1/826",
"base/1/2996",
"base/1/3764",
"base/1/2610_fsm",
"base/1/3603_fsm",
"base/1/1249_vm",
"base/1/3600_fsm",
"base/1/13512",
"base/1/3602",
"base/1/6228",
"base/1/4174",
"base/1/4157",
"base/1/4146",
"base/1/2611",
"base/1/2657",
"base/1/3079_vm",
"base/1/1247_vm",
"base/1/1259",
"base/1/3601_fsm",
"base/1/1417",
"base/1/4155",
"base/1/2668",
"base/1/2831",
"base/1/2841",
"base/1/3607",
"base/1/2836",
"base/1/1255_fsm",
"base/1/2615_vm",
"base/1/3575",
"base/1/2605_vm",
"base/1/2670",
"base/1/6106",
"base/1/4163"
],
"source": "/var/lib/docker/volumes/volgate-rallly_rallly_postgres_data/_data",
"target": "/var/lib/postgresql/data",
"writable_by_app": "yes"
}
],
"name": "rallly-postgres",
"restarts": null,
"status": "running",
"uid": 70
}
],
"declared_volumes": [
"rallly_postgres_data"
],
"env_keys": [
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SECRET_PASSWORD",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,95 @@
{
"probe": {
"app": "recipe-importer",
"containers": [
{
"diff_added": 13,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"data"
],
"changed_count": 2,
"db_signature": false,
"dir": "/",
"files": [
"data"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app",
"files": [
"app"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr",
"files": [
"local"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr/local",
"files": [
"lib"
]
}
],
"diff_token_dirs": [],
"diff_total": 22,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "gitea.dooplex.hu/admin/recipe-importer:v0.9.11",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-recipeimporter_recipe_data",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-recipeimporter_recipe_data/_data",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "recipe-importer",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"recipe_data"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SECRET_KEY",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"NOTHING this app wrote landed in ANY folder the template preserves: all 1 mount(s) across 1 container(s) are empty, yet entries were created in ['/']. Needs adjudication.",
"recipe-importer: this container's mounts are all empty while it created entries in ['/'] \u2014 benign when a sibling container holds the state, worth a look when none does",
"recipe-importer: declared volume /data is EMPTY"
],
"verdict": "UNDETERMINED",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,248 @@
{
"probe": {
"app": "romm",
"containers": [
{
"diff_added": 13,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/",
"files": [
"root",
"etc"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc",
"files": [
"nginx"
]
},
{
"added": [
".gunicorn"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root",
"files": [
".gunicorn"
]
},
{
"added": [
"gunicorn.ctl"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root/.gunicorn",
"files": [
"gunicorn.ctl"
]
}
],
"diff_token_dirs": [],
"diff_total": 19,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "rommapp/romm:5.0.0",
"mounts": [
{
"class": "anonymous",
"files": 0,
"name": "1ef425b6ade46b1849fdb2b3f632ed8640a9cb2f684686c1a175028a50ee706a",
"sample": [],
"source": "/var/lib/docker/volumes/1ef425b6ade46b1849fdb2b3f632ed8640a9cb2f684686c1a175028a50ee706a/_data",
"target": "/redis-data",
"writable_by_app": "yes"
},
{
"class": "anonymous",
"files": 0,
"name": "59a9958f0796e5ad06453b0ccf4b66018aa1897c68e3b646f3f469f221060752",
"sample": [],
"source": "/var/lib/docker/volumes/59a9958f0796e5ad06453b0ccf4b66018aa1897c68e3b646f3f469f221060752/_data",
"target": "/romm",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/hdd/userdata/roms",
"target": "/romm/library",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/hdd/appdata/romm/resources",
"target": "/romm/resources",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 1,
"name": "volgate-romm_romm_config",
"sample": [
"config.yml"
],
"source": "/var/lib/docker/volumes/volgate-romm_romm_config/_data",
"target": "/romm/config",
"writable_by_app": "yes"
}
],
"name": "romm",
"restarts": null,
"status": "running",
"uid": 0
},
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 999,
"health": "healthy",
"image": "mariadb:11.4",
"mounts": [
{
"class": "named-declared",
"files": 271,
"name": "volgate-romm_romm_db_data",
"sample": [
"undo002",
"tc.log",
"mariadb_upgrade_info",
"ibtmp1",
"aria_log.00000001",
"multi-master.info",
"ddl_recovery.log",
"ib_logfile0",
"undo003",
"ibdata1",
".my-healthcheck.cnf",
"aria_log_control",
"undo001",
"ib_buffer_pool",
"sys/x@0024wait_classes_global_by_latency.frm",
"sys/processlist.frm",
"sys/session.frm",
"sys/memory_by_host_by_current_bytes.frm",
"sys/user_summary.frm",
"sys/waits_global_by_latency.frm",
"sys/x@0024statement_analysis.frm",
"sys/x@0024host_summary.frm",
"sys/schema_unused_indexes.frm",
"sys/user_summary_by_file_io_type.frm",
"sys/memory_by_thread_by_current_bytes.frm",
"sys/x@0024statements_with_full_table_scans.frm",
"sys/wait_classes_global_by_avg_latency.frm",
"sys/x@0024schema_table_statistics.frm",
"sys/x@0024statements_with_temp_tables.frm",
"sys/schema_auto_increment_columns.frm",
"sys/x@0024ps_schema_table_statistics_io.frm",
"sys/x@0024memory_by_host_by_current_bytes.frm",
"sys/statements_with_runtimes_in_95th_percentile.frm",
"sys/x@0024statements_with_errors_or_warnings.frm",
"sys/waits_by_user_by_latency.frm",
"sys/x@0024io_global_by_file_by_bytes.frm",
"sys/innodb_buffer_stats_by_table.frm",
"sys/user_summary_by_statement_type.frm",
"sys/statements_with_errors_or_warnings.frm",
"sys/sys_config.MAD"
],
"source": "/var/lib/docker/volumes/volgate-romm_romm_db_data/_data",
"target": "/var/lib/mysql",
"writable_by_app": "yes"
}
],
"name": "romm-db",
"restarts": null,
"status": "running",
"uid": 999
},
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "redis:7-alpine",
"mounts": [
{
"class": "named-declared",
"files": 4,
"name": "volgate-romm_romm_redis_data",
"sample": [
"dump.rdb",
"appendonlydir/appendonly.aof.1.base.rdb",
"appendonlydir/appendonly.aof.1.incr.aof",
"appendonlydir/appendonly.aof.manifest"
],
"source": "/var/lib/docker/volumes/volgate-romm_romm_redis_data/_data",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "romm-redis",
"restarts": null,
"status": "running",
"uid": 999
}
],
"declared_volumes": [
"romm_config",
"romm_db_data",
"romm_redis_data"
],
"env_keys": [
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"MYSQL_ROOT_PASSWORD",
"ROMM_AUTH_SECRET_KEY",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,63 @@
{
"probe": {
"app": "seerr",
"containers": [
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "fallenbagel/jellyseerr:2.7.3",
"mounts": [
{
"class": "named-declared",
"files": 11,
"name": "volgate-seerr_seerr_config",
"sample": [
"settings.json",
"DOCKER",
"db/db.sqlite3-wal",
"db/db.sqlite3",
"db/db.sqlite3-shm",
"logs/.machinelogs.json",
"logs/jellyseerr.log",
"logs/.20136e5b8544ec13f7fc29ce3d35150d597108bb-audit.json",
"logs/jellyseerr-2026-08-02.log",
"logs/.machinelogs-2026-08-02.json",
"logs/.4295fcfc416647ffc3751a1d488b45a096cf2d4f-audit.json"
],
"source": "/var/lib/docker/volumes/volgate-seerr_seerr_config/_data",
"target": "/app/config",
"writable_by_app": "yes"
}
],
"name": "seerr",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"seerr_config"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,155 @@
{
"probe": {
"app": "sonarr",
"containers": [
{
"diff_added": 209,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"downloads"
],
"changed_count": 5,
"db_signature": false,
"dir": "/",
"files": [
"downloads"
]
},
{
"added": [],
"changed_count": 4,
"db_signature": false,
"dir": "/etc",
"files": [
"group-",
"s6-overlay",
"passwd-",
"crontabs"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/crontabs",
"files": [
"root"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/s6-overlay",
"files": [
"s6-rc.d"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/s6-overlay/s6-rc.d",
"files": [
"init-adduser"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc/s6-overlay/s6-rc.d/init-adduser",
"files": [
"branding"
]
}
],
"diff_token_dirs": [
{
"added": [
"tv"
],
"changed_count": 0,
"db_signature": false,
"dir": "/media",
"files": [
"tv"
]
}
],
"diff_total": 224,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "lscr.io/linuxserver/sonarr:4.0.19",
"mounts": [
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/hdd/userdata/media/tv",
"target": "/media/tv",
"writable_by_app": "yes"
},
{
"class": "bind",
"files": 0,
"name": null,
"sample": [],
"source": "/srv/felhom-gate/hdd/userdata/downloads",
"target": "/downloads",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 11,
"name": "volgate-sonarr_sonarr_config",
"sample": [
"logs.db-shm",
"sonarr.db",
"logs.db",
"sonarr.pid",
"logs.db-wal",
"sonarr.db-wal",
"sonarr.db-shm",
"config.xml",
"logs/sonarr.txt",
"logs/sonarr.debug.txt",
"asp/key-4d541e64-de4d-421d-a8f7-8c05ed629e0c.xml"
],
"source": "/var/lib/docker/volumes/volgate-sonarr_sonarr_config/_data",
"target": "/config",
"writable_by_app": "yes"
}
],
"name": "sonarr",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"sonarr_config"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"sonarr: writable-layer writes at /media (path suggests state, no database signature \u2014 judgement needed): ['tv']"
],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,231 @@
{
"probe": {
"app": "sparkyfitness",
"containers": [
{
"diff_added": 11,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 3,
"db_signature": false,
"dir": "/",
"files": [
"etc",
"run",
"var"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc",
"files": [
"nginx"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/var",
"files": [
"cache"
]
}
],
"diff_token_dirs": [],
"diff_total": 19,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "codewithcj/sparkyfitness:v0.17.3",
"mounts": [],
"name": "sparkyfitness",
"restarts": null,
"status": "running",
"uid": 0
},
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 70,
"health": "healthy",
"image": "postgres:15-alpine",
"mounts": [
{
"class": "named-declared",
"files": 1815,
"name": "volgate-sparkyfitness_sparkyfitness_db_data",
"sample": [
"pgdata/postmaster.opts",
"pgdata/postgresql.conf",
"pgdata/postgresql.auto.conf",
"pgdata/pg_ident.conf",
"pgdata/pg_hba.conf",
"pgdata/postmaster.pid",
"pgdata/PG_VERSION",
"pgdata/base/1/826",
"pgdata/base/1/2996",
"pgdata/base/1/3764",
"pgdata/base/1/2610_fsm",
"pgdata/base/1/3603_fsm",
"pgdata/base/1/1249_vm",
"pgdata/base/1/3600_fsm",
"pgdata/base/1/13506_vm",
"pgdata/base/1/3602",
"pgdata/base/1/6228",
"pgdata/base/1/4174",
"pgdata/base/1/4157",
"pgdata/base/1/4146",
"pgdata/base/1/2611",
"pgdata/base/1/2657",
"pgdata/base/1/3079_vm",
"pgdata/base/1/1247_vm",
"pgdata/base/1/13501_fsm",
"pgdata/base/1/1259",
"pgdata/base/1/3601_fsm",
"pgdata/base/1/1417",
"pgdata/base/1/4155",
"pgdata/base/1/2668",
"pgdata/base/1/13491_fsm",
"pgdata/base/1/2831",
"pgdata/base/1/2841",
"pgdata/base/1/3607",
"pgdata/base/1/2836",
"pgdata/base/1/1255_fsm",
"pgdata/base/1/2615_vm",
"pgdata/base/1/3575",
"pgdata/base/1/2605_vm",
"pgdata/base/1/2670"
],
"source": "/var/lib/docker/volumes/volgate-sparkyfitness_sparkyfitness_db_data/_data",
"target": "/var/lib/postgresql/data",
"writable_by_app": "yes"
}
],
"name": "sparkyfitness-db",
"restarts": null,
"status": "running",
"uid": 70
},
{
"diff_added": 392,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"app"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app",
"files": [
"SparkyFitnessServer"
]
},
{
"added": [
"backup",
"temp_uploads",
"uploads"
],
"changed_count": 0,
"db_signature": false,
"dir": "/app/SparkyFitnessServer",
"files": [
"backup",
"temp_uploads",
"uploads"
]
}
],
"diff_token_dirs": [],
"diff_total": 395,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "codewithcj/sparkyfitness_server:v0.17.3",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-sparkyfitness_sparkyfitness_uploads",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-sparkyfitness_sparkyfitness_uploads/_data",
"target": "/app/SparkyFitnessServer/uploads",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 0,
"name": "volgate-sparkyfitness_sparkyfitness_backup",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-sparkyfitness_sparkyfitness_backup/_data",
"target": "/app/SparkyFitnessServer/backup",
"writable_by_app": "yes"
}
],
"name": "sparkyfitness-server",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"sparkyfitness_backup",
"sparkyfitness_db_data",
"sparkyfitness_uploads"
],
"env_keys": [
"API_ENCRYPTION_KEY",
"APP_DB_PASSWORD",
"BETTER_AUTH_SECRET",
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"sparkyfitness-server: this container's mounts are all empty while it created entries in ['/app/SparkyFitnessServer'] \u2014 benign when a sibling container holds the state, worth a look when none does",
"sparkyfitness-server: declared volume /app/SparkyFitnessServer/uploads is EMPTY",
"sparkyfitness-server: declared volume /app/SparkyFitnessServer/backup is EMPTY"
],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,263 @@
{
"probe": {
"app": "tandoor",
"containers": [
{
"diff_added": 527,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/",
"files": [
"opt",
"usr"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/opt",
"files": [
"recipes"
]
},
{
"added": [
"mediafiles",
"staticfiles"
],
"changed_count": 3,
"db_signature": false,
"dir": "/opt/recipes",
"files": [
"mediafiles",
"staticfiles"
]
},
{
"added": [],
"changed_count": 7,
"db_signature": false,
"dir": "/opt/recipes/cookbook",
"files": [
"views",
"migrations",
"templatetags",
"integration",
"provider",
"connectors",
"helper"
]
},
{
"added": [
"Recipes.conf"
],
"changed_count": 0,
"db_signature": false,
"dir": "/opt/recipes/http.d",
"files": [
"Recipes.conf"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr",
"files": [
"local"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr/local",
"files": [
"lib"
]
}
],
"diff_token_dirs": [],
"diff_total": 576,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/tandoorrecipes/recipes:2.6.13",
"mounts": [
{
"class": "named-declared",
"files": 3047,
"name": "volgate-tandoor_tandoor_static",
"sample": [
"staticfiles.json",
"vue3/service-worker.js.gz",
"vue3/registerSW.js.gz",
"vue3/service-worker.js",
"vue3/manifest.484f96e63b3b.webmanifest",
"vue3/manifest.484f96e63b3b.webmanifest.gz",
"vue3/manifest.77a5899585d8.json.gz",
"vue3/service-worker.e1a4252df0ae.js.gz",
"vue3/registerSW.be6aad568a9d.js",
"vue3/registerSW.js",
"vue3/manifest.webmanifest",
"vue3/manifest.webmanifest.gz",
"vue3/service-worker.e1a4252df0ae.js",
"vue3/registerSW.be6aad568a9d.js.gz",
"vue3/manifest.json.gz",
"vue3/manifest.77a5899585d8.json",
"vue3/manifest.json",
"vue3/assets/PantryPage-ClGNwpHL.80923c1ff539.js.gz",
"vue3/assets/DatabaseLinkCol-d8pnKjbf.js.gz",
"vue3/assets/fontello-BxS_W-ym.86b6414dad9e.svg.gz",
"vue3/assets/VFileUpload-7CWUohzn.d182bb8e4f03.css",
"vue3/assets/fa-regular-400-DZaxPHgR.ttf.gz",
"vue3/assets/number_utils-DFmVVcK0.js.gz",
"vue3/assets/ja-Cqm3qbrP.d617fa524f97.js",
"vue3/assets/ModelListPage-xoBv_A6i.4681a991ae27.js",
"vue3/assets/et-zY9CrDMt.1761c6eb5f48.js",
"vue3/assets/fa-regular-400-BjRzuEpd.89672701a587.woff2",
"vue3/assets/ShoppingListView-C0_akhap.js",
"vue3/assets/VOverlay-CKBxglwy.b98729efffd0.css.gz",
"vue3/assets/ClosableHelpAlert-BoN8dDrm.js.gz",
"vue3/assets/VColorPicker-DoVATq5z.css.gz",
"vue3/assets/ja-Cqm3qbrP.js",
"vue3/assets/position-D7bmUCsu.f212789ebec5.css",
"vue3/assets/number_utils-Brwft-8t.css",
"vue3/assets/SpaceSettings-BPOt7vl3.ab2d8e61f937.js.gz",
"vue3/assets/InviteLinkEditor-BZ7NMcrL.19f59c5d2292.js.gz",
"vue3/assets/hu-DlZ4REsp.c1bc941c31dc.js.gz",
"vue3/assets/fileFilter-JaX38xV6.js.gz",
"vue3/assets/VBtn-rFOjfrXe.df1b89399b11.css",
"vue3/assets/VDataTableServer-BYvhcs5d.js.gz"
],
"source": "/var/lib/docker/volumes/volgate-tandoor_tandoor_static/_data",
"target": "/opt/recipes/staticfiles",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 0,
"name": "volgate-tandoor_tandoor_media",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-tandoor_tandoor_media/_data",
"target": "/opt/recipes/mediafiles",
"writable_by_app": "yes"
}
],
"name": "tandoor",
"restarts": null,
"status": "running",
"uid": 0
},
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 70,
"health": "healthy",
"image": "postgres:16-alpine",
"mounts": [
{
"class": "named-declared",
"files": 1984,
"name": "volgate-tandoor_tandoor_postgres_data",
"sample": [
"postmaster.opts",
"postgresql.conf",
"postgresql.auto.conf",
"pg_ident.conf",
"pg_hba.conf",
"postmaster.pid",
"PG_VERSION",
"base/1/826",
"base/1/2996",
"base/1/3764",
"base/1/2610_fsm",
"base/1/3603_fsm",
"base/1/1249_vm",
"base/1/3600_fsm",
"base/1/13512",
"base/1/3602",
"base/1/6228",
"base/1/4174",
"base/1/4157",
"base/1/4146",
"base/1/2611",
"base/1/2657",
"base/1/3079_vm",
"base/1/1247_vm",
"base/1/1259",
"base/1/3601_fsm",
"base/1/1417",
"base/1/4155",
"base/1/2668",
"base/1/2831",
"base/1/2841",
"base/1/3607",
"base/1/2836",
"base/1/1255_fsm",
"base/1/2615_vm",
"base/1/3575",
"base/1/2605_vm",
"base/1/2670",
"base/1/6106",
"base/1/4163"
],
"source": "/var/lib/docker/volumes/volgate-tandoor_tandoor_postgres_data/_data",
"target": "/var/lib/postgresql/data",
"writable_by_app": "yes"
}
],
"name": "tandoor-postgres",
"restarts": null,
"status": "running",
"uid": 70
}
],
"declared_volumes": [
"tandoor_media",
"tandoor_postgres_data",
"tandoor_static"
],
"env_keys": [
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SECRET_KEY",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"tandoor: declared volume /opt/recipes/mediafiles is EMPTY"
],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,94 @@
{
"probe": {
"app": "termix",
"containers": [
{
"diff_added": 9,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 2,
"db_signature": false,
"dir": "/",
"files": [
"etc",
"app"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app",
"files": [
"html"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app/html",
"files": [
"sw.js"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/etc",
"files": [
"group-"
]
}
],
"diff_token_dirs": [],
"diff_total": 17,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "ghcr.io/lukegus/termix:2.5.0",
"mounts": [
{
"class": "named-declared",
"files": 4,
"name": "volgate-termix_termix_data",
"sample": [
"db.sqlite.encrypted",
".env",
"opkssh/version.txt",
"opkssh/opkssh-linux-amd64"
],
"source": "/var/lib/docker/volumes/volgate-termix_termix_data/_data",
"target": "/app/data",
"writable_by_app": "yes"
}
],
"name": "termix",
"restarts": null,
"status": "running",
"uid": 1000
}
],
"declared_volumes": [
"termix_data"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,54 @@
{
"probe": {
"app": "uptime-kuma",
"containers": [
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "louislam/uptime-kuma:2.4.0",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-uptimekuma_uptime_kuma_data",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-uptimekuma_uptime_kuma_data/_data",
"target": "/app/data",
"writable_by_app": "yes"
}
],
"name": "uptime-kuma",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"uptime_kuma_data"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"nothing was written to any mount and nothing data-classified in any writable layer \u2014 the app produced no data to locate. Health is not data: this is UNDETERMINED, not CLEAN",
"uptime-kuma: declared volume /app/data is EMPTY"
],
"verdict": "UNDETERMINED",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,58 @@
{
"probe": {
"app": "vaultwarden",
"containers": [
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "vaultwarden/server:1.36.0-alpine",
"mounts": [
{
"class": "named-declared",
"files": 4,
"name": "volgate-vaultwarden_vaultwarden_data",
"sample": [
"rsa_key.pem",
"db.sqlite3-wal",
"db.sqlite3",
"db.sqlite3-shm"
],
"source": "/var/lib/docker/volumes/volgate-vaultwarden_vaultwarden_data/_data",
"target": "/data",
"writable_by_app": "yes"
}
],
"name": "vaultwarden",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"vaultwarden_data"
],
"env_keys": [
"ADMIN_TOKEN",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SIGNUPS_ALLOWED",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,100 @@
{
"probe": {
"app": "vikunja",
"containers": [
{
"diff_added": 4,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"db"
],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"db"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/app",
"files": [
"vikunja"
]
},
{
"added": [
"files"
],
"changed_count": 0,
"db_signature": false,
"dir": "/app/vikunja",
"files": [
"files"
]
}
],
"diff_token_dirs": [],
"diff_total": 6,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": null,
"image": "vikunja/vikunja:2.3.0",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-vikunja_vikunja_data",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-vikunja_vikunja_data/_data",
"target": "/app/vikunja/files",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 3,
"name": "volgate-vikunja_vikunja_db",
"sample": [
"vikunja.db-shm",
"vikunja.db-wal",
"vikunja.db"
],
"source": "/var/lib/docker/volumes/volgate-vikunja_vikunja_db/_data",
"target": "/db",
"writable_by_app": "yes"
}
],
"name": "vikunja",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"vikunja_data",
"vikunja_db"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH",
"VIKUNJA_SERVICE_JWTSECRET"
],
"exercise": [],
"ports": []
},
"reasons": [
"vikunja: declared volume /app/vikunja/files is EMPTY"
],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,194 @@
{
"probe": {
"app": "wanderer",
"containers": [
{
"diff_added": 6,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"root"
]
},
{
"added": [
".npm"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root",
"files": [
".npm"
]
}
],
"diff_token_dirs": [],
"diff_total": 8,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "unhealthy",
"image": "flomp/wanderer-web:v0.20.0",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-wanderer_wanderer_uploads",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-wanderer_wanderer_uploads/_data",
"target": "/app/uploads",
"writable_by_app": "yes"
}
],
"name": "wanderer",
"restarts": null,
"status": "running",
"uid": 0
},
{
"diff_added": 3,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"pb_data",
"data"
],
"changed_count": 0,
"db_signature": false,
"dir": "/",
"files": [
"pb_data",
"data"
]
}
],
"diff_token_dirs": [
{
"added": [
"plugins"
],
"changed_count": 0,
"db_signature": false,
"dir": "/data",
"files": [
"plugins"
]
}
],
"diff_total": 3,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "flomp/wanderer-db:v0.20.0",
"mounts": [
{
"class": "named-declared",
"files": 6,
"name": "volgate-wanderer_wanderer_data",
"sample": [
"auxiliary.db-wal",
"data.db",
"data.db-wal",
"auxiliary.db",
"auxiliary.db-shm",
"data.db-shm"
],
"source": "/var/lib/docker/volumes/volgate-wanderer_wanderer_data/_data",
"target": "/pb_data",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 0,
"name": "volgate-wanderer_wanderer_plugins",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-wanderer_wanderer_plugins/_data",
"target": "/data/plugins",
"writable_by_app": "yes"
}
],
"name": "wanderer-db",
"restarts": null,
"status": "running",
"uid": 0
},
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "getmeili/meilisearch:v1.36.0",
"mounts": [
{
"class": "named-declared",
"files": 11,
"name": "volgate-wanderer_wanderer_meili_data",
"sample": [
"data.ms/VERSION",
"data.ms/indexes/a0fe8809-d547-4e9f-9b13-f5962d76ee3f/data.mdb",
"data.ms/indexes/a0fe8809-d547-4e9f-9b13-f5962d76ee3f/lock.mdb",
"data.ms/indexes/45aacc63-1820-432b-9eb5-027bb1f94f5f/data.mdb",
"data.ms/indexes/45aacc63-1820-432b-9eb5-027bb1f94f5f/lock.mdb",
"data.ms/indexes/a982b080-60f2-4811-a993-0e235ea2a5b9/data.mdb",
"data.ms/indexes/a982b080-60f2-4811-a993-0e235ea2a5b9/lock.mdb",
"data.ms/auth/data.mdb",
"data.ms/auth/lock.mdb",
"data.ms/tasks/data.mdb",
"data.ms/tasks/lock.mdb"
],
"source": "/var/lib/docker/volumes/volgate-wanderer_wanderer_meili_data/_data",
"target": "/meili_data",
"writable_by_app": "yes"
}
],
"name": "wanderer-search",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"wanderer_data",
"wanderer_meili_data",
"wanderer_plugins",
"wanderer_uploads"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"MEILI_MASTER_KEY",
"POCKETBASE_ENCRYPTION_KEY",
"SUBDOMAIN",
"SUBDOMAIN_DB",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"wanderer: unhealthy",
"wanderer: this container's mounts are all empty while it created entries in ['/root'] \u2014 benign when a sibling container holds the state, worth a look when none does",
"wanderer: declared volume /app/uploads is EMPTY",
"wanderer-db: declared volume /data/plugins is EMPTY",
"wanderer-db: writable-layer writes at /data (path suggests state, no database signature \u2014 judgement needed): ['plugins']"
],
"verdict": "UNDETERMINED",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,66 @@
{
"probe": {
"app": "wger",
"containers": [
{
"diff_added": 0,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [],
"diff_token_dirs": [],
"diff_total": 0,
"diff_unresolved": [],
"exit": 0,
"gid": 1000,
"health": "healthy",
"image": "wger/server:2.6",
"mounts": [
{
"class": "named-declared",
"files": 1,
"name": "volgate-wger_wger_data",
"sample": [
"database.sqlite"
],
"source": "/var/lib/docker/volumes/volgate-wger_wger_data/_data",
"target": "/home/wger/db",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 0,
"name": "volgate-wger_wger_media",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-wger_wger_media/_data",
"target": "/home/wger/media",
"writable_by_app": "yes"
}
],
"name": "wger",
"restarts": null,
"status": "running",
"uid": 1000
}
],
"declared_volumes": [
"wger_data",
"wger_media"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SECRET_KEY",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"wger: declared volume /home/wger/media is EMPTY"
],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,163 @@
{
"probe": {
"app": "wishlist",
"containers": [
{
"diff_added": 35,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [
"data"
],
"changed_count": 2,
"db_signature": false,
"dir": "/",
"files": [
"data"
]
},
{
"added": [
".config",
".local"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root",
"files": [
".config",
".local"
]
},
{
"added": [
"caddy"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root/.config",
"files": [
"caddy"
]
},
{
"added": [
"autosave.json"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root/.config/caddy",
"files": [
"autosave.json"
]
},
{
"added": [
"share"
],
"changed_count": 0,
"db_signature": false,
"dir": "/root/.local",
"files": [
"share"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr",
"files": [
"src"
]
},
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/usr/src",
"files": [
"app"
]
},
{
"added": [
"data",
"uploads"
],
"changed_count": 0,
"db_signature": false,
"dir": "/usr/src/app",
"files": [
"data",
"uploads"
]
}
],
"diff_token_dirs": [],
"diff_total": 45,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/cmintey/wishlist:v0.66.0",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-wishlist_wishlist_data",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-wishlist_wishlist_data/_data",
"target": "/data",
"writable_by_app": "yes"
},
{
"class": "anonymous",
"files": 0,
"name": "bef31c91bf46c66ba902cc07e89fbd3032b67fd68264bd04afcb1f3ca7cce0c9",
"sample": [],
"source": "/var/lib/docker/volumes/bef31c91bf46c66ba902cc07e89fbd3032b67fd68264bd04afcb1f3ca7cce0c9/_data",
"target": "/usr/src/app/uploads",
"writable_by_app": "yes"
},
{
"class": "anonymous",
"files": 1,
"name": "782ab526684eaca336b6bfc3226ada078e567bce907a5e17b0782b35e38f016e",
"sample": [
"prod.db"
],
"source": "/var/lib/docker/volumes/782ab526684eaca336b6bfc3226ada078e567bce907a5e17b0782b35e38f016e/_data",
"target": "/usr/src/app/data",
"writable_by_app": "yes"
}
],
"name": "wishlist",
"restarts": null,
"status": "running",
"uid": 0
}
],
"declared_volumes": [
"wishlist_data"
],
"env_keys": [
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"wishlist: 1 file(s) in an ANONYMOUS volume at /usr/src/app/data \u2014 not in the compose `volumes:` block, so it is never backed up and a redeploy orphans it",
"wishlist: declared volume /data is EMPTY"
],
"verdict": "BROKEN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}
@@ -0,0 +1,170 @@
{
"probe": {
"app": "zipline",
"containers": [
{
"diff_added": 3,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"zipline"
]
},
{
"added": [
"uploads",
"public"
],
"changed_count": 0,
"db_signature": false,
"dir": "/zipline",
"files": [
"uploads",
"public"
]
}
],
"diff_token_dirs": [],
"diff_total": 5,
"diff_unresolved": [],
"exit": 0,
"gid": 0,
"health": "healthy",
"image": "ghcr.io/diced/zipline:4.6.1",
"mounts": [
{
"class": "named-declared",
"files": 0,
"name": "volgate-zipline_zipline_uploads",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-zipline_zipline_uploads/_data",
"target": "/zipline/uploads",
"writable_by_app": "yes"
},
{
"class": "named-declared",
"files": 0,
"name": "volgate-zipline_zipline_public",
"sample": [],
"source": "/var/lib/docker/volumes/volgate-zipline_zipline_public/_data",
"target": "/zipline/public",
"writable_by_app": "yes"
}
],
"name": "zipline",
"restarts": null,
"status": "running",
"uid": 0
},
{
"diff_added": 2,
"diff_benign_db_touches": [],
"diff_data_dirs": [],
"diff_other_dirs": [
{
"added": [],
"changed_count": 1,
"db_signature": false,
"dir": "/",
"files": [
"run"
]
}
],
"diff_token_dirs": [],
"diff_total": 4,
"diff_unresolved": [],
"exit": 0,
"gid": 70,
"health": "healthy",
"image": "postgres:16-alpine",
"mounts": [
{
"class": "named-declared",
"files": 1357,
"name": "volgate-zipline_zipline_postgres_data",
"sample": [
"postmaster.opts",
"postgresql.conf",
"postgresql.auto.conf",
"pg_ident.conf",
"pg_hba.conf",
"postmaster.pid",
"PG_VERSION",
"base/1/826",
"base/1/2996",
"base/1/3764",
"base/1/2610_fsm",
"base/1/3603_fsm",
"base/1/1249_vm",
"base/1/3600_fsm",
"base/1/13512",
"base/1/3602",
"base/1/6228",
"base/1/4174",
"base/1/4157",
"base/1/4146",
"base/1/2611",
"base/1/2657",
"base/1/3079_vm",
"base/1/1247_vm",
"base/1/1259",
"base/1/3601_fsm",
"base/1/1417",
"base/1/4155",
"base/1/2668",
"base/1/pg_internal.init",
"base/1/2831",
"base/1/2841",
"base/1/3607",
"base/1/2836",
"base/1/1255_fsm",
"base/1/2615_vm",
"base/1/3575",
"base/1/2605_vm",
"base/1/2670",
"base/1/6106"
],
"source": "/var/lib/docker/volumes/volgate-zipline_zipline_postgres_data/_data",
"target": "/var/lib/postgresql/data",
"writable_by_app": "yes"
}
],
"name": "zipline-postgres",
"restarts": null,
"status": "running",
"uid": 70
}
],
"declared_volumes": [
"zipline_postgres_data",
"zipline_public",
"zipline_uploads"
],
"env_keys": [
"CORE_SECRET",
"DB_PASSWORD",
"DOMAIN",
"HDD_PATH",
"IMPORT_PATH",
"SUBDOMAIN",
"TZ",
"USERDATA_PATH"
],
"exercise": [],
"ports": []
},
"reasons": [
"zipline: this container's mounts are all empty while it created entries in ['/zipline'] \u2014 benign when a sibling container holds the state, worth a look when none does",
"zipline: declared volume /zipline/uploads is EMPTY",
"zipline: declared volume /zipline/public is EMPTY"
],
"verdict": "CLEAN",
"verdict_recomputed_by": "check-volume-persistence.py classify() at final rules"
}