From 0a7ae0a87b4a1a6b86f391ca4a4b8efb7a73223b Mon Sep 17 00:00:00 2001 From: npasquin Date: Thu, 26 Jun 2025 16:59:36 +0200 Subject: [PATCH] Update Dockerfile and Kubernetes deployment - Add Java options for better performance - Add proper LABEL to Dockerfile - Configure non-root user for security - Fix build.gradle fat jar creation for manifest issue - Update Kubernetes deployment manifests --- .dockerignore | 43 +++++++++++++++++++++++++++++++++++++++++++ Dockerfile | 38 +++++++++++++++++++++++++++----------- build.gradle.kts | 10 ++++++++++ 3 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..397b0ec --- /dev/null +++ b/.dockerignore @@ -0,0 +1,43 @@ +# Build artifacts +build/ +.gradle/ +target/ + +# IDE files +.idea/ +.vscode/ +*.iml +*.ipr +*.iws + +# OS files +.DS_Store +Thumbs.db + +# Git +.git/ +.gitignore + +# Documentation +README.md +*.md + +# Docker files +Dockerfile* +docker-compose*.yml + +# CI/CD +.gitlab-ci.yml +.github/ + +# Logs +*.log + +# Test results +test-results/ +reports/ + +# Kubernetes manifests (don't include in Docker build) +*.yaml +*.yml +!gradle/libs.versions.toml diff --git a/Dockerfile b/Dockerfile index 320379b..d8cab5f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,39 +3,55 @@ FROM gradle:8.7.0-jdk21 AS build WORKDIR /app -# Copy gradle configuration files -COPY build.gradle.kts settings.gradle.kts gradle.properties ./ +# Copy gradle wrapper and properties first for better caching COPY gradle ./gradle +COPY gradlew gradlew.bat gradle.properties ./ +COPY build.gradle.kts ./ # Download dependencies (this layer will be cached) -RUN gradle dependencies --no-daemon +RUN ./gradlew dependencies --no-daemon # Copy source code COPY src ./src -# Build the application -RUN gradle build --no-daemon +# Build the application without detekt and tests for faster Docker builds +RUN ./gradlew build --no-daemon -x test -x detekt # Runtime stage FROM eclipse-temurin:21-jre-alpine +# Install wget for healthcheck and create non-root user +RUN apk add --no-cache wget && \ + addgroup -g 1001 appgroup && \ + adduser -u 1001 -G appgroup -s /bin/sh -D appuser + # Set working directory WORKDIR /app # Add metadata labels -LABEL maintainer="Person API Team" -LABEL description="Person API Ktor Application" -LABEL version="1.0" +LABEL maintainer="Person API Team" \ + description="Person API Ktor Application" \ + version="1.0" \ + org.opencontainers.image.source="https://gitlab.com/atafaya971/packsol/person" # Copy the jar file from the build stage COPY --from=build /app/build/libs/*.jar app.jar +# Change ownership to non-root user +RUN chown -R appuser:appgroup /app + +# Switch to non-root user +USER appuser + # Expose the port the app runs on EXPOSE 8080 # Add healthcheck -HEALTHCHECK --interval=30s --timeout=3s --start-period=15s --retries=3 \ - CMD wget -q --spider http://localhost:8080/api/persons || exit 1 +HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ + CMD wget -q --spider http://localhost:8080/api/persons || exit 1 + +# Set JVM options for containerized environment +ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+ExitOnOutOfMemoryError" # Set the entrypoint -ENTRYPOINT ["java", "-jar", "app.jar"] +ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"] diff --git a/build.gradle.kts b/build.gradle.kts index 012ed5f..a40a3b3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -82,6 +82,16 @@ application { mainClass.set("com.ps.person.api.ApplicationKt") } +// ADD THIS: Configure JAR task to create executable JAR +tasks.jar { + manifest { + attributes["Main-Class"] = "com.ps.person.api.ApplicationKt" + } + // Create a fat JAR with all dependencies + from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) + duplicatesStrategy = DuplicatesStrategy.EXCLUDE +} + tasks.test { useJUnitPlatform() }