From e9f52fa230c700f8b634a2086acf619700fdd0f4 Mon Sep 17 00:00:00 2001 From: Alan Brault Date: Fri, 5 Jun 2026 07:40:10 -0400 Subject: [PATCH] chore: create docker artifacts Signed-off-by: Alan Brault --- .dockerignore | 22 ++++++++++++++++++++++ Dockerfile | 45 +++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..fd5d46b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,22 @@ +build/ +.gradle/ +.kotlin/ + +.idea/ +*.iml +.vscode/ +.editorconfig + +.git/ +.gitattributes +.gitignore + +.env +.env.* +!.env.example + +HELP.md +*.md + +.DS_Store +Thumbs.db diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..83d5891 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +# syntax=docker/dockerfile:1 + +# ── Stage 1: Builder ────────────────────────────────────────────────────────── +# eclipse-temurin:21-jdk-noble +FROM eclipse-temurin@sha256:81cecb98bcca2d5d5c3d496e71779073865db0d0bd776ecf434e017f20dac638 AS builder + +WORKDIR /workspace + +COPY gradle/ gradle/ +COPY gradlew gradlew +COPY build.gradle.kts build.gradle.kts +COPY settings.gradle.kts settings.gradle.kts +COPY gradle.properties gradle.properties + +RUN chmod +x gradlew && ./gradlew dependencies --no-daemon + +# Source build +COPY src/ src/ +RUN ./gradlew bootJar --no-daemon -x test -x ktlintCheck + + +# ── Stage 2: Runtime ───────────────────────────────────────────────────────── +# gcr.io/distroless/java21-debian12 — no shell, no package manager, minimal attack surface +# Predefined nonroot user UID/GID: 65532 +FROM gcr.io/distroless/java21-debian12@sha256:f34fd3e4e2d7a246d764d0614f5e6ffb3a735930723fac4cfc25a72798950262 AS runtime + +WORKDIR /app + +# Glob matches fat jar (kotlin-api-0.0.1-SNAPSHOT.jar) but not -plain.jar +# --chown uses numeric UID:GID since distroless has no shell to resolve names +COPY --from=builder --chown=65532:65532 /workspace/build/libs/kotlin-api-*SNAPSHOT.jar app.jar + +USER 65532 + +EXPOSE 8080 + +# Leave empty so Spring fails fast with a clear error if not provided at runtime. +ENV MONGODB_URI="" +ENV JWT_ENCRYPTION_SECRET="" + +ENTRYPOINT ["/usr/bin/java", \ + "-XX:+UseContainerSupport", \ + "-XX:MaxRAMPercentage=75.0", \ + "-Djava.security.egd=file:/dev/./urandom", \ + "-jar", "/app/app.jar"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..965ce22 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,40 @@ +services: + app: + build: . + ports: + - "8080:8080" + environment: + # Override the local-dev default — "mongodb" resolves to the service below + MONGODB_URI: mongodb://mongodb:27017/kotlin-api + # Interpolated from .env (copy .env.example → .env and fill in the value) + JWT_ENCRYPTION_SECRET: ${JWT_ENCRYPTION_SECRET} + depends_on: + mongodb: + condition: service_healthy + networks: + - backend + + mongodb: + # mongo:8.0 + image: mongo@sha256:f93b9015613e393b76fdf4fb71f3435ece6a3b46cc56c62c08875ad08442aa4c + ports: + - "27017:27017" + environment: + MONGO_INITDB_DATABASE: kotlin-api + volumes: + - mongodb_data:/data/db + healthcheck: + test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 10s + networks: + - backend + +networks: + backend: + driver: bridge + +volumes: + mongodb_data: