rewire 2026-08-11: single-mount NFS architecture

- topology.svg, container-tree.svg, data-flow.svg: show /srv/nc-files
  bound directly into nextcloud container at /mnt/ncdata (no
  intermediate /mnt/nc-data/nextcloud-data layer).
- architecture.html: explain rewire, update storage table, remove
  pre-rewire 'why two layers' section.
- procedure.html: NEXTCLOUD_DATADIR=/srv/nc-files, no mastercontainer
  bind, add §2.5 Rewire 2026-08-11 with recovery procedure,
  update backup script to also tar local nextcloud app volume,
  fix 4.3 verification (302 -> /login, status.php, file visibility).
- operations.html: 4 backup files now (added aio-nextcloud-app.tar.gz),
  restore procedures updated, single-file restore uses new tar layout.
- troubleshooting.html: add 3 new sections — appdata-missing,
  nextcloud-not-spawning, collabora-discovery-warning.
- request-flow.svg: remove nextcloud/ subdir from NFS write path.
- index.html, README.md: update paths and metadata.
This commit is contained in:
2026-08-11 12:09:26 -05:00
parent d172771aa1
commit b4777a5e4d
10 changed files with 423 additions and 121 deletions
+38 -16
View File
@@ -23,8 +23,9 @@
<p>
Three layers to understand: <strong>network</strong> (public → Caddy →
NetBird → AIO Apache), <strong>containers</strong> (8 AIO processes on
one host, single docker network), and <strong>data flow</strong>
(NFS for everything, plus a postgres dump that hits NFS too).
one host, host network namespace shared with mastercontainer), and
<strong>data flow</strong> (NFS for user files, local ext4 for
everything else, plus a daily postgres dump that lands on NFS).
</p>
<h2>Topology — public ingress</h2>
@@ -58,9 +59,11 @@
<li>
<strong>Storage</strong> — NFSv4.1 from
<code>desslok:/slab/container_storage/office</code> mounted at
<code>/srv/nc-files/</code> on homework03. Subdirs:
<code>nextcloud/</code> for user files, <code>backups/</code> for
daily pgdump + config + user-files tars.
<code>/srv/nc-files</code> on homework03. User files live at
the NFS export root (no intermediate <code>nextcloud/</code>
subdir): <code>admin/</code>, <code>race/</code>,
<code>appdata_*/</code>, plus <code>backups/</code> for the
daily backup pipeline.
</li>
<li>
<strong>Retired (torn down)</strong> — OnlyOffice container
@@ -99,7 +102,7 @@
<tr>
<td><code>nextcloud-aio-nextcloud</code></td>
<td>PHP-FPM + Nextcloud app code</td>
<td><code>./nextcloud-aio-nextcloud/</code> + <code>/mnt/nc-data/nextcloud-data</code> via <code>NEXTCLOUD_DATADIR</code></td>
<td><code>./nextcloud-aio-nextcloud/</code> (local volume) + <code>/srv/nc-files</code> (NFS) → <code>/mnt/ncdata</code></td>
<td>root (entrypoint)</td>
<td>:9000 (PHP-FPM)</td>
</tr>
@@ -172,20 +175,21 @@
<h2>Data flow — where each piece lives</h2>
<p>
Most of AIO's data is on NFS (<code>/srv/nc-files</code> on
homework03). The Postgres database is inside the database
container; its data directory is a docker named-volume bind, not
on NFS — keeping PostgreSQL's WAL writes off NFS is critical for
durability.
Most of AIO's user data is on NFS
(<code>/srv/nc-files</code> on homework03 → container bind at
<code>/mnt/ncdata</code>). Postgres, Redis, and the AIO
mastercontainer's configuration live on local ext4 (named
volumes) — keeping PostgreSQL's WAL writes off NFS is critical
for durability.
</p>
<p><img src="assets/diagrams/data-flow.svg" alt="Data flow — NFS for user files, named volumes for container state" class="diagram"></p>
<table>
<tr><th>Path</th><th>Filesystem</th><th>Why</th></tr>
<tr>
<td><code>/srv/nc-files/nextcloud/</code></td>
<td><code>/srv/nc-files/</code> (NFS root on homework03)</td>
<td>NFSv4.1 from desslok</td>
<td>User-uploaded files. Snapshotted daily via desslok's existing ZFS path.</td>
<td>User-uploaded files live at the export root: <code>admin/</code>, <code>race/</code>, <code>appdata_*/</code>, etc. The nextcloud container binds this path to <code>/mnt/ncdata</code> directly. Snapshotted daily via desslok's ZFS path.</td>
</tr>
<tr>
<td><code>/srv/nc-files/backups/</code></td>
@@ -193,9 +197,9 @@
<td>Daily pgdump + AIO config tar + user-files tar. 14-day retention.</td>
</tr>
<tr>
<td><code>/mnt/nc-data/nextcloud-data/</code></td>
<td><code>/usr/local/containers/nextcloudaio/nextcloud-aio-nextcloud/_data/</code></td>
<td>ext4 (local)</td>
<td>Bind mount, mounted INTO the nextcloud container as <code>/nextcloud-aio</code>. Holds app config, theme, install state.</td>
<td>Local named-volume bind for the nextcloud container. AIO-managed; <code>NEXTCLOUD_DATADIR</code> points at <code>/srv/nc-files</code> separately, NOT at this volume.</td>
</tr>
<tr>
<td><code>/usr/local/containers/nextcloudaio/nextcloud-aio-{mastercontainer,database,redis,apache,...}/</code></td>
@@ -204,6 +208,24 @@
</tr>
</table>
<div class="callout info">
<p>
<strong>Rewire 2026-08-11:</strong> before the rewire, AIO
bind-mounted a <em>third</em> host layer
(<code>/mnt/nc-data/nextcloud-data</code>) into the nextcloud
container, with <code>NEXTCLOUD_DATADIR=/mnt/nc-data/nextcloud-data</code>.
That double-bind worked but had two sharp edges: (a) the
<code>NEXTCLOUD_DATADIR</code> host path and the actual NFS
mount path had to be kept in sync manually; (b) a typo would
silently create an empty datadir, masking the real NFS data
and triggering an "Appdata is not present" crash on next
start. The rewire collapses both to a single layer:
<code>/srv/nc-files</code> is the NFS mount AND the
<code>NEXTCLOUD_DATADIR</code> value — AIO binds it directly
into the nextcloud container at <code>/mnt/ncdata</code>.
</p>
</div>
<div class="callout warn">
<p>
<strong>Why isn't the postgres data on NFS?</strong>
@@ -232,7 +254,7 @@
<li><strong>NetBird tunnel</strong> encapsulates the request in WireGuard (UDP 51820), P2P from hawker to homework03.</li>
<li><strong>AIO Apache</strong> (nextcloud-aio-apache container) terminates the TLS-stripped HTTP and forwards to <code>127.0.0.1:9000</code> (PHP-FPM in nextcloud-aio-nextcloud).</li>
<li><strong>PHP-FPM (Nextcloud)</strong> authenticates the user via the session cookie, authorizes the path under <code>/admin/files/</code>, and writes the file via WebDAV.</li>
<li><strong>NFS write</strong> of the file to <code>/srv/nc-files/nextcloud/admin/files/smoke-test.md</code> on homework03 → <code>/slab/container_storage/office/nextcloud/admin/files/smoke-test.md</code> on desslok.</li>
<li><strong>NFS write</strong> of the file to <code>/srv/nc-files/admin/files/smoke-test.md</code> on homework03 → <code>/slab/container_storage/office/admin/files/smoke-test.md</code> on desslok (nextcloud container's <code>/mnt/ncdata</code> is bound to <code>/srv/nc-files</code> directly).</li>
<li><strong>Response</strong>: <code>HTTP/2 201 Created</code> with empty body (WebDAV semantics).</li>
</ol>