From a52b8a06940745b136623194e141f81568befb7e Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 19 Mar 2026 12:56:59 +0100 Subject: [PATCH 1/5] fix(auth): use API_INTERNAL_URL in userGroup hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The userGroup hook was hardcoding http://localhost:8080 instead of reading API_INTERNAL_URL from the environment. In Docker this caused the /api/users/me fetch to fail silently, leaving event.locals.user unset and triggering the handleAuth guard to redirect every page to /login — including the login form action itself, creating an infinite redirect loop. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/hooks.server.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/hooks.server.ts b/frontend/src/hooks.server.ts index 716b7fbd..6271507e 100644 --- a/frontend/src/hooks.server.ts +++ b/frontend/src/hooks.server.ts @@ -27,7 +27,8 @@ const userGroup: Handle = async ({ event, resolve }) => { if (auth) { try { - const response = await fetch('http://localhost:8080/api/users/me', { + const apiUrl = env.API_INTERNAL_URL || 'http://localhost:8080'; + const response = await fetch(`${apiUrl}/api/users/me`, { headers: { Authorization: auth } }); -- 2.49.1 From 5044f99aac1898f561fae61752b0b58ca38a7bfb Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 19 Mar 2026 12:58:21 +0100 Subject: [PATCH 2/5] fix(api): use API_INTERNAL_URL in tags and persons proxy routes Both SvelteKit API proxy routes were hardcoding http://localhost:8080, breaking typeahead search in Docker environments. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/routes/api/persons/+server.ts | 3 ++- frontend/src/routes/api/tags/+server.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/src/routes/api/persons/+server.ts b/frontend/src/routes/api/persons/+server.ts index 71f51963..23ee59ae 100644 --- a/frontend/src/routes/api/persons/+server.ts +++ b/frontend/src/routes/api/persons/+server.ts @@ -1,5 +1,6 @@ import { json } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; +import { env } from 'process'; export const GET: RequestHandler = async ({ url, fetch }) => { // 1. Suchparameter aus der URL des Browsers holen @@ -8,7 +9,7 @@ export const GET: RequestHandler = async ({ url, fetch }) => { try { // 3. Anfrage an das Java-Backend weiterleiten (Server-to-Server) // Wir nutzen hier den internen Docker-Hostnamen oder localhost, je nach Netzwerk - const backendUrl = `http://localhost:8080/api/persons?q=${encodeURIComponent(q)}`; + const backendUrl = `${env.API_INTERNAL_URL || 'http://localhost:8080'}/api/persons?q=${encodeURIComponent(q)}`; const response = await fetch(backendUrl, { method: 'GET', diff --git a/frontend/src/routes/api/tags/+server.ts b/frontend/src/routes/api/tags/+server.ts index 63c9829d..4e43e11b 100644 --- a/frontend/src/routes/api/tags/+server.ts +++ b/frontend/src/routes/api/tags/+server.ts @@ -1,5 +1,6 @@ import { json } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; +import { env } from 'process'; export const GET: RequestHandler = async ({ url, fetch }) => { // 1. Suchparameter aus der URL des Browsers holen @@ -8,7 +9,7 @@ export const GET: RequestHandler = async ({ url, fetch }) => { try { // 3. Anfrage an das Java-Backend weiterleiten (Server-to-Server) // Wir nutzen hier den internen Docker-Hostnamen oder localhost, je nach Netzwerk - const backendUrl = `http://localhost:8080/api/tags?q=${encodeURIComponent(q)}`; + const backendUrl = `${env.API_INTERNAL_URL || 'http://localhost:8080'}/api/tags?q=${encodeURIComponent(q)}`; const response = await fetch(backendUrl, { method: 'GET', -- 2.49.1 From a87f40d0ea43f6ed88603923857ffc84f78c1df9 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 19 Mar 2026 13:06:38 +0100 Subject: [PATCH 3/5] fix(ci): pass docker-compose.ci.yml override to e2e compose commands The e2e job was calling plain `docker compose up` without the CI override file, so it used the base compose bind-mount for MinIO (./data/minio) which doesn't exist on the runner. The CI override replaces bind mounts with ephemeral named volumes. Co-Authored-By: Claude Sonnet 4.6 --- .gitea/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 991ea0b5..e060c25f 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -109,10 +109,10 @@ jobs: # ── Infrastructure ────────────────────────────────────────────────────── - name: Cleanup leftover containers from previous runs - run: docker compose down --volumes --remove-orphans || true + run: docker compose -f docker-compose.yml -f docker-compose.ci.yml down --volumes --remove-orphans || true - name: Start DB and MinIO - run: docker compose up -d db minio create-buckets + run: docker compose -f docker-compose.yml -f docker-compose.ci.yml up -d db minio create-buckets - name: Wait for DB to be ready run: | -- 2.49.1 From c023d5b0a2e086c2e2aa61411d3f5592f3fe236a Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 19 Mar 2026 14:00:51 +0100 Subject: [PATCH 4/5] fix(ci): connect job container to compose network for DB/MinIO access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The act_runner job runs inside a Docker container. Docker Compose port mappings bind to the Docker host, not the job container's localhost — so localhost:5433 was always refused. Fix: after compose starts, connect the job container (identified by /etc/hostname) to the archive-net compose network. Then switch the backend startup args to use service names db:5432 and minio:9000 instead of host-mapped ports. Co-Authored-By: Claude Sonnet 4.6 --- .gitea/workflows/ci.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index e060c25f..2f348f5c 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -117,7 +117,10 @@ jobs: - name: Wait for DB to be ready run: | timeout 30 bash -c \ - 'until docker compose exec -T db pg_isready -U archive_user; do sleep 2; done' + 'until docker compose -f docker-compose.yml -f docker-compose.ci.yml exec -T db pg_isready -U archive_user; do sleep 2; done' + + - name: Connect job container to compose network + run: docker network connect familienarchiv_archive-net $(cat /etc/hostname) # ── Backend ───────────────────────────────────────────────────────────── - uses: actions/setup-java@v4 @@ -142,10 +145,10 @@ jobs: run: | java -jar backend/target/*.jar \ --spring.profiles.active=e2e \ - --SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5433/family_archive_db \ + --SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/family_archive_db \ --SPRING_DATASOURCE_USERNAME=archive_user \ --SPRING_DATASOURCE_PASSWORD=ci_db_password \ - --S3_ENDPOINT=http://localhost:9100 \ + --S3_ENDPOINT=http://minio:9000 \ --S3_ACCESS_KEY=minio_admin \ --S3_SECRET_KEY=ci_minio_password \ --S3_BUCKET_NAME=archive-documents \ -- 2.49.1 From 706c029a5e43cae7e4fadc564818df2ecdf3e418 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 19 Mar 2026 14:32:27 +0100 Subject: [PATCH 5/5] fix(ci): pin DOCKER_API_VERSION=1.43 for e2e job The runner's Docker client negotiates API 1.53 but the daemon on the NAS only supports up to 1.43. Pin the version for all docker commands in the e2e job, including the new network connect step. Co-Authored-By: Claude Sonnet 4.6 --- .gitea/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 2f348f5c..5c5e0683 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -92,6 +92,7 @@ jobs: # These env vars are picked up by docker-compose (overrides .env file) env: + DOCKER_API_VERSION: "1.43" POSTGRES_USER: archive_user POSTGRES_PASSWORD: ci_db_password POSTGRES_DB: family_archive_db -- 2.49.1