Skip to content

feat: add multi-stage Dockerfile for building and running app#195

Merged
nanotaboada merged 2 commits intomasterfrom
feature/dockerfile
May 25, 2025
Merged

feat: add multi-stage Dockerfile for building and running app#195
nanotaboada merged 2 commits intomasterfrom
feature/dockerfile

Conversation

@nanotaboada
Copy link
Copy Markdown
Owner

@nanotaboada nanotaboada commented May 25, 2025

This change is Reviewable

Summary by CodeRabbit

  • New Features
    • Added Docker support with a multi-stage build for efficient containerization of the application.
    • Introduced Docker Compose configuration for simplified local setup and management.
    • Implemented automated health checks for the running container.
  • Documentation
    • Updated the README with containerization instructions and usage details.
  • Chores
    • Added a .dockerignore file to optimize Docker builds.
    • Enhanced GitHub Actions workflow to build and publish Docker images automatically.
    • Configured management server to accept connections on all network interfaces.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented May 25, 2025

Walkthrough

This update introduces containerization support for a Java Spring Boot application. It adds a multi-stage Dockerfile, a .dockerignore file, a Docker Compose configuration, health check and entrypoint scripts, and updates the CI workflow to build and push Docker images. The README is updated with container usage instructions. The management server binding address is changed to allow external access.

Changes

File(s) Change Summary
.dockerignore Added to exclude unnecessary files and directories from Docker build context.
Dockerfile Added multi-stage Dockerfile for building and running the Spring Boot application with health check, non-root user, and metadata labels.
compose.yaml Added Docker Compose configuration for building, running, and configuring the containerized application.
scripts/healthcheck.sh, scripts/entrypoint.sh Added shell scripts for container health checking and entrypoint startup logic.
.github/workflows/maven.yml Updated workflow to add a job for building and pushing Docker images to GitHub Container Registry after coverage job passes.
README.md Updated with a new section on container usage and Docker Compose instructions; added emoji to title.
src/main/resources/application.properties Changed management server address binding from localhost to all interfaces (0.0.0.0).

Sequence Diagram(s)

sequenceDiagram
    participant Developer
    participant GitHub Actions
    participant Docker Daemon
    participant GitHub Container Registry

    Developer->>GitHub Actions: Push to master branch
    GitHub Actions->>GitHub Actions: Run coverage job
    GitHub Actions->>GitHub Actions: Run container job (after coverage)
    GitHub Actions->>Docker Daemon: Build Docker image (multi-stage)
    Docker Daemon->>GitHub Actions: Return built image
    GitHub Actions->>GitHub Container Registry: Push Docker image (latest, sha-tagged)
Loading
sequenceDiagram
    participant User
    participant Docker Compose
    participant Container (Spring App)
    participant Healthcheck Script

    User->>Docker Compose: docker compose up
    Docker Compose->>Container (Spring App): Start container
    Container (Spring App)->>Healthcheck Script: Run healthcheck.sh periodically
    Healthcheck Script->>Container (Spring App): HTTP GET /actuator/health
    Container (Spring App)->>Healthcheck Script: Responds to health check
Loading

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b7b6402 and 4c046fb.

