From d943aac3e3b2840f0caa5c78e143a97571d5f466 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 15 Apr 2026 11:15:05 +0200 Subject: [PATCH 1/4] devops(backend): switch to multi-stage Docker build Replace runtime mvn spring-boot:run with a proper multi-stage build: - Stage 1 (builder): compiles JAR with BuildKit cache mount for ~/.m2 - Stage 2 (runtime): eclipse-temurin:21-jre with only the JAR Removes the backend source volume mount and maven_cache named volume. Deploy with: docker compose up -d --build Co-Authored-By: Claude Sonnet 4.6 --- backend/Dockerfile | 19 +++++++++++++------ docker-compose.yml | 3 --- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 33fe810a..a6cd524e 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,9 +1,16 @@ -FROM eclipse-temurin:21-jdk - +FROM eclipse-temurin:21-jdk AS builder WORKDIR /app -EXPOSE 8080 +# Copy wrapper and POM first — dependency layer is cached separately from source +COPY .mvn .mvn +COPY mvnw pom.xml ./ +RUN --mount=type=cache,target=/root/.m2 ./mvnw dependency:go-offline -q -# Source code and mvnw are mounted via docker-compose volume at runtime. -# Maven dependencies are cached in a named volume (~/.m2). -CMD ["./mvnw", "spring-boot:run"] +COPY src ./src +RUN --mount=type=cache,target=/root/.m2 ./mvnw clean package -DskipTests -q + +FROM eclipse-temurin:21-jre +WORKDIR /app +COPY --from=builder /app/target/*.jar app.jar +EXPOSE 8080 +CMD ["java", "-jar", "app.jar"] diff --git a/docker-compose.yml b/docker-compose.yml index 0637d417..ce7cdf73 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -112,9 +112,7 @@ services: container_name: archive-backend restart: unless-stopped volumes: - - ./backend:/app - ./import:/import - - maven_cache:/root/.m2 depends_on: db: condition: service_healthy @@ -191,6 +189,5 @@ networks: volumes: frontend_node_modules: - maven_cache: ocr_models: ocr_cache: -- 2.49.1 From eee2d4ff812d702db211d9d644a0f8ca0efc6ce0 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 15 Apr 2026 11:28:25 +0200 Subject: [PATCH 2/4] devops(backend): add .dockerignore to exclude target/ from build context Prevents 111MB of compiled output from being sent to the BuildKit daemon on cold builds. Only .mvn/, mvnw, pom.xml, and src/ are needed by the three COPY instructions in the Dockerfile. Co-Authored-By: Claude Sonnet 4.6 --- backend/.dockerignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 backend/.dockerignore diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 00000000..3ddbd536 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,4 @@ +target/ +.git/ +*.md +api_tests/ -- 2.49.1 From 3865a9c1134658acae074af53492663142c98b12 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 15 Apr 2026 11:29:13 +0200 Subject: [PATCH 3/4] devops(backend): pin eclipse-temurin tags, skip test compilation, document jar glob MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Pin to eclipse-temurin:21.0.10_7-{jdk,jre}-noble for reproducible builds - Switch -DskipTests to -Dmaven.test.skip=true: skips test compilation entirely, not just execution — faster and avoids build failures from test-only missing classes - Add comment on COPY *.jar explaining why the glob is safe (Spring Boot renames the pre-repackage artifact to .jar.original, leaving only one .jar in target/) Co-Authored-By: Claude Sonnet 4.6 --- backend/Dockerfile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index a6cd524e..3f2c02a5 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,4 +1,4 @@ -FROM eclipse-temurin:21-jdk AS builder +FROM eclipse-temurin:21.0.10_7-jdk-noble AS builder WORKDIR /app # Copy wrapper and POM first — dependency layer is cached separately from source @@ -7,10 +7,12 @@ COPY mvnw pom.xml ./ RUN --mount=type=cache,target=/root/.m2 ./mvnw dependency:go-offline -q COPY src ./src -RUN --mount=type=cache,target=/root/.m2 ./mvnw clean package -DskipTests -q +# -Dmaven.test.skip=true skips test compilation entirely (not just execution) +RUN --mount=type=cache,target=/root/.m2 ./mvnw clean package -Dmaven.test.skip=true -q -FROM eclipse-temurin:21-jre +FROM eclipse-temurin:21.0.10_7-jre-noble WORKDIR /app +# Spring Boot repackages to *.jar; pre-repackage artifact uses .jar.original, not .jar COPY --from=builder /app/target/*.jar app.jar EXPOSE 8080 CMD ["java", "-jar", "app.jar"] -- 2.49.1 From bbafbe6a072ce3f86dddef5eaa0ace37bf69faa4 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 15 Apr 2026 11:30:04 +0200 Subject: [PATCH 4/4] devops(backend): reduce healthcheck start_period to 30s With a pre-built JAR, Spring Boot + Flyway starts in ~15 seconds. The previous 60s was sized for runtime compilation (90+ seconds). Co-Authored-By: Claude Sonnet 4.6 --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index ce7cdf73..1a55f04d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -153,7 +153,7 @@ services: interval: 15s timeout: 5s retries: 10 - start_period: 60s + start_period: 30s # JAR starts in ~15s; was 60s when compilation happened at startup # --- Frontend: SvelteKit (Dev Server) --- frontend: -- 2.49.1