From e5c9cf35e573534327defb40ceb8f22e59f25ffa Mon Sep 17 00:00:00 2001 From: James Manuel Date: Sat, 2 May 2026 08:21:05 +0200 Subject: [PATCH 1/3] feat: :whale: Add dev override for NC version switching with per-branch volumes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each NC_BRANCH gets its own named volume (nc_data_master, nc_data_stable33, nc_data_stable34), so switching between NC versions during development preserves each branch's installed state — eurooffice config, files, sessions — instead of wiping on every switch. Usage: docker compose up -d nextcloud (master/NC34 trunk) NC_BRANCH=stable33 docker compose up -d nextcloud (NC33) Pairs with the develop stack's existing setup/shared/hooks/after-install.sh which configures eurooffice on every fresh-volume bring-up. The Makefile's `refresh-urls` target then aligns DocumentServerUrl + JWT after install. Co-Authored-By: Claude Signed-off-by: James Manuel --- develop/docker-compose.override.yml | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 develop/docker-compose.override.yml diff --git a/develop/docker-compose.override.yml b/develop/docker-compose.override.yml new file mode 100644 index 0000000..166c684 --- /dev/null +++ b/develop/docker-compose.override.yml @@ -0,0 +1,32 @@ +# Switches the NC container to the nextcloud-docker-dev image, enabling NC version switching. +# +# Each NC_BRANCH gets its own named volume, so switching between branches preserves +# each branch's installed state (eurooffice config, files, sessions, etc.). +# +# Usage: +# docker compose up -d nextcloud (master/NC34 trunk, volume: nc_data_master) +# NC_BRANCH=stable33 docker compose up -d nextcloud (NC33, volume: nc_data_stable33) +# NC_BRANCH=stable34 docker compose up -d nextcloud (once 34 is cut, volume: nc_data_stable34) +# +# To switch branches: docker compose stop nextcloud && docker compose rm -f nextcloud && \ +# NC_BRANCH= docker compose up -d nextcloud +# +# To wipe a single branch without touching the others: +# docker compose rm -sfv nextcloud (only removes the currently-attached volume) +# Or: docker volume rm develop_nc_data_ + +services: + nextcloud: + image: ghcr.io/juliusknorr/nextcloud-dev-php82:latest + environment: + SERVER_BRANCH: ${NC_BRANCH:-master} + SQL: sqlite + volumes: + - nc_data_${NC_BRANCH:-master}:/var/www/html + - ../../eurooffice-nextcloud:/var/www/html/apps-extra/eurooffice + - ./setup/shared:/shared + +volumes: + nc_data_master: + nc_data_stable33: + nc_data_stable34: From f1edcd5884ef7c07abef7c4986877908bb54e18b Mon Sep 17 00:00:00 2001 From: James Manuel Date: Tue, 5 May 2026 01:24:26 +0200 Subject: [PATCH 2/3] chore: :speech_balloon: Rebrand develop setup hook from onlyoffice to eurooffice setup/enable-office.sh is the post-installation hook for the official Nextcloud Docker Hub image (mounted to /docker-entrypoint-hooks.d/). Update it to enable and configure the eurooffice app instead of the upstream onlyoffice app, remove the stock onlyoffice app on first boot to avoid autoloader conflicts, and align the JWT secret with the value the document server container uses. Co-Authored-By: Claude Signed-off-by: James Manuel --- develop/setup/enable-office.sh | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/develop/setup/enable-office.sh b/develop/setup/enable-office.sh index bdc1f57..b655a45 100755 --- a/develop/setup/enable-office.sh +++ b/develop/setup/enable-office.sh @@ -7,6 +7,9 @@ php /var/www/html/occ config:system:set trusted_domains 10 --value=nextcloud php /var/www/html/occ config:system:set auth.bruteforce.protection.enabled --value=false --type=boolean php /var/www/html/occ config:system:set ratelimit.protection.enabled --value=false --type=boolean +# Remove stock onlyoffice app if present — it conflicts with eurooffice's autoloader +rm -rf /var/www/html/custom_apps/onlyoffice + echo "Waiting for Euro-Office document server to be ready..." until curl -sf http://eo/healthcheck > /dev/null 2>&1; do echo "Waiting for http://eo/healthcheck..." @@ -15,10 +18,10 @@ done echo "Document server is ready!" # Baseline URL; `make local` / `make mobile` rewrite this via `refresh-urls`. -php /var/www/html/occ app:enable onlyoffice -php /var/www/html/occ config:app:set onlyoffice DocumentServerUrl --value="http://localhost:8080/" -php /var/www/html/occ config:app:set onlyoffice StorageUrl --value="http://nextcloud/" -php /var/www/html/occ config:app:set onlyoffice DocumentServerInternalUrl --value="http://eo/" -php /var/www/html/occ config:app:set onlyoffice VerifyPeerOff --value="true" -php /var/www/html/occ config:app:set onlyoffice jwt_secret --value="secret" +php /var/www/html/occ app:enable eurooffice +php /var/www/html/occ config:app:set eurooffice DocumentServerUrl --value="http://localhost:8080/" +php /var/www/html/occ config:app:set eurooffice StorageUrl --value="http://nextcloud/" +php /var/www/html/occ config:app:set eurooffice DocumentServerInternalUrl --value="http://eo/" +php /var/www/html/occ config:app:set eurooffice VerifyPeerOff --value="true" +php /var/www/html/occ config:app:set eurooffice jwt_secret --value="euro-office-dev-jwt-secret-key-2026" From 083f29c2f3736bc464707c3ce1b8e40a37cd7f7b Mon Sep 17 00:00:00 2001 From: James Manuel Date: Tue, 5 May 2026 01:25:26 +0200 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20:sparkles:=20Rework=20dev=20stack?= =?UTF-8?q?=20=E2=80=94=20stable-by-default,=20opt-in=20future-NC=20testin?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reframe the dev compose around what 90% of work needs (current NC stable from Docker Hub, fast boot, no version drift) and make the nextcloud-docker-dev source-clone path opt-in via `make next` for testing future NC versions only. Compose: - docker-compose.yml: parameterise NC image as `nextcloud:${NC_VERSION:-latest}` so matrix testing against specific majors is `NC_VERSION=33 docker compose up -d`. Fix a typo in a trusted_domains comment along the way. - Rename docker-compose.override.yml → docker-compose.next.yml so it stops auto-loading. `make local` now uses the base file directly → official `nextcloud:latest` image, ~3s boot, no master/upgrade drift. - docker-compose.next.yml: dynamic per-branch volume name via the top-level `volumes..name` interpolation (`nc_data_${NC_BRANCH:-master}`). Replaces the hardcoded list of three branch names — any NC_BRANCH value now gets its own volume without yaml edits. Makefile: - New `next` target opts into the dev image with branch switching. `make next` runs against master; `make next NC_BRANCH=stable33` etc. - New `print-nc-version` helper queries `occ -V` and is called from `local` and `next` so each run reports the NC version it landed on. - Suppress the `Profiler output available at …` STDERR noise emitted by occ on every CLI invocation in `refresh-urls`. - Differentiate the two refresh-urls polling lines (eo vs nextcloud). - `docker compose exec eo bash` exits cleanly if the container shell returns non-zero (Ctrl+C or stray non-zero exit). Bootstrap: - New setup/shared/hooks/after-install.sh — equivalent of enable-office.sh but for the nextcloud-docker-dev image's hook system (mounted at /shared). Used only by `make next`; `make local` continues to use enable-office.sh via /docker-entrypoint-hooks.d/. README: - New "Testing against a future Nextcloud version" section explaining `make next` and per-branch volumes. Co-Authored-By: Claude Signed-off-by: James Manuel --- develop/Makefile | 59 ++++++++++++++++----- develop/README.md | 36 +++++++++++-- develop/docker-compose.next.yml | 39 ++++++++++++++ develop/docker-compose.override.yml | 32 ----------- develop/docker-compose.yml | 7 +-- develop/setup/shared/hooks/after-install.sh | 26 +++++++++ 6 files changed, 147 insertions(+), 52 deletions(-) create mode 100644 develop/docker-compose.next.yml delete mode 100644 develop/docker-compose.override.yml create mode 100755 develop/setup/shared/hooks/after-install.sh diff --git a/develop/Makefile b/develop/Makefile index 8485319..72040ea 100644 --- a/develop/Makefile +++ b/develop/Makefile @@ -1,6 +1,9 @@ PRODUCT_VERSION ?= $(shell cat ../VERSION) export PRODUCT_VERSION +EO_JWT_SECRET ?= euro-office-dev-jwt-secret-key-2026 +export EO_JWT_SECRET + # Detect host LAN IP for phones/emulators/LAN devices. Used by `make mobile` # and `make refresh-urls`. ifeq ($(shell uname -s),Darwin) @@ -38,43 +41,75 @@ endif @echo "" docker compose up -d @$(MAKE) --no-print-directory refresh-urls - docker compose exec eo bash + @$(MAKE) --no-print-directory print-nc-version + @docker compose exec eo bash || true # Like `make local`, but injects the detected HOST_LAN_IP so that Nextcloud # returns a DocumentServerUrl mobile/LAN clients can actually reach. mobile: @HOST_LAN_IP="$(DETECTED_HOST_LAN_IP)" $(MAKE) local +# Run against a future Nextcloud version (master / stable33 / stable34) using the +# nextcloud-docker-dev source-clone image. Each NC_BRANCH gets its own named volume, +# so switching branches preserves each branch's installed state. +# +# make next — master (current NC dev trunk) +# make next NC_BRANCH=stable33 — pin to NC33 stable +# make next NC_BRANCH=stable34 — pin to NC34 stable (once cut) +# +# `make local` follows nextcloud:latest from Docker Hub (current stable) — use that +# for day-to-day work; reach for `make next` only when testing against unreleased +# or non-current NC. +next: + @echo "" + @echo " Euro-Office — Next NC testing" + @echo " NC branch: $${NC_BRANCH:-master}" + @echo " Volume: nc_data_$${NC_BRANCH:-master} (preserved across switches)" + @echo "" + NC_BRANCH=$${NC_BRANCH:-master} docker compose -f docker-compose.yml -f docker-compose.next.yml up -d + @$(MAKE) --no-print-directory refresh-urls + @$(MAKE) --no-print-directory print-nc-version + @docker compose exec eo bash || true + pull: - docker compose pull && docker compose up -d && docker compose exec eo bash + docker compose pull && docker compose up -d && docker compose exec eo bash || true build: (cd ../build && docker buildx bake develop) && \ (docker compose up -d) && \ - (docker compose exec eo bash) + (docker compose exec eo bash || true) -# Align OnlyOffice URLs and trusted_domains with the current mode. +# Align Euro-Office URLs and trusted_domains with the current mode. # - If HOST_LAN_IP is set: mobile/LAN mode (DocumentServerUrl = http://:8080/, trusted_domains[2] = ). # - If HOST_LAN_IP is empty: localhost mode (DocumentServerUrl = http://localhost:8080/, trusted_domains[2] cleared). -# Waits for Nextcloud + OnlyOffice to finish installing on first boot, then applies idempotently. +# Waits for Nextcloud + Euro-Office to finish installing on first boot, then applies idempotently. refresh-urls: @start=$$(date +%s); \ while ! docker compose exec -T eo curl -sf http://localhost/healthcheck >/dev/null 2>&1; do \ - printf "\rWaiting for document server (%ds) " $$(($$(date +%s) - start)); \ + printf "\r[eo] waiting (%ds) " $$(($$(date +%s) - start)); \ sleep 2; \ done; \ - printf "\rDocument server ready (%ds). \n" $$(($$(date +%s) - start)) + printf "\r[eo] ready (%ds) \n" $$(($$(date +%s) - start)) @start=$$(date +%s); \ - while ! docker compose exec -T -u www-data nextcloud ./occ config:app:get onlyoffice DocumentServerUrl 2>/dev/null | grep -q "http"; do \ - printf "\rWaiting for Nextcloud setup (%ds) " $$(($$(date +%s) - start)); \ + while ! docker compose exec -T -u www-data nextcloud ./occ config:app:get eurooffice DocumentServerUrl 2>/dev/null | grep -q "http"; do \ + printf "\r[nextcloud] installing (%ds) " $$(($$(date +%s) - start)); \ sleep 2; \ done; \ - printf "\rNextcloud setup ready (%ds). \n" $$(($$(date +%s) - start)) + printf "\r[nextcloud] ready (%ds) \n" $$(($$(date +%s) - start)) @target="$${HOST_LAN_IP:-localhost}"; \ echo "Setting DocumentServerUrl to http://$$target:8080/"; \ - docker compose exec -T -u www-data nextcloud ./occ config:app:set onlyoffice DocumentServerUrl --value="http://$$target:8080/" >/dev/null; \ + docker compose exec -T -u www-data nextcloud ./occ config:app:set eurooffice DocumentServerUrl --value="http://$$target:8080/" >/dev/null 2>&1; \ if [ "$$target" = "localhost" ]; then \ docker compose exec -T -u www-data nextcloud ./occ config:system:delete trusted_domains 2 >/dev/null 2>&1 || true; \ else \ - docker compose exec -T -u www-data nextcloud ./occ config:system:set trusted_domains 2 --value=$$target >/dev/null; \ + docker compose exec -T -u www-data nextcloud ./occ config:system:set trusted_domains 2 --value=$$target >/dev/null 2>&1; \ fi + @docker compose exec -T -u www-data nextcloud ./occ config:app:set eurooffice jwt_secret --value="$(EO_JWT_SECRET)" >/dev/null 2>&1; \ + echo "JWT secret aligned with document server" + +# Print the Nextcloud version installed in the running container. Useful after +# `make local` (where it shows the latest stable Docker Hub tag) and `make next` +# (where it resolves the tracked branch — e.g. master → "34.0.0 beta 2"). +print-nc-version: + @v=$$(docker compose exec -T -u www-data nextcloud ./occ -V 2>/dev/null | tr -d '\r'); \ + if [ -n "$$v" ]; then echo "Running: $$v"; fi diff --git a/develop/README.md b/develop/README.md index a39ac54..5a6b83e 100644 --- a/develop/README.md +++ b/develop/README.md @@ -3,6 +3,12 @@ The docker compose environment in this directory allows to run document server built from our code base. It runs a container called develop, which just adds the development (i.e., build) tooling to the finalubuntu container. This lets you build pieces on the fly directly inside the container, saving build time when developing: +- Clone the Euro-Office Nextcloud connector as a sibling of `DocumentServer` (i.e. inside the same `euro-office-public` parent): + ```sh + git clone https://github.com/Euro-Office/eurooffice-nextcloud.git ../../eurooffice-nextcloud + cd ../../eurooffice-nextcloud && git submodule update --init --recursive && npm install && npm run build && composer install --no-dev + cd ../DocumentServer/develop + ``` - Follow the repo cloning steps in the build readme - In DocumentServer/develop, start the containers and get into eo bash with either: - `make` to use the image that is currently available locally @@ -16,11 +22,11 @@ The docker compose environment in this directory allows to run document server b #### Using the image: - It's exposed at `http://localhost:8081/` -- Nextclouds onlyoffice app should be installed and configured automatically. If not follow the next steps - - Install the onlyoffice app with the UI, or via `docker compose exec nextcloud bash` -> `php occ app:install onlyoffice` - - Configure your instance at `http://localhost:8081/settings/admin/onlyoffice`: +- The Euro-Office Nextcloud connector (`eurooffice`) is installed and configured automatically. If not, follow these steps: + - Install via `docker compose exec nextcloud bash` -> `php occ app:enable eurooffice` + - Configure your instance at `http://localhost:8081/settings/admin/eurooffice`: - Docs address `http://localhost:8080/` - - Server address for internal requests from ONLYOFFICE Docs `http://nextcloud/` + - Server address for internal requests from Euro-Office Docs `http://nextcloud/` - Docs address for internal requests from Nextcloud `http://eo/` - Secret key: `secret` - Navigate to Files `http://localhost:8081/apps/files/`, create a document, and try to open it @@ -48,7 +54,27 @@ When your LAN IP changes (new wifi, tethering, etc.), update the running stack w make refresh-urls ``` -Switching between `make local` and `make mobile` on an already-started stack is supported — both targets re-apply the correct URLs and trusted domains on each run. +Switching between `make local` and `make mobile` on a running stack is supported — both targets re-apply the correct URLs and trusted domains on each run. + +#### Testing against a future Nextcloud version + +`make local` follows `nextcloud:latest` from Docker Hub — current stable. + +Use `make next` when you specifically need to test against an unreleased or non-current NC: `master`, `stable33`, `stable34`, etc. + +Run from `DocumentServer/develop/`: + +```sh +make next # master (current NC dev trunk) +make next NC_BRANCH=stable33 # NC33 stable +make next NC_BRANCH=stable34 # NC34 stable (once cut) +``` + +`make next` swaps the official image for the source-clone dev image (`nextcloud-docker-dev`) via `docker-compose.next.yml`, and gives each NC branch its own named volume — switching between branches preserves each branch's installed state (eurooffice config, files, sessions). Compose detects the volume mount change and recreates the container automatically; no manual stop/rm. + +First boot per branch will be several minutes while NC clones and installs into the empty volume; subsequent switches reattach to the warm volume in seconds. Wipe a single branch with `docker volume rm nc_data_`. + +> Note: tracking `master` means NC's code moves between sessions. If you see `Nextcloud or one of the apps require upgrade` in `make next` output, run `docker compose exec -u www-data nextcloud ./occ upgrade` (or wipe the volume and then run `make next`). #### Building changes: diff --git a/develop/docker-compose.next.yml b/develop/docker-compose.next.yml new file mode 100644 index 0000000..9222456 --- /dev/null +++ b/develop/docker-compose.next.yml @@ -0,0 +1,39 @@ +# "Next NC" testing variant — opt-in via `make next` (or explicit +# `-f docker-compose.yml -f docker-compose.next.yml ...`). Use this to test +# against future Nextcloud versions before they ship as `nextcloud:latest`. +# +# Switches the NC container from the official Docker Hub image (used by `make local`) +# to the source-clone nextcloud-docker-dev image, enabling NC version switching by +# branch (master / stable33 / stable34) instead of by Docker Hub release tag. +# +# Each NC_BRANCH gets its own named volume, so switching between branches preserves +# each branch's installed state (eurooffice config, files, sessions, etc.). +# +# Usage (run from DocumentServer/develop/): +# make next (master, current NC dev trunk) +# make next NC_BRANCH=stable33 (NC33 stable) +# make next NC_BRANCH=stable34 (NC34 stable, once cut) +# +# Compose detects the volume mount change and recreates the nextcloud container +# automatically; no manual stop/rm needed when switching NC_BRANCH. +# +# To wipe a single branch without touching the others: +# docker volume rm euro-officedevelopmentenvironment_nc_data_ + +services: + nextcloud: + image: ghcr.io/juliusknorr/nextcloud-dev-php82:latest + environment: + SERVER_BRANCH: ${NC_BRANCH:-master} + SQL: sqlite + volumes: + - nc_data:/var/www/html + - ../../eurooffice-nextcloud:/var/www/html/apps-extra/eurooffice + - ./setup/shared:/shared + +volumes: + nc_data: + # Per-branch volume name via interpolation. Each NC_BRANCH value gets its + # own actual Docker volume (nc_data_master, nc_data_stable33, …) so state + # is preserved across switches without listing every supported branch. + name: nc_data_${NC_BRANCH:-master} diff --git a/develop/docker-compose.override.yml b/develop/docker-compose.override.yml deleted file mode 100644 index 166c684..0000000 --- a/develop/docker-compose.override.yml +++ /dev/null @@ -1,32 +0,0 @@ -# Switches the NC container to the nextcloud-docker-dev image, enabling NC version switching. -# -# Each NC_BRANCH gets its own named volume, so switching between branches preserves -# each branch's installed state (eurooffice config, files, sessions, etc.). -# -# Usage: -# docker compose up -d nextcloud (master/NC34 trunk, volume: nc_data_master) -# NC_BRANCH=stable33 docker compose up -d nextcloud (NC33, volume: nc_data_stable33) -# NC_BRANCH=stable34 docker compose up -d nextcloud (once 34 is cut, volume: nc_data_stable34) -# -# To switch branches: docker compose stop nextcloud && docker compose rm -f nextcloud && \ -# NC_BRANCH= docker compose up -d nextcloud -# -# To wipe a single branch without touching the others: -# docker compose rm -sfv nextcloud (only removes the currently-attached volume) -# Or: docker volume rm develop_nc_data_ - -services: - nextcloud: - image: ghcr.io/juliusknorr/nextcloud-dev-php82:latest - environment: - SERVER_BRANCH: ${NC_BRANCH:-master} - SQL: sqlite - volumes: - - nc_data_${NC_BRANCH:-master}:/var/www/html - - ../../eurooffice-nextcloud:/var/www/html/apps-extra/eurooffice - - ./setup/shared:/shared - -volumes: - nc_data_master: - nc_data_stable33: - nc_data_stable34: diff --git a/develop/docker-compose.yml b/develop/docker-compose.yml index f80c45c..dae9314 100644 --- a/develop/docker-compose.yml +++ b/develop/docker-compose.yml @@ -17,19 +17,20 @@ services: environment: ALLOW_PRIVATE_IP_ADDRESS: true USE_UNAUTHORIZED_STORAGE: true - JWT_SECRET: secret + JWT_SECRET: ${EO_JWT_SECRET:-euro-office-dev-jwt-secret-key-2026} THEME: euro-office volumes: - ../:/develop # mounts deployed files to application - ./setup/Makefile:/Makefile # mounts deployed files to application nextcloud: - image: nextcloud:latest + image: nextcloud:${NC_VERSION:-latest} container_name: nextcloud ports: - "8081:80" volumes: - /var/www/html - ./setup/enable-office.sh:/docker-entrypoint-hooks.d/post-installation/enable-office.sh:ro + - ../../eurooffice-nextcloud:/var/www/html/custom_apps/eurooffice:ro environment: # 10.0.2.2 = Android emulator's alias for host. Mobile/LAN IPs are # applied post-boot by `make refresh-urls` so the container env stays @@ -46,5 +47,5 @@ services: environment: ALLOW_PRIVATE_IP_ADDRESS: true USE_UNAUTHORIZED_STORAGE: true - JWT_SECRET: secret + JWT_SECRET: ${EO_JWT_SECRET:-euro-office-dev-jwt-secret-key-2026} diff --git a/develop/setup/shared/hooks/after-install.sh b/develop/setup/shared/hooks/after-install.sh new file mode 100755 index 0000000..277acbe --- /dev/null +++ b/develop/setup/shared/hooks/after-install.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -e + +# Disable dev-unfriendly protections +occ config:system:set auth.bruteforce.protection.enabled --value=false --type=boolean +occ config:system:set ratelimit.protection.enabled --value=false --type=boolean + +# Allow eo to call back to NC via the service hostname +occ config:system:set trusted_domains 3 --value=nextcloud + +# Remove stock onlyoffice if present — conflicts with eurooffice autoloader +rm -rf /var/www/html/custom_apps/onlyoffice + +echo "Waiting for Euro-Office document server to be ready..." +until curl -sf http://eo/healthcheck > /dev/null 2>&1; do + echo " still waiting..." + sleep 5 +done +echo "Document server ready." + +occ app:enable eurooffice +occ config:app:set eurooffice DocumentServerUrl --value="http://localhost:8080/" +occ config:app:set eurooffice StorageUrl --value="http://nextcloud/" +occ config:app:set eurooffice DocumentServerInternalUrl --value="http://eo/" +occ config:app:set eurooffice VerifyPeerOff --value="true" +occ config:app:set eurooffice jwt_secret --value="${EO_JWT_SECRET:-euro-office-dev-jwt-secret-key-2026}"