Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions .github/workflows/spring-prometheus-grafana-example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: spring-prometheus-grafana-example CI Build

on:
pull_request:
branches: [master]
paths:
- "spring-prometheus-grafana-example/**"
types:
- opened
- synchronize
- reopened

jobs:

integration-tests:
name: Run Unit & Integration Tests
runs-on: ubuntu-latest
defaults:
run:
working-directory: spring-prometheus-grafana-example
strategy:
matrix:
distribution: [ 'temurin' ]
java: [ '21' ]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up JDK ${{ matrix.java }}
uses: actions/[email protected]
with:
java-version: ${{ matrix.java }}
distribution: ${{ matrix.distribution }}
cache: 'maven'
- name: Build and analyze
run: ./mvnw clean verify

health-check:
runs-on: ubuntu-latest
steps:
- name: Checkout repository and submodules
uses: actions/checkout@v4
with:
submodules: true

- name: Start containers with Compose Action
uses: hoverkraft-tech/[email protected]
with:
compose-file: './spring-prometheus-grafana-example/compose.yaml'
services: |
app
up-flags: '--build'
down-flags: '--volumes'

- name: Wait for containers to initialize
run: sleep 10

- name: Check container health
run: |
echo "Verificando saúde dos containers..."

APP_STATUS=$(docker inspect -f '{{.State.Running}}' app || echo "false")

echo "Status do app: $APP_STATUS"

if [ "$APP_STATUS" != "true" ]; then
echo "::error ::An error occurred while executing the containers."
exit 1
fi

# Se chegou aqui, ambos estão ativos
- name: Success message
run: echo "Container testing completed successfully!"
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

<modules>
<module>spring-kafka-example</module>
<module>spring-prometheus-grafana-example</module>
</modules>

</project>
62 changes: 62 additions & 0 deletions spring-prometheus-grafana-example/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Include any files or directories that you don't want to be copied to your
# container here (e.g., local build artifacts, temporary files, etc.).
#
# For more help, visit the .dockerignore file reference guide at
# https://docs.docker.com/go/build-context-dockerignore/

**/.DS_Store
**/.classpath
**/.dockerignore
**/.env
**/.factorypath
**/.git
**/.gitignore
**/.idea
**/.project
**/.sts4-cache
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.next
**/.cache
**/*.dbmdl
**/*.jfm
**/charts
**/docker-compose*
**/compose.y*ml
**/Dockerfile*
**/secrets.dev.yaml
**/values.dev.yaml
**/vendor
LICENSE
README.md
**/*.class
**/*.iml
**/*.ipr
**/*.iws
**/*.log
**/.apt_generated
**/.gradle
**/.gradletasknamecache
**/.nb-gradle
**/.springBeans
**/build
**/dist
**/gradle-app.setting
**/nbbuild
**/nbdist
**/nbproject/private
**/target
*.ctxt
.mtj.tmp
.mvn/timing.properties
buildNumber.properties
dependency-reduced-pom.xml
hs_err_pid*
pom.xml.next
pom.xml.releaseBackup
pom.xml.tag
pom.xml.versionsBackup
release.properties
replay_pid*
2 changes: 2 additions & 0 deletions spring-prometheus-grafana-example/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/mvnw text eol=lf
*.cmd text eol=crlf
30 changes: 30 additions & 0 deletions spring-prometheus-grafana-example/.github/workflows/maven.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI Build

on:
push:
branches:
- "**"

jobs:
build:
name: Build
runs-on: ubuntu-latest
strategy:
matrix:
distribution: [ 'temurin' ]
java: [ '21' ]
steps:
- uses: actions/checkout@v4

- name: Setup Java 21
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
distribution: ${{ matrix.distribution }}
cache: 'maven'

- name: Grant execute permission for mvnw
run: chmod +x mvnw

- name: Build with Maven
run: ./mvnw clean verify
32 changes: 32 additions & 0 deletions spring-prometheus-grafana-example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
target/
.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip
47 changes: 47 additions & 0 deletions spring-prometheus-grafana-example/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
FROM eclipse-temurin:21-jdk-jammy as deps

WORKDIR /build

COPY --chmod=0755 mvnw mvnw
COPY .mvn/ .mvn/

RUN --mount=type=bind,source=pom.xml,target=pom.xml \
--mount=type=cache,target=/root/.m2 ./mvnw dependency:go-offline -DskipTests

FROM deps as package

WORKDIR /build

