From 0ae9198428f2e56aae0e07c45f036438c3431407 Mon Sep 17 00:00:00 2001 From: MechaCat02 Date: Sun, 13 Sep 2026 14:34:12 +0200 Subject: [PATCH] Run Etherpad by default: without it every topic page 500s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The legacy client requests an Etherpad session on every topic page whose lesson has contents, without ever checking whether the lesson contains a pad — controllers/topics.js collects `etherpadPads` and then ignores it. With Etherpad unreachable the request fails, `validUntil` comes back undefined, and `new Date(undefined * 1000)` makes Express reject the session cookie: "option expires is invalid", rendered as a 500. So Etherpad was only nominally optional. Moving it out of the `tools` profile also matches the live deployment, which always runs it. The topic pages that still 500 are courses the signed-in user is not a member of; the same page returns 200 for its own teacher. That is the legacy client rendering a 403 as a 500, upstream behaviour we don't own. Co-Authored-By: Claude Opus 4.8 --- local-instance/README.md | 14 ++++++++++--- local-instance/docker-compose.yml | 33 ++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/local-instance/README.md b/local-instance/README.md index a1b5824..58f8ec8 100644 --- a/local-instance/README.md +++ b/local-instance/README.md @@ -29,7 +29,7 @@ graded submissions). `seed.sh` prints the full account list on completion. > teacher `klara.fall` use `Schulcloud1!`, and the `*.qa` accounts use > `Schulcloud1qa!`. -To add the external tools (Etherpad, H5P, tldraw, Collabora): +To add the remaining external tools (H5P, tldraw, Collabora): ```bash docker compose --profile tools up -d @@ -174,11 +174,19 @@ against real data. Here it can be. | Profile | Services | Cost | |---|---|---| -| *(default)* | Mongo, Valkey, RabbitMQ, MinIO, api, management, board-collaboration, admin-api, file-storage, client, nuxt, proxy | ~4 GB images | -| `tools` | Etherpad, H5P editor + static files + library install, tldraw server + worker, Collabora | ~4 GB more, Collabora is the bulk | +| *(default)* | Mongo, Valkey, RabbitMQ, MinIO, api, management, board-collaboration, admin-api, file-storage, client, nuxt, Etherpad, proxy | ~4.7 GB images | +| `tools` | H5P editor + static files + library install, tldraw server + worker, Collabora | ~3.3 GB more, Collabora is the bulk | | `av` | ClamAV + Clammit | ~1.5 GB resident for the signature database | | `preview` | file-preview generator (thumbnails) | small | +Etherpad is in the default profile even though it is an external tool. The +legacy client requests an Etherpad session on **every** topic page whose lesson +has contents — it never checks whether a pad is actually present. With Etherpad +down that call fails, `validUntil` comes back undefined, and Express rejects the +resulting session cookie with *"option expires is invalid"*: a 500 on every +topic page, pad or no pad. The live deployment always runs it, so this is the +faithful configuration as well as the working one. + `av` is opt-in for a reason beyond size: with `ENABLE_FILE_SECURITY_CHECK=true` but no scanner reachable, every upload stays at `securityCheck.status=pending` and can never be downloaded. Turn the flag in diff --git a/local-instance/docker-compose.yml b/local-instance/docker-compose.yml index 2b8b1b0..c6faa14 100644 --- a/local-instance/docker-compose.yml +++ b/local-instance/docker-compose.yml @@ -6,7 +6,7 @@ # behaviour under test is the deployed behaviour, not a rebuild of main. # # docker compose up -d core: login, courses, boards, files -# docker compose --profile tools up -d + etherpad, h5p, tldraw, collabora +# docker compose --profile tools up -d + h5p, tldraw, collabora # docker compose --profile av up -d + virus scanning of uploads # # Everything here is a throwaway dev instance: the credentials are the upstream @@ -162,6 +162,26 @@ services: ports: ["127.0.0.1:4000:4000"] restart: unless-stopped + etherpad: + # The collaborative text editor element. + # + # Core, not a "tool", however much it looks like one: the legacy client asks + # the server for an Etherpad session on *every* topic page whose lesson has + # contents, without checking whether the lesson contains a pad at all + # (controllers/topics.js builds `etherpadPads` and then never reads it). + # Unreachable, that call fails, `validUntil` arrives undefined, and + # `new Date(undefined * 1000)` makes Express reject the session cookie — + # "option expires is invalid", a 500 on every topic page. The live + # deployment always runs Etherpad (ETHERPAD_REPLICAS: 1), so keeping it in + # the default profile is both the working and the faithful choice. + image: docker.io/etherpad/etherpad:3.3.3 + env_file: [env/etherpad.env] + volumes: + - ./etherpad/APIKEY.txt:/opt/etherpad-lite/APIKEY.txt:ro + depends_on: + mongo: {condition: service_healthy} + restart: unless-stopped + proxy: # The single origin. Everything a browser touches goes through here, so the # app sees one host the way it does in production. @@ -173,17 +193,6 @@ services: restart: unless-stopped # -------------------------------------------------- external tools ------- - etherpad: - # The collaborative text editor element on column boards. - image: docker.io/etherpad/etherpad:3.3.3 - profiles: ["tools"] - env_file: [env/etherpad.env] - volumes: - - ./etherpad/APIKEY.txt:/opt/etherpad-lite/APIKEY.txt:ro - depends_on: - mongo: {condition: service_healthy} - restart: unless-stopped - h5p-editor: image: quay.io/schulcloudverbund/h5p-server:${SC_VERSION:-33.40} profiles: ["tools"]