Deploy temporary Atlas Nextcloud and ONLYOFFICE stack

This commit is contained in:
Fabio Scotto di Santolo
2026-10-03 17:42:16 +02:00
parent a00602973c
commit def3dbf313
20 changed files with 1074 additions and 74 deletions

View File

@@ -0,0 +1,105 @@
# Nextcloud on Atlas — design draft
Status: the empty stack was deployed on 2026-10-03, explicitly before the first
scrub. The operator configured DNS/NPM and authorized public cutover; public TLS,
DAV and cross-user file checks passed. Client editing/sync acceptance and consistent
backup/restore validation remain open before family data. iCloud import remains a
separate operation. See `docs/atlas-nextcloud.md` for observed runtime state.
## Confirmed requirements
- Three family members are the eventual scope; provision only two standard user
accounts initially, `fabio` and `chiara`, with the third family user deferred.
Each initial user has a private file space and no administrator privileges.
- Add a separate Nextcloud application administrator account named `admin`, for
administration rather than daily document use. This is distinct from Atlas'
host account of the same name; credentials must not be reused.
- 2FA is optional, not enforced for the accounts. Offer enrollment and recovery
codes; encourage it for the administrator without silently imposing it.
- The three application accounts have been created in the empty deployment.
- No SMTP service is available. Initial deployment will not configure outbound
email or provision a mail server. Email notifications and email-based password
recovery are unavailable until SMTP is explicitly added. Document administrator-
assisted recovery for standard users and a private host-side admin recovery
procedure; do not expose a recovery endpoint or store plaintext passwords.
- Both initial users may add, edit and delete files in the shared `Famiglia`
folder. This does not imply sharing personal calendars or contacts.
- No initial per-user Nextcloud storage quota for `fabio` or `chiara`. Available
space is still bounded by the physical pool and any separately approved dataset
limits; monitor capacity and do not describe this as unlimited physical storage.
- Files, calendars, contacts and Office document editing in the browser.
- iPhone/iPad, Windows and Linux clients.
- Migrate iCloud Drive files, calendars and contacts. The operator estimates
approximately 50 GB of iCloud Drive files, excluding iCloudPD photos; this is
an estimate, not a measured inventory. The files include a mix of Fabio's and
Chiara's data. Migration is explicitly deferred to a separate later operation;
initial deployment must not import iCloud files, calendars or contacts.
Per-account mapping will be decided at migration time. Do not assume ongoing
two-way synchronization with iCloud or extend this scope to iCloud Photos.
- ONLYOFFICE is the chosen editor: browser editing on desktop and the existing
ONLYOFFICE app on iPhone/iPad. Mobile browser editing is not required.
- Temporary Atlas hosting, with eventual migration to Uranus.
- Completed one-time imports/migrations stay outside the steady-state playbook.
## Implemented architecture — public acceptance pending
- Nextcloud application with Files, Calendar, Contacts and an Office connector.
- PostgreSQL database and Redis for locking/cache; deployed versions and pinned
image digests are declared in Atlas host vars and documented in the runbook.
- Dedicated ONLYOFFICE Docs service and its Nextcloud connector. Test real
DOCX/XLSX/PPTX files in desktop browsers and opening/editing/saving through
the mobile ONLYOFFICE app before acceptance. Community Edition is deployed;
internal connector checks passed, but browser/mobile acceptance is still pending.
- Explicit Podman Quadlets managed by Ansible, preferably rootless like existing
Atlas services, subject to image/user namespace/SELinux validation.
- Separate persistent application/configuration, user files, database and cache
storage in the service namespace. Do not expose the managed Nextcloud data
directory as a writable SMB share or let Syncthing modify it directly.
- Approved names: `cloud.fscotto.co` for Nextcloud and `office.fscotto.co` for
ONLYOFFICE Docs. The operator configured DNS, certificates and NPM hosts;
public endpoint and routing checks passed on 2026-10-03.
- Public HTTPS through Prometheus NPM and the existing Aegis gateway only.
No public database/cache ports or directly exposed administrative interfaces.
- Office/Nextcloud callback routing, WebSockets, trusted proxies, JWT authentication
and upload limits must be tested end to end before publication.
- Credentials remain in Vault; never enter passwords or private keys in chat.
## Office decision
The operator already uses ONLYOFFICE on mobile and desktop and selected it for
this project. Desktop browser editing will use ONLYOFFICE Docs integrated with
Nextcloud; mobile editing will use the existing ONLYOFFICE app. The limitation
on Community mobile web editors does not conflict with that requirement.
App integration, permissions, document fidelity and reliable saves still require
acceptance tests; the app is not treated as proof of server-side compatibility.
## Data protection and rollout gates
- The operator explicitly authorized this empty deployment before the first scrub.
Close the data-protection checks before accepting live family data; this limited
exception does not mark the scrub or recovery checks complete.
- Re-check free RAM/CPU/storage and existing workload before choosing limits or quotas.
- Design consistent backups covering configuration, custom apps/themes, user files
and the database. ZFS snapshots alone do not establish application consistency.
- Define a coordinated maintenance/background-job pause and database dump/snapshot
procedure for recurring backups, with failure cleanup and monitoring.
- Confirm ZFS/Borg/USB coverage and independently restore into an isolated environment
before importing family data.
- Define deliberate upgrades and rollback boundaries; do not roll back a database
independently of its matching application/data backup.
- Start with a test account and representative documents; migrate iCloud content
explicitly only after client, sharing, Office and recovery tests pass.
- Plan Uranus transfer separately; do not add permanent one-time migration flags.
## Next decisions, one at a time
1. Validate desktop Office editing/saving, calendar/contact synchronization and
mobile ONLYOFFICE app integration; public empty-stack cutover is verified.
2. Complete protection gates and application-consistent backup/recovery tests.
3. Plan the deferred iCloud migration when explicitly requested.
## Primary references
- [Nextcloud Office installation](https://docs.nextcloud.com/server/stable/admin_manual/office/installation.html)
- [ONLYOFFICE mobile web editor restrictions](https://helpcenter.onlyoffice.com/mobile/android/mobile-web-editors/overview.aspx)
- [Nextcloud backup requirements](https://docs.nextcloud.com/server/stable/admin_manual/maintenance/backup.html)

127
docs/atlas-nextcloud.md Normal file
View File

@@ -0,0 +1,127 @@
# Atlas Nextcloud — public empty-stack cutover
## Observed state, 2026-10-03
The operator explicitly approved an empty deployment before the first monthly
scrub, and subsequently authorized public cutover. No iCloud files, calendars
or contacts have been imported. Public empty-stack validation is not acceptance
of production data before the outstanding protection and recovery checks.
Ansible manages the steady state through `profile_atlas` and the host-local
`atlas_manage_nextcloud: true` declaration. No migration/import flags or helpers
were added. An actual repeat run returned `changed=0`, with no failures.
- Rootless `admin` Quadlets: Nextcloud 33.0.9, PostgreSQL 17.11, Redis 7.4.11 and
ONLYOFFICE Docs Community 9.4.0.129 (image tag 9.4.0.1), on a dedicated network.
- Images are pinned by digest; Calendar 6.6.2, Contacts 8.9.1, ONLYOFFICE connector
10.2.1 and Team Folders 21.0.9 archives are pinned by version and SHA-256.
- Dedicated ZFS namespace: `zpool/services/data/nextcloud`, with separate `app`,
`files`, `database`, `cache` and `office` datasets. No writable SMB/Syncthing
access to the Nextcloud-managed file namespace is provided.
- The `admin` Nextcloud account is an application administrator, distinct from
the host account. `fabio` and `chiara` are standard users in `famiglia`, each
with no initial quota. Team folder `Famiglia` has unlimited quota and group
permission mask 15 (read/create/update/delete, not additional re-sharing).
- Optional TOTP is available; 2FA is not enforced. SMTP is not configured.
- The five-minute user cron timer is active; a manual service run succeeded.
Its `Type=oneshot` means a recurring short-lived job, not a one-time migration.
- Component memory ceilings are Nextcloud 2 GiB, ONLYOFFICE 4 GiB, PostgreSQL
1 GiB and Redis 256 MiB; these are ceilings, not reserved memory or load-test results.
Nextcloud reported installed, no maintenance mode and no pending DB upgrade.
PostgreSQL was healthy; ONLYOFFICE `/healthcheck` returned `true`. The connector's
`onlyoffice:documentserver --check` succeeded using internal routing. JWT is
enabled and matches the dedicated secret; neither privileged containers nor
container-engine socket mounts are used.
NPM on Prometheus reached both upstreams through the Aegis gateway. Direct LAN
connections from Ikaros to 8080/8081 were blocked, and PostgreSQL/Redis had no
published host ports. Existing Git, Music and Syncthing HTTPS returned 200 with
valid TLS. NPM and its backup export timer stayed active; the pool remained healthy.
After operator DNS/NPM configuration, both public hostnames resolved to the VPS.
HTTPS and HTTP-to-HTTPS redirects passed with valid certificates. Both Proxy Hosts
were enabled with Force SSL and WebSocket support. Public Office health and its
browser API asset returned 200; the connector check also passed. Actual browser
editing/saving and native mobile client use remain operator acceptance tests.
Public session-based web login and authenticated WebDAV succeeded for admin,
fabio and chiara. CalDAV/CardDAV
discovery redirected to the DAV endpoint; Fabio's calendar/address-book collections
answered PROPFIND. A uniquely named private test file was inaccessible to Chiara.
Fabio created a test file in Famiglia; Chiara read, edited and deleted it, and Fabio
read the updated contents. All temporary test files were removed. These are HTTP
protocol checks, not device synchronization or large-upload acceptance evidence.
## Operator DNS and NPM configuration
Namecheap: add CNAMEs `cloud` and `office` to `fscotto.co`. Do not change the blog,
mail records or apex IP.
| NPM hostname | Scheme | Upstream | Port |
| --- | --- | --- | --- |
| cloud.fscotto.co | http | 192.168.178.55 | 8080 |
| office.fscotto.co | http | 192.168.178.55 | 8081 |
For each host, obtain a certificate for its hostname, enable Force SSL and
WebSocket support. Keep NPM administration loopback-only; do not expose port 81.
Nextcloud's declared upload ceiling is 2 GiB; align the proxy request-size and
timeout settings rather than claiming large uploads work before testing them.
Verify CalDAV/CardDAV `.well-known` redirects to `/remote.php/dav/` through NPM.
Never disable certificate verification to make Office work.
The browser-facing Office URL is `https://office.fscotto.co/`; server-side routes
use `http://atlas-onlyoffice/` and `http://atlas-nextcloud/` on the private network.
These internal routes require explicit local-address permission in the connector
and ONLYOFFICE. Metadata-address access remains disabled. Nextcloud trusts only
the declared Aegis address and rootless network gateway, not arbitrary proxies.
## Secrets and administration
Six unique secrets were generated into the existing encrypted `secrets/vault.yml`:
database, Redis, Office JWT and initial passwords for `admin`, `fabio`, `chiara`.
Use the local Vault editor to retrieve them; do not paste them in chat.
Account provisioning never resets an existing user's password. After a user
changes it, the initial Vault password is not necessarily their current password.
Database secret rotation needs a coordinated role-password update, not just an
edited initialization file. Image/app upgrades likewise require a deliberate window.
Host configuration lives below `/home/admin/.config/atlas-nextcloud` with a 0700
parent. Mounted individual secret files are readable by their container consumers,
but a different host user was verified unable to read them through the parent.
Nextcloud's managed PHP include inherits the live container SELinux category;
neither global relabeling nor disabling SELinux is used.
```bash
ansible-playbook ansible/site.yml --limit atlas --tags nextcloud --check --diff
ansible-playbook ansible/site.yml --limit atlas --tags nextcloud
```
Dry-run skips initial downloads, image pulls and runtime account/app commands;
it is not proof of an installed or healthy stack. The deployed repeat run is
the current idempotence evidence.
## Gates before family data and full client acceptance
- Verify the first actual scrub and the outstanding protection checks.
- Public TLS, redirects, web login and WebDAV passed. Complete calendar/contact
synchronization and Office editing/saving from a desktop.
- Test opening, editing and saving from the iPhone/iPad ONLYOFFICE app; mobile
browser editing is not a requirement. No such client test is claimed yet.
- Private-space isolation and cross-user shared writes/deletes passed the public
smoke test above; complete normal client acceptance as well.
- Integrate and test application-consistent database/files backups before import.
The new datasets fall beneath existing recursive snapshot/backup scope, but
that alone does not verify a new Borg/USB version or a consistent Nextcloud restore.
- For a consistent backup, coordinate pending Office saves, pause cron and writes,
take a verified PostgreSQL dump and matching application/files snapshot, and
resume services promptly even on failure. Extend recurring backup procedures,
not the steady-state playbook with one-time migration tasks. Restore into an
isolated environment using matching image/app versions, config, files and DB.
- Confirm encrypted Vault/recovery material is available offline. Without SMTP,
recovery for standard accounts is administrator-assisted; a forgotten admin
password can be reset through the private host-side `occ` CLI.
- Select versions deliberately for upgrades. Do not downgrade the application
against an upgraded database; use matching tested backups for recovery.
- Future Uranus migration and iCloud import are separate, explicitly authorized
operations. No source data deletion or automatic cross-system cutover is provided.