Implement per-job Docker-in-Docker (DinD) for E2E tests, giving each job a completely isolated Docker daemon and network. This prevents leakage to the host Docker or other containers. The previous E2E approach failed because: 1. The Forgejo runner's container.docker_host was not set, causing the runner itself to try unix:///var/run/docker.sock and crash-loop. 2. The host DinD daemon had isolated networking — job containers running docker compose could not resolve 'dind' hostname or access host filesystem bind mounts (e.g. .:/app). New approach — zero bind mounts, all COPY-based images: - docker/backend.e2e.Dockerfile: multi-stage build from repo root. Copies gradlew + settings.gradle + backend/build.gradle to download dependencies in a cacheable layer, then copies backend/src and builds the bootJar. Runs the JAR directly on startup. - docker/frontend.e2e.Dockerfile: multi-stage Node build → nginx. Reuses existing docker/nginx.conf for /api proxy to backend service. No volume mounts, fully self-contained. - docker/playwright.e2e.Dockerfile: extends official Playwright image. Installs deps from package-lock.json, copies e2e tests + config. - docker-compose.e2e.yml: zero bind mounts. Services depend on each other in order: postgres (healthy) → backend → frontend → playwright. Playwright waits for backend and frontend via curl loops before running tests. - .forgejo/workflows/ci.yml: E2E job adds a 'dind' service container (docker:28-dind, privileged, no TLS). The job sets DOCKER_HOST to tcp://dind:2375 so the docker CLI inside the job talks to the per-job DinD daemon. The compose file is docker-compose.e2e.yml. - Runner fix on tocke: added container.docker_host: 'tcp://dind:2375' to runner-config.yaml so the runner's own Docker client connects to the host DinD container, stopping the crash loop. Key properties: - Network isolation: each E2E job gets its own DinD with its own container network. No host container visibility. - No bind mount leakage: all images use COPY instead of volume mounts. The per-job DinD has its own filesystem and can't see host paths. - Deterministic: builds start from clean state every time. Image cache exists only within the per-job DinD lifetime. - Lint-and-test job is untouched and remains green.
10 lines
367 B
Docker
10 lines
367 B
Docker
FROM eclipse-temurin:21-jdk
|
|
WORKDIR /app
|
|
COPY gradlew settings.gradle ./
|
|
COPY gradle/wrapper/ gradle/wrapper/
|
|
COPY backend/build.gradle backend/
|
|
RUN chmod +x gradlew && ./gradlew :backend:dependencies --no-daemon -q
|
|
COPY backend/src backend/src
|
|
RUN ./gradlew :backend:bootJar --no-daemon -q
|
|
EXPOSE 8080
|
|
CMD ["sh", "-c", "java -jar backend/build/libs/*-SNAPSHOT.jar"]
|