📒 Files selected for processing (1)
  • Dockerfile (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Dockerfile
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.


### Docker Compose

This setup uses [Docker Compose](https://docs.docker.com/compose/) to build and run the app
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Line length

@codacy-production
Copy link
Copy Markdown

codacy-production bot commented May 25, 2025

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
+0.00% (target: -1.00%)
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (c5c6e74) 49 49 100.00%
Head commit (4c046fb) 49 (+0) 49 (+0) 100.00% (+0.00%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#195) 0 0 ∅ (not applicable)

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

@codecov
Copy link
Copy Markdown

codecov bot commented May 25, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (c5c6e74) to head (4c046fb).
Report is 3 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##              master      #195   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
  Complexity        20        20           
===========================================
  Files              2         2           
  Lines             49        49           
  Branches           4         4           
===========================================
  Hits              49        49           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (9)
.dockerignore (1)

1-13: Enhancement: ignore common OS and IDE files.
To further slim down the build context, consider adding patterns such as:

.DS_Store
*.iml
*.log

This will prevent macOS or other IDE/editor artifacts from being sent to the Docker daemon.

README.md (2)

34-52: Improve and consolidate Docker Compose commands.
You can streamline the build and startup into a single detached command:

docker compose up -d --build

This reduces the number of steps and runs the container in the background.


30-52: Document Docker prerequisites.
It would be helpful to add a "Prerequisites" section noting that Docker Engine (v20.10+) and Docker Compose (v2+) must be installed before running these commands.

scripts/healthcheck.sh (1)

1-2: Use a portable shebang.
For better cross‐environment compatibility, consider using:

#!/usr/bin/env sh

instead of hardcoding /bin/sh.

compose.yaml (1)

1-16: Optional: specify Compose file version.
Adding a top‐level field like:

version: "3.9"

can clarify compatibility requirements for different Docker Compose releases.

.github/workflows/maven.yml (1)

69-103: Optional: add build cache settings.
To accelerate Docker builds, consider adding cache-from and cache-to arguments. For example:

       with:
         context: .
+        cache-from: type=registry,ref=ghcr.io/${{ github.repository }}:cache
+        cache-to: type=inline
         push: true
         platforms: linux/amd64
         provenance: false
         tags: |
           ghcr.io/${{ github.repository }}:latest
           ghcr.io/${{ github.repository }}:sha-${{ github.sha }}

This can significantly reduce build times on subsequent runs.

Dockerfile (3)

24-26: Reduce image layers by combining package installs and user setup.
Merging APK commands and user creation into a single RUN reduces layers and total image size.

-RUN apk add --no-cache curl
+RUN apk add --no-cache curl \
+    && addgroup -S spring \
+    && adduser -S -G spring spring

Then remove the separate RUN addgroup... block at lines 46–47.

Also applies to: 46-49


28-31: Enhance image metadata with version label.
Adding org.opencontainers.image.version aids in identifying the application version running inside the container.

Add:

LABEL org.opencontainers.image.version="1.0.0"

33-34: Clarify or remove Sonar rule reference.
The inline RSPEC-6504 comment could be removed or expanded to explain why it’s relevant for this Dockerfile.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c5c6e74 and 5971835.

📒 Files selected for processing (6)
  • .dockerignore (1 hunks)
  • .github/workflows/maven.yml (1 hunks)
  • Dockerfile (1 hunks)
  • README.md (2 hunks)
  • compose.yaml (1 hunks)
  • scripts/healthcheck.sh (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (9)
.dockerignore (1)

1-13: .dockerignore entries optimize the build context.
The file effectively excludes project metadata, IDE folders, and build artifacts (e.g., target), which will significantly reduce the Docker build context size.

README.md (1)

30-33: New Container section is clear.
The "## Container" and "### Docker Compose" headings logically group the container usage instructions, making it easy for users to find.

compose.yaml (1)

1-16: Compose service configuration is sound.
The service correctly builds from the Dockerfile, maps ports, sets environment variables, and applies a restart policy.

.github/workflows/maven.yml (1)

69-103: Container job is configured properly.
The new container job runs only on pushes to master, logs in to GHCR, and uses Buildx to tag and push both latest and SHA‐specific images.

Dockerfile (5)

5-5: Verify the availability of the base builder image.
Ensure maven:3.9-eclipse-temurin-21-alpine is published on Docker Hub to avoid build failures due to missing tags.


36-37: Ensure deterministic JAR selection.
Using a wildcard (*.jar) may accidentally match multiple artifacts. Locking the filename prevents ambiguity.

Could you confirm the produced JAR name or adjust to:

COPY --from=builder /app/target/myapp.jar ./app.jar

39-41: Approve copying documentation with read-only permissions.
Locking down README.md and assets with --chmod is a good practice to prevent accidental modification at runtime.


43-44: Verify healthcheck script integrity and permissions.
Confirm scripts/healthcheck.sh has a proper shebang (#!/usr/bin/env sh) and exits non-zero on failure for Docker to mark unhealthy.


51-58: Usage of explicit exec form is correct.
JSON-form EXPOSE, HEALTHCHECK, and ENTRYPOINT ensure proper signal handling and metadata exposure.

@nanotaboada nanotaboada linked an issue May 25, 2025 that may be closed by this pull request
@nanotaboada nanotaboada force-pushed the feature/dockerfile branch from 5971835 to b7b6402 Compare May 25, 2025 16:26
@qlty-cloud-legacy
Copy link
Copy Markdown

Code Climate has analyzed commit 4c046fb and detected 1 issue on this pull request.

Here's the issue category breakdown:

Category Count
Style 1

View more on Code Climate.

@sonarqubecloud
Copy link
Copy Markdown

@nanotaboada nanotaboada merged commit 45a5a0e into master May 25, 2025
19 checks passed
@nanotaboada nanotaboada deleted the feature/dockerfile branch May 25, 2025 16:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Containerize application with Docker

1 participant