mirror of
https://github.com/fscotto/infra.git
synced 2026-10-04 05:49:50 +00:00
Deploy temporary Atlas Nextcloud and ONLYOFFICE stack
This commit is contained in:
105
docs/atlas-nextcloud-design.md
Normal file
105
docs/atlas-nextcloud-design.md
Normal 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
127
docs/atlas-nextcloud.md
Normal 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.
|
||||
Reference in New Issue
Block a user