From 37d3d638afcd8e0177303885281dc226d9d7e2ec Mon Sep 17 00:00:00 2001 From: Marija Stopa Date: Thu, 8 Jan 2026 13:20:51 +0100 Subject: [PATCH] Add multi-stage Dockerfile with security best practices --- Dockerfile | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..ed5429bb8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,60 @@ +# Multi-stage Dockerfile for Spring PetClinic +# Stage 1: Build +FROM eclipse-temurin:21-jdk-jammy AS builder + +WORKDIR /app + +# Copy Maven wrapper and pom.xml for dependency caching +COPY .mvn/ .mvn/ +COPY mvnw pom.xml ./ + +# Download dependencies +RUN ./mvnw dependency:go-offline -B + +# Copy source code +COPY src ./src + +# Build application +RUN ./mvnw clean package -DskipTests -B + +# Extract JAR layers for better caching +RUN mkdir -p target/extracted && \ + java -Djarmode=layertools -jar target/*.jar extract --destination target/extracted + +# Stage 2: Runtime +FROM eclipse-temurin:21-jre-jammy + +# Install curl for health checks +RUN apt-get update && \ + apt-get install -y --no-install-recommends curl && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Create non-root user +RUN groupadd -r spring && useradd -r -g spring spring + +WORKDIR /app + +# Copy extracted layers from builder +COPY --from=builder /app/target/extracted/dependencies/ ./ +COPY --from=builder /app/target/extracted/spring-boot-loader/ ./ +COPY --from=builder /app/target/extracted/snapshot-dependencies/ ./ +COPY --from=builder /app/target/extracted/application/ ./ + +# Change ownership +RUN chown -R spring:spring /app + +# Switch to non-root user +USER spring:spring + +EXPOSE 8080 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \ + CMD curl -f http://localhost:8080/actuator/health || exit 1 + +# JVM options for containers +ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0" + +# Run application +ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS org.springframework.boot.loader.launch.JarLauncher"] \ No newline at end of file