mirror of
https://github.com/nextcloud/all-in-one.git
synced 2026-07-22 06:02:54 +00:00
Revert "📝 docs: add session context and implementation plan"
This reverts commit c88687255d.
Signed-off-by: James Manuel <moodyjmz@users.noreply.github.com>
This commit is contained in:
@@ -1,153 +0,0 @@
|
||||
# Euro-Office AIO — Work Context
|
||||
|
||||
## Goal
|
||||
Ship Nextcloud AIO with **EuroOffice as the default document editor** (replacing Collabora).
|
||||
This is the euro-office-public fork of `nextcloud/all-in-one`. Current phase: **testing**.
|
||||
|
||||
---
|
||||
|
||||
## What We've Done
|
||||
|
||||
### `php/src/Data/ConfigurationManager.php`
|
||||
- `isEuroofficeEnabled` default: `false` → `true` (+ added missing `(bool)` cast)
|
||||
- `isCollaboraEnabled` default: `true` → `false`
|
||||
- `getNextcloudStartupApps()`: added `eurooffice` to the default app list
|
||||
- Added `performMigrations()`: one-time migration (flag `eurooffice_default_migration_v1`) that forces existing installs to switch to EuroOffice on next mastercontainer start
|
||||
|
||||
### `php/public/index.php`
|
||||
- Calls `$configurationManager->performMigrations()` at bootstrap (before route handling)
|
||||
|
||||
### `Containers/apache/Caddyfile` — EuroOffice SDK 404 fix
|
||||
**Root cause:** EuroOffice nginx maps `$http_x_forwarded_prefix` → `$the_prefix` and uses it to construct SDK asset URLs (e.g. `/eurooffice/sdkjs/...`). Without the header, `$the_prefix` is empty so the browser requests `/sdkjs/...` which Caddy routes to Nextcloud → 404.
|
||||
|
||||
**Fix:** Send `X-Forwarded-Prefix` as a separate header instead of appending the path to `X-Forwarded-Host`:
|
||||
```
|
||||
route /eurooffice/* {
|
||||
uri strip_prefix /eurooffice
|
||||
reverse_proxy {$EUROOFFICE_HOST}:80 {
|
||||
header_up X-Forwarded-Host {http.request.hostport}
|
||||
header_up X-Forwarded-Prefix /eurooffice
|
||||
}
|
||||
}
|
||||
```
|
||||
Note: OnlyOffice block uses the old pattern (`X-Forwarded-Host host/onlyoffice`) and was left unchanged — OO worked with it. This fix is also needed upstream in `nextcloud/all-in-one`.
|
||||
|
||||
### `Containers/nextcloud/entrypoint.sh` — EuroOffice internal URL and preview fix
|
||||
|
||||
**Root cause summary:** Containers resolve `nextcloud.test` → `127.0.0.1` (Docker reads host `/etc/hosts` which has `127.0.0.1 nextcloud.test`). So any container→container call using the public domain fails. This affects:
|
||||
1. NC → EuroOffice converter calls (preview generation, document editing callbacks)
|
||||
2. EuroOffice → NC file download calls (EuroOffice needs to fetch the document to convert it)
|
||||
|
||||
Three fixes baked into the entrypoint EuroOffice block:
|
||||
|
||||
**Fix 1 — DocumentServerInternalUrl** (NC → EuroOffice, bypasses public domain):
|
||||
```bash
|
||||
php /var/www/html/occ config:app:set eurooffice DocumentServerInternalUrl --value="http://$EUROOFFICE_HOST:80/"
|
||||
```
|
||||
- Must have trailing slash — `getDocumentServerInternalUrl()` returns raw value, concatenated directly with `"converter"` in `DocumentService::getConvertedUri()` (line 124)
|
||||
- `$EUROOFFICE_HOST` is the Docker container name (e.g. `nextcloud-aio-eurooffice`) before it gets rewritten to `$NC_DOMAIN/eurooffice`
|
||||
|
||||
**Fix 2 — StorageUrl** (EuroOffice → NC, bypasses public domain):
|
||||
```bash
|
||||
APACHE_CONTAINER_HOST=$(echo "$EUROOFFICE_HOST" | sed 's/-eurooffice$/-apache/')
|
||||
php /var/www/html/occ config:app:set eurooffice StorageUrl --value="http://$APACHE_CONTAINER_HOST.nextcloud-aio:23973/"
|
||||
```
|
||||
- Port 23973 matches Caddy's `http://{$APACHE_HOST}.nextcloud-aio:23973` server block (the WOPI/callback port), which routes to Nextcloud at `127.0.0.1:8000`
|
||||
- Port 11000 does NOT work even though it's open — Caddy rejects requests where `Host: nextcloud-aio-apache:11000` doesn't match the `nextcloud.test:11000` binding
|
||||
- Must have trailing slash — `getStorageUrl()` returns raw value; `str_replace("https://nextcloud.test/", storageUrl, $fileUrl)` strips the `/` from the origin, producing `...23973apps/` (broken URL) if StorageUrl has no trailing slash
|
||||
|
||||
**Fix 3 — enabledPreviewProviders** (EuroOffice class missing from explicit allowlist):
|
||||
```bash
|
||||
if ! php /var/www/html/occ config:system:get enabledPreviewProviders | grep -q "Eurooffice"; then
|
||||
php /var/www/html/occ config:system:set enabledPreviewProviders 50 --value="OCA\Eurooffice\Preview"
|
||||
fi
|
||||
```
|
||||
- NC has `enabledPreviewProviders` explicitly set; `registerPreviewProvider()` in `Application.php` is insufficient — the class must also be in this allowlist or the provider is silently skipped
|
||||
- FQCN: `OCA\Eurooffice\Preview` (namespace `OCA\Eurooffice`, class `Preview`)
|
||||
- occ stores with `\\` in config.php (PHP string literal for single backslash) — this is correct
|
||||
- Index 50 chosen to avoid collision with AIO's seeded range (indices 1–7 on fresh install, 23 for Imaginary). Previous `wc -l` approach would have produced index 7 on a standard install, silently overwriting the Krita preview provider.
|
||||
|
||||
### Local `aio-apache:beta` image
|
||||
Built from repo to test the Caddyfile fix:
|
||||
```bash
|
||||
docker buildx build --file Containers/apache/Dockerfile --tag ghcr.io/nextcloud-releases/aio-apache:beta --load Containers/apache
|
||||
```
|
||||
AIO uses the `:beta` tag in this test environment; local image takes precedence over remote pull.
|
||||
|
||||
After the build, `/Caddyfile` inside the image still had the old content (build context was captured before the edit was saved). The runtime `/tmp/Caddyfile` was manually correct. Fixed with:
|
||||
```bash
|
||||
docker exec nextcloud-aio-apache caddy reload --config /tmp/Caddyfile
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Status as of 2026-06-08
|
||||
|
||||
- ✅ **EuroOffice documents open** — Caddyfile X-Forwarded-Prefix fix working, SDK assets load correctly
|
||||
- ✅ **Preview generation works** — preview PNG files stored at `/mnt/ncdata/appdata_*/preview/.../107/` (confirmed valid)
|
||||
- ⚠️ **Preview display** — browser/service worker caches stale 404; hard reload (`Cmd+Shift+R`) clears it
|
||||
- ⬜ **Commit all changes** — entrypoint.sh, Caddyfile, ConfigurationManager.php, index.php
|
||||
- ⬜ **Upstream PR** to `nextcloud/all-in-one` for the Caddyfile `X-Forwarded-Prefix` fix
|
||||
- ⬜ **Docker Desktop restart** — still needed for `daemon.json` DNS change; currently working around it with internal URLs
|
||||
|
||||
---
|
||||
|
||||
## Caveats & Local Environment Notes
|
||||
|
||||
### Docker DNS — containers resolving `nextcloud.test`
|
||||
|
||||
**Why internal URLs are needed:** `/etc/hosts` on the macOS host has `127.0.0.1 nextcloud.test`. Docker embeds these in container DNS, so containers resolve `nextcloud.test` → `127.0.0.1` (the container's own loopback) rather than the host Caddy. This breaks any container→host→container call.
|
||||
|
||||
**Workaround (in place):** Both `DocumentServerInternalUrl` and `StorageUrl` bypass `nextcloud.test` entirely by using Docker-internal container names.
|
||||
|
||||
**Permanent fix (not yet applied):** Restart Docker Desktop to load `daemon.json` (`"dns": ["192.168.97.1"]`). Then dnsmasq at `192.168.97.1` will resolve `.test` → `0.250.250.254` (macOS `host.docker.internal`) and `nextcloud.test` will resolve correctly from containers.
|
||||
|
||||
Setup:
|
||||
- **dnsmasq** (Homebrew): `/opt/homebrew/etc/dnsmasq.conf` has:
|
||||
```
|
||||
address=/.test/0.250.250.254
|
||||
listen-address=127.0.0.1,192.168.97.1
|
||||
```
|
||||
(`192.168.97.1` is the Docker bridge gateway — containers use it as DNS)
|
||||
- **`~/.docker/daemon.json`**: `"dns": ["192.168.97.1"]` — containers get dnsmasq as DNS resolver
|
||||
- **`/etc/hosts`**: `127.0.0.1 nextcloud.test` — browser resolves directly (Caddy only listens on loopback, not the Docker bridge)
|
||||
- Docker Desktop restart required for daemon.json to take effect — **still pending**
|
||||
|
||||
### Apache container — patching Caddyfile at runtime
|
||||
- `/Caddyfile` is baked into the image; cannot be edited in a running container (image rootfs is read-only for that path)
|
||||
- `/tmp/Caddyfile` is the runtime copy generated by `start.sh`; it is writable
|
||||
- Caddy loads from `/tmp/Caddyfile` at startup (`caddy run --config /tmp/Caddyfile`)
|
||||
- To apply a Caddyfile fix without a full container restart:
|
||||
```bash
|
||||
# edit /tmp/Caddyfile, then:
|
||||
docker exec nextcloud-aio-apache caddy reload --config /tmp/Caddyfile
|
||||
```
|
||||
|
||||
### EuroOffice NC connector app
|
||||
- App ID: `eurooffice`, FQCN for preview provider: `OCA\Eurooffice\Preview`
|
||||
- Available on the Nextcloud appstore: https://apps.nextcloud.com/apps/eurooffice (v11.0.0, NC 33/34)
|
||||
- Added to `STARTUP_APPS` so it installs automatically on first Nextcloud start
|
||||
- Sibling repo: `/Users/jamesmanuel/PhpstormProjects/euro-office-public/eurooffice-nextcloud`
|
||||
- Uses OnlyOffice `/converter` API (not WOPI) for preview generation and document editing
|
||||
- JWT: shared secret configured via `jwt_secret` in both `config:system:set eurooffice jwt_secret` and `config:app:set eurooffice jwt_secret`; header is `AuthorizationJwt`
|
||||
|
||||
### AIO UI & access
|
||||
- Mastercontainer: `https://localhost:9090`
|
||||
- Nextcloud: `https://nextcloud.test`
|
||||
- Stop/start containers via the AIO UI — not `docker stop` directly
|
||||
- Upstream beta tag being tested: `v13.2.0` (first version with EuroOffice support merged via PR #8052)
|
||||
|
||||
### Local images pulled
|
||||
- `ghcr.io/euro-office/documentserver:v9.3.1-beta.1` — 7.14 GB
|
||||
- `ghcr.io/nextcloud-releases/all-in-one:latest` — 386 MB
|
||||
- `ghcr.io/nextcloud-releases/aio-apache:beta` — 289 MB (locally built)
|
||||
|
||||
### Building locally
|
||||
```bash
|
||||
# apache image (Caddyfile changes):
|
||||
docker buildx build --file Containers/apache/Dockerfile --tag ghcr.io/nextcloud-releases/aio-apache:beta --load Containers/apache
|
||||
|
||||
# mastercontainer (PHP/config changes):
|
||||
docker buildx build --file Containers/mastercontainer/Dockerfile --tag ghcr.io/nextcloud-releases/all-in-one:develop --load .
|
||||
# then add ?bypass_mastercontainer_update to the URL to skip self-update prompt
|
||||
```
|
||||
-187
@@ -1,187 +0,0 @@
|
||||
# EuroOffice Default Editor — Implementation Plan
|
||||
|
||||
**Status:** Changes implemented, tested locally. Ready to commit.
|
||||
**Phase:** Testing → Commit → Build → (upstream Caddyfile PR optional)
|
||||
|
||||
---
|
||||
|
||||
## Security Review (Completed)
|
||||
|
||||
**Verdict: no regressions.** The four changed files introduce no new attack surface.
|
||||
|
||||
- **Caddyfile `X-Forwarded-Prefix /eurooffice`** — literal string set by Caddy `header_up`, not
|
||||
user-controlled. Overwrites any client-supplied value before it reaches EuroOffice nginx.
|
||||
- **`X-Forwarded-Host {http.request.hostport}`** — appears in the EuroOffice route and was already
|
||||
present in existing OnlyOffice and Nextcloud server blocks. Caddy only routes requests matching its
|
||||
server-block bindings, and Nextcloud enforces `trusted_domains` downstream. Considered and
|
||||
dismissed; not a reflective-Host injection issue in this deployment model.
|
||||
- **Internal HTTP (DocumentServerInternalUrl / StorageUrl)** — identical threat model to the existing
|
||||
Collabora WOPI callback path. `http://nextcloud-aio-apache.nextcloud-aio:23973` is the documented
|
||||
internal callback address (used by Collabora in containers.json lines 394/405). Same Docker
|
||||
network isolation, same JWT signing (`AuthorizationJwt`). No new port opened.
|
||||
- **`performMigrations()` in index.php** — runs an idempotent config read on every HTTP request until
|
||||
the migration flag is set for the first time. Not a security concern; minor performance overhead
|
||||
on first-boot only.
|
||||
|
||||
---
|
||||
|
||||
## Wider Implications
|
||||
|
||||
### 1. Migration blast-radius (decision required)
|
||||
|
||||
`performMigrations()` runs on every mastercontainer boot. When `eurooffice_default_migration_v1` is
|
||||
unset it force-sets:
|
||||
- `isCollaboraEnabled = false`
|
||||
- `isOnlyofficeEnabled = false`
|
||||
- `isEuroofficeEnabled = true`
|
||||
|
||||
**This overrides an admin's explicit prior choice**, not just an unset default. An existing install
|
||||
that deliberately runs Collabora will have its editor swapped silently on the next image pull.
|
||||
|
||||
The flag (`eurooffice_default_migration_v1`) prevents re-fighting an admin who switches back after
|
||||
migration. But there is no rollback: once migrated, Collabora/OnlyOffice must be re-enabled manually.
|
||||
|
||||
**Open question for James:** Is the silent force-switch the intended behaviour for all existing forks
|
||||
of this repo, or should it only apply when no editor has been explicitly set?
|
||||
|
||||
If the answer is "force-switch is correct" → current code is right.
|
||||
If "preserve explicit Collabora installs" → change the migration to check whether an explicit choice
|
||||
was already made (e.g., only migrate if `isCollaboraEnabled` is still at its factory default).
|
||||
|
||||
### 2. Preview provider index fix (bug fixed)
|
||||
|
||||
`occ config:system:set enabledPreviewProviders` in AIO seeds indices 1–7 on fresh install, and also
|
||||
uses index 23 for Imaginary. The previous approach of computing the next index via `wc -l` would
|
||||
produce 7 on a standard install, which collides with the Krita entry at index 7 — silently removing
|
||||
Krita previews.
|
||||
|
||||
**Fixed:** replaced dynamic `wc -l` with fixed index 50. AIO never exceeds index 23 in its own
|
||||
seeding; 50 is safe for the foreseeable set of providers.
|
||||
|
||||
### 3. Local-only validation gap
|
||||
|
||||
All testing was done in a local environment where `nextcloud.test` resolves to `127.0.0.1` inside
|
||||
containers (host `/etc/hosts` is embedded into Docker DNS). The internal URLs work around this. In a
|
||||
production install where DNS resolves correctly, the public-domain code path would be used instead
|
||||
of the internal Docker URLs — but the code we added runs only when `$EUROOFFICE_HOST` matches the
|
||||
`nextcloud-.*-eurooffice` pattern, which is the AIO default naming. That pattern is stable.
|
||||
|
||||
**What is reasoned but not yet tested on a clean prod-like install:** that port 23973 routes
|
||||
EuroOffice→NC callbacks correctly end-to-end without the local DNS workaround in play. The port is
|
||||
the documented Collabora WOPI ingress (confirmed in containers.json:394) so the reasoning is sound.
|
||||
|
||||
---
|
||||
|
||||
## Commits
|
||||
|
||||
Three atomic commits in logical order:
|
||||
|
||||
### Commit 1 — Caddyfile X-Forwarded-Prefix fix
|
||||
|
||||
```
|
||||
fix(apache): send X-Forwarded-Prefix for EuroOffice SDK assets
|
||||
|
||||
EuroOffice nginx uses $http_x_forwarded_prefix to construct SDK
|
||||
asset URLs (e.g. /eurooffice/sdkjs/...). Without this header the
|
||||
prefix is empty and the browser requests /sdkjs/... which Caddy
|
||||
routes to Nextcloud → 404.
|
||||
|
||||
Send X-Forwarded-Prefix as a separate header (not appended to
|
||||
X-Forwarded-Host as OnlyOffice does) to match EuroOffice nginx
|
||||
expectations. X-Forwarded-Host continues to carry host only.
|
||||
```
|
||||
|
||||
**Files:** `Containers/apache/Caddyfile`
|
||||
|
||||
Note: this fix is also applicable upstream to `nextcloud/all-in-one` as a standalone PR (no other
|
||||
changes needed).
|
||||
|
||||
### Commit 2 — Make EuroOffice the default editor
|
||||
|
||||
```
|
||||
feat: make EuroOffice the default editor for new and existing installs
|
||||
|
||||
- isEuroofficeEnabled default: false → true
|
||||
- isCollaboraEnabled default: true → false
|
||||
- Add eurooffice to STARTUP_APPS
|
||||
- performMigrations(): one-time force-switch for existing installs
|
||||
(guarded by eurooffice_default_migration_v1 flag to prevent
|
||||
re-fighting an admin who switches back)
|
||||
- Call performMigrations() at index.php bootstrap
|
||||
```
|
||||
|
||||
**Files:** `php/src/Data/ConfigurationManager.php`, `php/public/index.php`
|
||||
|
||||
### Commit 3 — Configure EuroOffice internal URLs and preview provider
|
||||
|
||||
```
|
||||
fix(nextcloud): configure EuroOffice internal URLs and preview provider
|
||||
|
||||
Three fixes applied in entrypoint.sh when $EUROOFFICE_HOST matches
|
||||
the default AIO container naming pattern:
|
||||
|
||||
1. DocumentServerInternalUrl → http://$EUROOFFICE_HOST:80/
|
||||
Bypasses the public domain (which containers cannot resolve in
|
||||
many setups) for NC→EuroOffice converter calls. Trailing slash
|
||||
required; DocumentService.php concatenates the raw value with
|
||||
"converter" (no separator).
|
||||
|
||||
2. StorageUrl → http://$APACHE_CONTAINER_HOST.nextcloud-aio:23973/
|
||||
Bypasses the public domain for EuroOffice→NC file fetch calls.
|
||||
Port 23973 is the Collabora WOPI ingress (server block matches
|
||||
the container FQDN; port 11000 rejects the wrong Host header).
|
||||
Trailing slash required; str_replace strips the / from the origin.
|
||||
|
||||
3. enabledPreviewProviders index 50 → OCA\Eurooffice\Preview
|
||||
NC's allowlist is explicit; registerPreviewProvider() alone is
|
||||
insufficient. Index 50 avoids collision with AIO's seeded range
|
||||
(1-7, 23).
|
||||
```
|
||||
|
||||
**Files:** `Containers/nextcloud/entrypoint.sh`
|
||||
|
||||
---
|
||||
|
||||
## Build and Deploy
|
||||
|
||||
After committing, the apache image must be rebuilt for the Caddyfile change to take effect:
|
||||
|
||||
```bash
|
||||
# Rebuild apache image
|
||||
docker buildx build \
|
||||
--file Containers/apache/Dockerfile \
|
||||
--tag ghcr.io/nextcloud-releases/aio-apache:beta \
|
||||
--load \
|
||||
Containers/apache
|
||||
|
||||
# Rebuild mastercontainer (for ConfigurationManager + index.php changes)
|
||||
docker buildx build \
|
||||
--file Containers/mastercontainer/Dockerfile \
|
||||
--tag ghcr.io/nextcloud-releases/all-in-one:develop \
|
||||
--load .
|
||||
```
|
||||
|
||||
Then restart the AIO stack via the AIO UI at `https://localhost:9090`.
|
||||
Use `?bypass_mastercontainer_update` in the URL to skip self-update prompt.
|
||||
|
||||
---
|
||||
|
||||
## Upstream PR (Optional)
|
||||
|
||||
The Caddyfile fix (commit 1) is a clean, standalone bugfix that applies to
|
||||
`nextcloud/all-in-one` regardless of EuroOffice. The other two commits are
|
||||
fork-specific and should not go upstream.
|
||||
|
||||
Before opening the upstream PR, confirm that OnlyOffice's `X-Forwarded-Host
|
||||
host/onlyoffice` pattern is intentional for OO (it works differently) so the
|
||||
PR can be scoped to EuroOffice only.
|
||||
|
||||
---
|
||||
|
||||
## Remaining Items
|
||||
|
||||
- [ ] Docker Desktop restart — apply `daemon.json` `"dns": ["192.168.97.1"]` for
|
||||
permanent DNS fix. Non-urgent: internal URL workaround is in place.
|
||||
- [ ] Decision on migration behaviour (see §1 above) — confirm or adjust
|
||||
`performMigrations()` before tagging a release.
|
||||
- [ ] Validate on a clean install without the local DNS workaround.
|
||||
Reference in New Issue
Block a user