122bbeea48
gates / gates (push) Successful in 1s
papra mounted papra_data:/app/data while the application writes to /app/app-data, so its database sat in the container's writable layer: lost on redeploy, and tarred nightly as an empty directory while the healthcheck stayed green. Last of the three apps R-156 convicted. Decided from the IMAGE, not the README. docker inspect of ghcr.io/papra-hq/papra:26.6.1-rootless gives WORKDIR=/app and all three data paths under ./app-data (DATABASE_URL, DOCUMENT_STORAGE_FILESYSTEM_ROOT, PAPRA_CONFIG_DIR) — and /app/data does not exist in the image at all. Reconfiguring the app to write to /app/data was available and deliberately not taken: it enumerates data paths, so a fourth added upstream would escape to the writable layer again, silently — this defect re-armed. Mounting the app's own data ROOT captures every current and future path by construction. Precondition checked rather than inherited: docker ps -a (including stopped) on BOTH demo guests, plus the hub fleet view (two enrolled hosts, zero papra) — both boxes were wiped and rebuilt today, so the 2 August evidence was re-measured. Proven by the runtime gate in both directions: CLEAN with the self-test passing, and BROKEN when the mount is reverted, with the exact R-156 evidence. Full catalog_gates.py papra: all three gates OK.
63 lines
2.6 KiB
YAML
63 lines
2.6 KiB
YAML
# Papra - Minimalista dokumentumtár és rendszerező
|
|
# Domain: ${SUBDOMAIN}.${DOMAIN}
|
|
# Database: None (file-based)
|
|
# RAM: ~50M (mem_limit: 256M) | Pi-compatible: Yes
|
|
#
|
|
# Environment variables:
|
|
# DOMAIN - Your domain (e.g., demo-felhom.eu)
|
|
|
|
services:
|
|
papra:
|
|
image: ghcr.io/papra-hq/papra:26.6.1-rootless
|
|
container_name: papra
|
|
restart: unless-stopped
|
|
environment:
|
|
- TZ=Europe/Budapest
|
|
- APP_BASE_URL=https://${SUBDOMAIN}.${DOMAIN}
|
|
- AUTH_SECRET=${AUTH_SECRET}
|
|
volumes:
|
|
# R-156: a csatolási pont /app/app-data, NEM /app/data. A képfájl WORKDIR-je
|
|
# /app, és MINDHÁROM adatútvonal az ./app-data alá mutat (a képfájlból
|
|
# kiolvasva, nem a README-ből): DATABASE_URL=file:./app-data/db/db.sqlite,
|
|
# DOCUMENT_STORAGE_FILESYSTEM_ROOT=./app-data/documents, PAPRA_CONFIG_DIR=./app-data.
|
|
# A /app/data könyvtár a képfájlban nem is létezik — a régi csatolás olyan
|
|
# útvonalra mutatott, ahová az alkalmazás soha nem írt, így a db.sqlite a
|
|
# konténer írható rétegében maradt: újratelepítéskor elveszett, a napi mentés
|
|
# pedig üres könyvtárat tarolt, miközben a healthcheck végig zöld volt.
|
|
#
|
|
# Az alkalmazás adatútvonalainak átállítása (/app/data-ra) is járható lett
|
|
# volna, de az HÁROM környezeti változó karbantartását jelentené: ha a
|
|
# felsőbb projekt egy negyedik adatútvonalat vezet be, az megint csendben az
|
|
# írható rétegbe szökne. A gyökér csatolása minden jelenlegi ÉS jövőbeli
|
|
# adatútvonalat elkap. Ellenőrzi: scripts/check-volume-persistence.py.
|
|
- papra_data:/app/app-data
|
|
networks:
|
|
- traefik-public
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 256M
|
|
healthcheck:
|
|
# A papra képfájlban nincs wget és nincs curl — csak node. A korábbi wget
|
|
# próba ezért soha nem futott le, a konténer véglegesen unhealthy maradt,
|
|
# és a Traefik nem irányított rá forgalmat (404).
|
|
test: ["CMD", "node", "-e", "const http=require('http');http.get('http://127.0.0.1:1221',r=>process.exit(r.statusCode<500?0:1)).on('error',()=>process.exit(1))"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 30s
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.papra.rule=Host(`${SUBDOMAIN}.${DOMAIN}`)"
|
|
- "traefik.http.routers.papra.entrypoints=websecure"
|
|
- "traefik.http.routers.papra.tls=true"
|
|
- "traefik.http.routers.papra.tls.certresolver=letsencrypt"
|
|
- "traefik.http.services.papra.loadbalancer.server.port=1221"
|
|
|
|
volumes:
|
|
papra_data:
|
|
|
|
networks:
|
|
traefik-public:
|
|
external: true
|