Files
race b4777a5e4d 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.
2026-08-11 12:09:26 -05:00

137 lines
7.5 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Nextcloud Office — Project Documentation</title>
<link rel="stylesheet" href="assets/style.css">
</head>
<body>
<div id="wrapper">
<ul class="nav">
<li><a href="index.html" class="active">Overview</a></li>
<li><a href="architecture.html">Architecture</a></li>
<li><a href="procedure.html">Procedure</a></li>
<li><a href="troubleshooting.html">Troubleshooting</a></li>
<li><a href="operations.html">Operations</a></li>
</ul>
<h1>Nextcloud Office</h1>
<p>
<span class="tag green">COMPLETE</span>
Deployed <code>office.rmf44.xyz</code> as a Nextcloud All-in-One stack
with Collabora + Whiteboard on <code>homework03</code>, with public
ingress through <code>hawker</code>'s Caddy over a NetBird mesh.
Replaces the retired OnlyOffice container.
<strong>Cutover completed 2026-08-10.</strong>
</p>
<div class="toc">
<h2>Page index</h2>
<ul>
<li><a href="architecture.html">Architecture</a> — topology, container tree, data flow</li>
<li><a href="procedure.html">Procedure</a> — phase-by-phase build + cutover commands</li>
<li><a href="troubleshooting.html">Troubleshooting</a> — every pitfall we hit + the fix</li>
<li><a href="operations.html">Operations</a> — backup, rollback, monitoring, day-2</li>
</ul>
</div>
<h2>The goal</h2>
<p>
Replace the standalone OnlyOffice container on <code>hawker</code>
with a full Nextcloud All-in-One deployment providing file sync,
Collabora-based office editing (Word/Excel/PowerPoint), and the
built-in Whiteboard. Public URL <code>https://office.rmf44.xyz</code>
serves a single domain (no subdomain split). User data lives on
<code>desslok</code> via NFS so existing backup snapshots still apply.
</p>
<h2>At a glance</h2>
<table>
<tr><th>Item</th><th>Value</th></tr>
<tr><td>Hostname</td><td><code>office.rmf44.xyz</code> (single domain)</td></tr>
<tr><td>Stack</td><td>Nextcloud All-in-One, 8 containers (mastercontainer, apache, nextcloud-fcgi, database, redis, collabora, whiteboard, notify-push)</td></tr>
<tr><td>AIO host</td><td><code>homework03 (10.0.0.73)</code>, Debian 13, Docker 29.6.2, 15 GB RAM</td></tr>
<tr><td>Apache port</td><td><code>11000</code> (host-side; mastercontainer owns host :80 for acme)</td></tr>
<tr><td>Public ingress</td><td><code>hawker</code> Caddy <code>office.rmf44.xyz → 100.79.142.164:11000</code> over NetBird</td></tr>
<tr><td>Office suite</td><td>Collabora (via <code>richdocuments</code> + <code>office</code> apps)</td></tr>
<tr><td>Extras enabled</td><td>Whiteboard</td></tr>
<tr><td>Extras disabled</td><td>Talk, Imaginary (previews), ClamAV, Fulltextsearch, Adminer</td></tr>
<tr><td>Storage</td><td>NFSv4.1 from <code>desslok:/slab/container_storage/office</code> mounted at <code>/srv/nc-files/</code> on homework03</td></tr>
<tr><td>Database</td><td>PostgreSQL inside <code>nextcloud-aio-database</code> container, daily <code>pg_dumpall</code> to NFS</td></tr>
<tr><td>RAM footprint</td><td>~6-9 GB on 15 GB host (97% baseline before AIO)</td></tr>
<tr><td>Cutover time</td><td>Caddy block upstream fix (:80 → :11000) ≈ 1 minute</td></tr>
</table>
<h2>Architecture at a glance</h2>
<p><img src="assets/diagrams/topology.svg" alt="Topology — NetBird mesh, AIO on homework03, NFS on desslok" class="diagram"></p>
<p><a href="architecture.html">Full architecture detail →</a></p>
<h2>Why this approach</h2>
<ul>
<li>
<strong>Single domain, no subdomain gymnastics.</strong> AIO's
mastercontainer terminates TLS for the domain validation
endpoint, but it does NOT proxy Nextcloud traffic — Apache does,
on a non-standard port (11000). One Caddy block on hawker
forwards to that port. No <code>office</code> vs <code>nextcloud</code>
split needed.
</li>
<li>
<strong>Data on desslok via NFS.</strong> Existing backup snapshots
cover <code>/slab/container_storage/office</code>; AIO runs
stateless otherwise. The bind-mount pattern keeps everything
portable — destroy the AIO stack and the data is still there.
</li>
<li>
<strong>Mastercontainer owns host :80.</strong> This is mandatory
for AIO's domain-validation flow, but it conflicts with Apache.
Moving Apache to :11000 lets both coexist on the same host.
</li>
<li>
<strong>Own backup pipeline.</strong> AIO's built-in backup feature
is disabled (<code>AIO_DISABLE_BACKUP=true</code>) because the
data is already on NFS — the natural backup target. A daily
systemd timer on <code>hector</code> SSHes to homework03 and
runs <code>pg_dumpall</code> + a config tar + a user-files tar,
all writing back to desslok via NFS.
</li>
<li>
<strong>No adminer sidecar.</strong> The AIO admin UI on :8080
has full container management; an adminer would just be another
admin surface to secure. Dropped.
</li>
</ul>
<h2>What's still on the day-2 list</h2>
<ul>
<li><strong>E2E browser smoke test</strong> — login flow + Collabora document open + whiteboard create verified via API; full UI click-through needs your eyes (the admin password is in the chat).</li>
<li><strong>Additional users</strong> — currently only <code>admin</code>, <code>race</code> (Lord Race), <code>bettyanne</code> in DB. Family members can be added through the user management UI.</li>
<li><strong>Talk container</strong> — disabled to save RAM. If video conferencing is needed later, re-enable via AIO admin UI.</li>
<li><strong>Imaginary (image previews)</strong> — disabled to save RAM. Re-enable if Nextcloud previews become a complaint.</li>
</ul>
<h2>Files &amp; code paths</h2>
<table>
<tr><th>Path</th><th>Host</th><th>What</th></tr>
<tr><td><code>/usr/local/containers/nextcloudaio/docker-compose.yaml</code></td><td>homework03</td><td>Mastercontainer with <code>network_mode: host</code></td></tr>
<tr><td><code>/usr/local/containers/nextcloudaio/nextcloud-aio-{mastercontainer,database,redis,apache,nextcloud,collabora,whiteboard,notify-push,database-dump}/</code></td><td>homework03</td><td>Named docker volume bind targets</td></tr>
<tr><td><code>/srv/nc-files/</code></td><td>homework03</td><td>NFS mount of <code>desslok:/slab/container_storage/office</code>; AIO binds this directly into the nextcloud container at <code>/mnt/ncdata</code> via <code>NEXTCLOUD_DATADIR</code></td></tr>
<tr><td><code>/usr/local/containers/nextcloudaio/nextcloud-aio-nextcloud/</code></td><td>homework03</td><td>Local docker volume bind for the nextcloud container's <code>/var/www/html</code> (AIO-managed app code)</td></tr>
<tr><td><code>/usr/local/bin/office-backup.sh</code></td><td>homework03</td><td>Daily backup script (pgdump + AIO config tar + app volume tar + user files tar)</td></tr>
<tr><td><code>/etc/systemd/system/office-backup.{service,timer}</code></td><td>hector</td><td>Daily 03:30 UTC trigger, SSH to homework03</td></tr>
<tr><td><code>/etc/caddy/Caddyfile</code></td><td>hawker</td><td>Reverse proxy block: <code>office.rmf44.xyz → 100.79.142.164:11000</code></td></tr>
<tr><td><code>/slab/container_storage/office/</code></td><td>desslok</td><td>Live data + <code>backups/</code> subdir</td></tr>
</table>
<p class="footer">
Project deployed 2026-08-10. Documentation modeled on
<code>../gite_replacement/</code>.
</p>
</div>
</body>
</html>