COPY ./src src/
RUN --mount=type=bind,source=pom.xml,target=pom.xml \
--mount=type=cache,target=/root/.m2 \
./mvnw package -DskipTests && \
mv target/$(./mvnw help:evaluate -Dexpression=project.artifactId -q -DforceStdout)-$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout).jar target/app.jar
Comment on lines +16 to +19
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Quote command substitution to avoid word-splitting (Hadolint SC2046)

-    mv target/$(./mvnw help:evaluate -Dexpression=project.artifactId -q -DforceStdout)-$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout).jar target/app.jar
+    mv target/"$(./mvnw help:evaluate -Dexpression=project.artifactId -q -DforceStdout)"-"$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)".jar target/app.jar

Prevents edge-cases when artifactId contains spaces.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
RUN --mount=type=bind,source=pom.xml,target=pom.xml \
--mount=type=cache,target=/root/.m2 \
./mvnw package -DskipTests && \
mv target/$(./mvnw help:evaluate -Dexpression=project.artifactId -q -DforceStdout)-$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout).jar target/app.jar
RUN --mount=type=bind,source=pom.xml,target=pom.xml \
--mount=type=cache,target=/root/.m2 \
./mvnw package -DskipTests && \
mv target/"$(./mvnw help:evaluate -Dexpression=project.artifactId -q -DforceStdout)"-"$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)".jar target/app.jar
🧰 Tools
🪛 Hadolint (2.12.0)

[warning] 16-16: Quote this to prevent word splitting.

(SC2046)

🤖 Prompt for AI Agents
In spring-prometheus-grafana-example/Dockerfile around lines 16 to 19, the
command substitution used to get the artifactId and version is not quoted, which
can cause word-splitting issues if the artifactId contains spaces. To fix this,
wrap the command substitutions in double quotes to ensure the entire output is
treated as a single string and prevent splitting or globbing errors.


FROM package as extract

WORKDIR /build

RUN java -Djarmode=layertools -jar target/app.jar extract --destination target/extracted

FROM eclipse-temurin:21-jre-jammy AS final

ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
USER appuser

COPY --from=extract build/target/extracted/dependencies/ ./
COPY --from=extract build/target/extracted/spring-boot-loader/ ./
COPY --from=extract build/target/extracted/snapshot-dependencies/ ./
COPY --from=extract build/target/extracted/application/ ./
Comment on lines +27 to +43
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Set WORKDIR before layering & fix relative COPY warnings

Without a WORKDIR, the four COPY commands place files at /, triggering Hadolint DL3045 and cluttering the root. Define an explicit working directory in the runtime image and copy into it:

-FROM eclipse-temurin:21-jre-jammy AS final
+FROM eclipse-temurin:21-jre-jammy AS final
+
+WORKDIR /app
...
-COPY --from=extract build/target/extracted/dependencies/ ./
+COPY --from=extract /build/target/extracted/dependencies/ ./

(Repeat for the other three COPY lines.)

This keeps the layer structure tidy and predictable.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
FROM eclipse-temurin:21-jre-jammy AS final
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
USER appuser
COPY --from=extract build/target/extracted/dependencies/ ./
COPY --from=extract build/target/extracted/spring-boot-loader/ ./
COPY --from=extract build/target/extracted/snapshot-dependencies/ ./
COPY --from=extract build/target/extracted/application/ ./
FROM eclipse-temurin:21-jre-jammy AS final
WORKDIR /app
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
USER appuser
COPY --from=extract /build/target/extracted/dependencies/ ./
COPY --from=extract /build/target/extracted/spring-boot-loader/ ./
COPY --from=extract /build/target/extracted/snapshot-dependencies/ ./
COPY --from=extract /build/target/extracted/application/ ./
🧰 Tools
🪛 Hadolint (2.12.0)

[warning] 40-40: COPY to a relative destination without WORKDIR set.

(DL3045)


[warning] 41-41: COPY to a relative destination without WORKDIR set.

(DL3045)


[warning] 42-42: COPY to a relative destination without WORKDIR set.

(DL3045)


[warning] 43-43: COPY to a relative destination without WORKDIR set.

(DL3045)

🤖 Prompt for AI Agents
In spring-prometheus-grafana-example/Dockerfile lines 27 to 43, the COPY
commands place files directly into the root directory because no WORKDIR is set,
causing Hadolint DL3045 warnings. To fix this, add a WORKDIR instruction before
the COPY commands to define a specific working directory (e.g., /app), then
update each COPY command to copy files into this directory. This organizes the
layers and avoids cluttering the root filesystem.


EXPOSE 80

