This setup defines a CI/CD pipeline and containerization strategy for the Critical Alert System, a Java-based backend application. It is composed of three key components: 1. Dockerfile
A multi-stage Docker build:
Stage 1 (Builder Stage):
Uses a Maven image (maven:3.9.5-eclipse-temurin-17) to build the project. It compiles the Java code and packages it into a JAR file using mvn clean package -DskipTests.
Stage 2 (Runtime Stage): Uses a lightweight JDK image (eclipse-temurin:17-jdk) to run the built JAR file. This reduces the final image size for deployment.
- .dockerignore Optimizes the Docker context by excluding unnecessary files and folders, such as: The entire target/ directory except the final JAR. Git-related files, IDE configs (.idea/), and project metadata (*.iml, README.md, etc.).
- .github/workflows/critical-alert-ci.yml This GitHub Actions workflow automates the CI/CD process: Triggers: On push or pull_request to the main branch. Environment Setup: Checks out the code. Sets up Java 17 using the temurin distribution. Builds and verifies the project using Maven. Docker Integration: Logs into GitHub Container Registry (GHCR) securely. Builds the Docker image. Pushes the image to GHCR. (Optional) Deployment: A placeholder for automated deployment on merges to main. Purpose & Benefits: Ensures consistent builds, security validation, and automated deployments. Promotes DevOps best practices: Immutable Docker builds, CI/CD automation, secure token handling, and streamlined container publishing.
Dockerfile
# First stage: build the JAR
FROM maven:3.9.5-eclipse-temurin-17 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
# Second stage: run the app
FROM eclipse-temurin:17-jdk
WORKDIR /app
COPY --from=builder /app/target/critical-alert-system-*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"].
-------------------------------------------------------
.dockerignore
# Ignore everything in target except the final JAR
target/*
!target/critical-alert-system-*.jar
# General exclusions
.git/
.gitignore
README.md
Dockerfile
*.iml
.idea/.
---------------------------------------------------------------------------
.github/workflows/critical-alert-ci.yml
name: CI/CD - Critical Alert Systems
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
env:
IMAGE_NAME: ghcr.io/${{ github.repository }}:latest
jobs:
build-test-docker:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Java 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Maven
run: mvn clean verify
- name: Log in to GHCR
run: echo "${{ secrets.GHCR_PAT }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Set lowercase image name
id: vars
run: echo "IMAGE_NAME=ghcr.io/$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]'):latest" >> $GITHUB_ENV
- name: Build Docker image
run: docker build -t $IMAGE_NAME .
- name: Push Docker image to GHCR
run: docker push $IMAGE_NAME
- name: Deploy (optional)
if: github.ref == 'refs/heads/main'
run: echo "Deploying to production"
Top comments (132)
Fantastic.....good information
Love the CI/CD pipeline setup for the Critical Alert System! The multi-stage Docker build is genius, keeping the final image lightweight and secure. The GitHub Actions workflow is well-structured, automating the build, verification, and deployment process. Great job implementing DevOps best practices.
I like how this setup balances simplicity with best practices—it’s not just about getting a JAR into a container, but doing it in a way that feels production-ready. The multi-stage build trims the fat, and pushing straight to GHCR keeps the flow tight. What stands out is how it quietly enforces discipline: no stray files, secure token usage, and a clear path to deployment without overcomplicating things.
Solid foundation. A few things that would harden this further:
Swap GHCR_PAT for GITHUB_TOKEN — for pushing to GHCR from the same repo, the built-in secrets.GITHUB_TOKEN works out of the box. It's auto-scoped to the repo, expires after the workflow run, and you never have to rotate it. Just add permissions: packages: write to the job block.
Add a container scan between build and push — right now the image goes straight to GHCR unchecked. Dropping in aquasecurity/trivy-action with severity: CRITICAL,HIGH and exit-code: 1 blocks vulnerable images from reaching the registry. One step, huge security win.
Pin action versions to commit SHA — actions/checkout@v3 means any future commit pushed to the v3 tag runs in your pipeline. Pinning to a specific SHA (actions/checkout@8e5e7e5...) prevents supply chain attacks through compromised actions.
Consider OIDC for AWS deploys — if the deploy step eventually pushes to ECR or ECS, GitHub's OIDC provider issues short-lived tokens per workflow run. No long-lived AWS keys to store or leak.
Minor Dockerfile note: the runtime stage uses eclipse-temurin:17-jdk — if the app doesn't need compiler tools at runtime, switching to 17-jre cuts the image size roughly in half.
This is a solid example of how to combine simplicity with good practices in Java. The way you’ve added security, logging, and metrics while keeping the code easy to follow makes it really useful for both beginners and those brushing up on architecture concepts.
I like how clear and modular this project is. Perfect for learning best practices in Java while simulating real-world security and monitoring scenarios. Also Your step-by-step approach makes it easy to follow and implement really thank you for sharing this post
This is a robust and professional CI/CD pipeline that exemplifies modern DevOps best practices for a Java application. The multi-stage Docker build and automated GitHub Actions workflow ensure efficient, secure, and consistent deployments from code commit to container registry
Great write-up! The multi-stage Docker build is well thought out, and using Maven for the build stage with a lightweight JDK for runtime is an efficient choice. The inclusion of a .dockerignore and GitHub Actions workflow shows a solid understanding of DevOps best practices. It’s impressive how the pipeline ensures consistent builds and secure image publishing. Curious—do you plan to add automated tests or deployment steps to the CI/CD workflow in the future?
CI/CD done right
A secure Java Alert System with Dockerized builds and GitHub Actions automation – from Maven compile → lightweight JAR runtime → pushed to GHCR. 🔐✅ This setup nails DevOps best practices: immutable images, automated tests, and ready hooks for AWS deployment.
Implemented a secure and efficient CI/CD pipeline for the Java-based Critical Alert System using Docker and GitHub Actions. It automates builds, testing, and container publishing to GHCR, following modern DevOps and security best practices.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.