Description
This issue covers creating a containerized environment for the application with multi-stage builds and Docker Compose orchestration, plus updating the CI workflow to build and push the container image to GitHub Container Registry (GHCR). This ensures streamlined builds, easy local dev/testing, and automatic publishing of container images on push.
Proposed Solution
- Create a multi-stage
Dockerfile with build and runtime stages.
- Add a
.dockerignore file for efficient builds.
- Add a Docker Compose file (
compose.yaml) for local orchestration.
- Include a health check script for container health validation.
- Update the CI workflow to:
- Build the Docker image.
- Authenticate with GHCR.
- Push the image with proper tags (e.g.,
latest, git SHA).
Suggested Approach
Dockerfile
# ------------------------------------------------------------------------------
# Stage 1: Builder
# This stage builds the application and its dependencies.
# ------------------------------------------------------------------------------
FROM maven:3.9-eclipse-temurin-21-alpine AS builder
WORKDIR /app
# Copy pom.xml and source code
COPY pom.xml .
COPY src ./src
# Build the application and skip tests for faster build
RUN mvn clean package -DskipTests
# ------------------------------------------------------------------------------
# Stage 2: Runtime
# This stage creates the final, minimal image to run the application.
# ------------------------------------------------------------------------------
FROM eclipse-temurin:21-jdk-alpine AS runtime
WORKDIR /app
# Install curl for health check
RUN apk add --no-cache curl
# Metadata labels for the image. These are useful for registries and inspection.
LABEL org.opencontainers.image.title="🧪 RESTful Web Service with Spring Boot"
LABEL org.opencontainers.image.description="Proof of Concept for a RESTful Web Service made with JDK 21 (LTS) and Spring Boot 3"
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.source="https://github.com/nanotaboada/java.samples.spring.boot"
# https://rules.sonarsource.com/docker/RSPEC-6504/
# Copy application JAR file from the builder stage
COPY --from=builder /app/target/*.jar ./app.jar
# Copy metadata docs for container registries (e.g.: GitHub Container Registry)
COPY --chmod=444 README.md ./
COPY --chmod=555 assets/ ./assets/
# Copy entrypoint and healthcheck scripts
COPY --chmod=555 scripts/healthcheck.sh ./healthcheck.sh
# Add system user
RUN addgroup -S spring && \
adduser -S -G spring spring
USER spring
EXPOSE 9000
EXPOSE 9001
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD ["./healthcheck.sh"]
ENTRYPOINT ["java", "-jar", "./app.jar"]
healthcheck.sh
#!/bin/sh
set -e
# Minimal curl-based health check with timeout and error reporting
curl --fail --silent --show-error --connect-timeout 1 --max-time 2 http://localhost:9000/health
.dockerignore
.github
.mvn
.vscode
target
.codacy.yml
.gitignore
azure-pipelines.yml
CODE_OF_CONDUCT.md
codecov.yml
CONTRIBUTING.md
LICENSE
mvnw
mvnw.cmd
compose.yaml
services:
api:
image: java-samples-spring-boot
container_name: spring-app
build:
context: .
dockerfile: Dockerfile
ports:
- "9000:9000"
- "9001:9001"
environment:
- SPRING_PROFILES_ACTIVE=production
- SERVER_PORT=9000
restart: unless-stopped
Acceptance Criteria
Dockerfile builds a working image with multi-stage build.
.dockerignore excludes unnecessary files.
- Docker Compose spins up the app with environment variables and health check working.
- Docker image runs as non-root user.
- CI workflow builds and pushes Docker image to GHCR on main branch push.
- Workflow uses secrets safely and authenticates properly to GHCR.
Resources
Description
This issue covers creating a containerized environment for the application with multi-stage builds and Docker Compose orchestration, plus updating the CI workflow to build and push the container image to GitHub Container Registry (GHCR). This ensures streamlined builds, easy local dev/testing, and automatic publishing of container images on push.
Proposed Solution
Dockerfilewith build and runtime stages..dockerignorefile for efficient builds.compose.yaml) for local orchestration.latest, git SHA).Suggested Approach
Dockerfilehealthcheck.sh.dockerignorecompose.yamlAcceptance Criteria
Dockerfilebuilds a working image with multi-stage build..dockerignoreexcludes unnecessary files.Resources