- Migrate all 127 non-reserved docs to OKF v0.1 frontmatter (type/description/tags/timestamp); fix 13 YAML issues, 2 duplicate-FM blocks, strip reserved-page FM - Restructure log.md to OKF (## YYYY-MM-DD, newest-first) - Fact-check against scripts/AGENTS.md ground truth: fix 6 false 'Active' banners on retired runbooks, 96->114 GiB GTT, deployment.md vs deploy-plan.py/deploy-remote.sh, Deployment Flow frank-medium=Quadlet, Calibre 9.9.0->9.15.0 + CVE-2025-7404 conflation, Copyparty v1.20.24, RomM 5.3.0 breaking change - Move *arr docs to new FrankBook-Pro/ section (git mv, link-safe) - Write active runbook bodies from ground truth (frank-large, frank-small) - Add 3 research briefs + HTML report: Local TTS and Voice Cloning, AI Job Search and Resume Tools, Most Popular Self-Hosted AI Apps (Jun-Sep 2026) - Add upstream-version rows to ComfyUI/OpenWebUI/Hermes app docs - All 336 tests pass; 136 pages, 0 unresolved wikilinks
70 lines
2.8 KiB
Markdown
70 lines
2.8 KiB
Markdown
---
|
|
type: reference
|
|
description: "All persistent data uses **bind mounts**: a host directory mapped directly into the container."
|
|
tags:
|
|
- architecture
|
|
- storage
|
|
timestamp: 2026-09-01
|
|
---
|
|
|
|
# Storage Policy
|
|
|
|
All persistent data uses **bind mounts**: a host directory mapped directly into the container. No named volumes. This matches the preference of this repo and the existing Gitea stack on Dankclaw.
|
|
|
|
## Why Bind Mounts
|
|
|
|
- The exact host location of every byte is visible and controllable.
|
|
- Backups are a simple `tar` of known host directories.
|
|
- The data survives container recreation and `podman-compose down`.
|
|
- Ownership is explicit: everything runs as UID 1000 (`dank`) so host tools can read it.
|
|
|
|
## Conventions
|
|
|
|
| Stack | Host data root |
|
|
|-------|----------------|
|
|
| Dankserver | `/home/dank/Containers/<svc>/` (romm, jellyfin, calibre-web, copyparty) |
|
|
| Dankclaw | `/home/dank/Containers/<svc>/` (caddy, gitea, authentik, hermes, …) |
|
|
|
|
This layout was standardized on 2026-09-01. The old `/opt/<service>` roots were
|
|
migrated by the deployers' `migrate_data_root` (merge-move, numeric ownership
|
|
preserved); `/opt` holds no live container data on either host.
|
|
|
|
## Ownership
|
|
|
|
Containers are rootless. Two regimes exist and the deployer must respect both:
|
|
|
|
- **PUID/PGID images** (linuxserver calibre-web, jellyfin): data is owned by
|
|
host uid 1000 (`dank`) — plain `chown` is safe.
|
|
- **Mapped-uid images** (official mariadb, redis, authentik, postgres): files
|
|
land in the subuid range (e.g. 100998 for container uid 999). Renaming such
|
|
a directory requires root (rename needs write on the directory itself) and
|
|
**re-chowning to 1000 breaks the container's internal user**. Migrations
|
|
therefore use `sudo mv` (numeric-preserving) and skip the chown pass
|
|
(`migrate_data_root … keep`).
|
|
|
|
```bash
|
|
stat -c '%u %n' /home/dank/Containers/romm/mariadb # 100998 = mapped, leave it
|
|
```
|
|
|
|
## Secrets
|
|
|
|
Secrets never live in bind-mounted configs that get committed. The quadlet
|
|
convention on both hosts:
|
|
|
|
1. One host-local env file per stack at `/home/dank/Containers/<svc>/env`
|
|
(mode 0600), referenced from the unit's `[Service] EnvironmentFile=` so
|
|
`${VAR}` expansion works at `ExecStart` time; never committed.
|
|
2. `.env` files in the checkout (git-ignored, `.env.example` committed as
|
|
template) for compose-era and Caddy-rendered secrets.
|
|
|
|
Deployed units hold only variable expansions (`${COPAY_ACCOUNT}` …), never
|
|
literals — enforced by the `no secret material` seams. The live Gitea
|
|
database password exists only in `/home/dank/Containers/gitea/env` on
|
|
Dankclaw. A test enforces that it never appears in this repo.
|
|
|
|
## See Also
|
|
|
|
- [[Deployment Flow]]
|
|
- [[Gitea]] — the original bind-mount stack, now on the Containers layout
|
|
- [[Backblaze Integration]] — future backup target for these mounts
|