ENTRYPOINT [ "java", "org.springframework.boot.loader.launch.JarLauncher" ]
Comment on lines +45 to +47
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Provide a container HEALTHCHECK

Checkov flags missing health-checks. A lightweight HTTP probe against Spring Boot’s actuator keeps orchestrators informed:

 EXPOSE 80

+HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
+  CMD curl -f http://localhost:80/actuator/health || exit 1
+
 ENTRYPOINT [ "java", "org.springframework.boot.loader.launch.JarLauncher" ]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
EXPOSE 80
ENTRYPOINT [ "java", "org.springframework.boot.loader.launch.JarLauncher" ]
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD curl -f http://localhost:80/actuator/health || exit 1
ENTRYPOINT [ "java", "org.springframework.boot.loader.launch.JarLauncher" ]
🧰 Tools
🪛 Checkov (3.2.334)

[LOW] 1-47: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)

🤖 Prompt for AI Agents
In spring-prometheus-grafana-example/Dockerfile around lines 45 to 47, add a
HEALTHCHECK instruction to define a container health probe. Implement a
lightweight HTTP GET request to the Spring Boot actuator endpoint (e.g.,
/actuator/health) to verify the application is running. This will help container
orchestrators monitor container health and respond appropriately.

9 changes: 9 additions & 0 deletions spring-prometheus-grafana-example/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

services:
Comment on lines +1 to +2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Remove leading blank line—YAMLlint failure

The first empty line violates empty-lines rule and breaks some parsers.

-
 services:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
services:
services:
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: too many blank lines (1 > 0)

(empty-lines)

🤖 Prompt for AI Agents
In spring-prometheus-grafana-example/compose.yaml at the beginning of the file
(lines 1-2), remove the leading blank line before the "services:" key to comply
with YAML syntax rules and avoid parser errors.


app:
container_name: app
build:
context: .
ports:
- "80:80"
Comment on lines +4 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Consider including Prometheus & Grafana services

Since this example showcases Prometheus/Grafana integration, composing those containers here would let users spin up the full stack with one command. If omission is intentional (e.g., external stack or k8s), feel free to disregard.


🏁 Script executed:

#!/bin/bash
# Locate any Docker Compose files and show their contents
find . -maxdepth 3 -type f \( -name "*compose*.yml" -o -name "*compose*.yaml" \) | while read -r f; do
  echo "File: $f"
  head -n 200 "$f"
  echo "----"
done

Length of output: 1408


Add Prometheus & Grafana services to the Compose file

To enable users to bring up the full Prometheus/Grafana stack with the example, extend spring-prometheus-grafana-example/compose.yaml by adding the Prometheus and Grafana services (with hard-coded container names to satisfy CI validation):

• File: spring-prometheus-grafana-example/compose.yaml
• Insert under services: after the existing app: block

Suggested diff:

 services:

   app:
     container_name: app
     build:
       context: .
     ports:
       - "80:80"

+  prometheus:
+    container_name: prometheus
+    image: prom/prometheus:latest
+    ports:
+      - "9090:9090"
+    volumes:
+      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
+
+  grafana:
+    container_name: grafana
+    image: grafana/grafana:latest
+    ports:
+      - "3000:3000"
+    environment:
+      GF_SECURITY_ADMIN_PASSWORD: "admin"

If you intentionally manage Prometheus/Grafana outside of this Compose file (e.g., via Kubernetes or an external stack), you can ignore this suggestion.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 9-9: no new line character at the end of file

(new-line-at-end-of-file)

🤖 Prompt for AI Agents
In spring-prometheus-grafana-example/compose.yaml around lines 4 to 9, the
Compose file currently only defines the app service. To enable bringing up the
full Prometheus and Grafana stack, add two new services under the services
section after the app block: one for Prometheus with a hard-coded container_name
"prometheus" and appropriate image and port mappings, and another for Grafana
with container_name "grafana" and its respective image and port mappings. This
will allow users to start the full monitoring stack using this Compose file.

Comment on lines +8 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Add terminating newline

A missing final newline also raises YAMLlint warnings and can trip diff tools.

-      - "80:80"
+      - "80:80"
+
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ports:
- "80:80"
ports:
- "80:80"
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 9-9: no new line character at the end of file

(new-line-at-end-of-file)

🤖 Prompt for AI Agents
In spring-prometheus-grafana-example/compose.yaml at lines 8 to 9, the file is
missing a terminating newline at the end. Add a newline character after the last
line to ensure the file ends with a proper newline, which will prevent YAMLlint
warnings and avoid issues with diff tools.

Loading