Services DevOps DevSecOps Cloud Consulting Infrastructure Automation Managed Services AIOps MLOps DataOps Microservices 🔐 Private AINEW Solutions DevOps Transformation CI/CD Automation Platform Engineering Security Automation Zero Trust Security Compliance Automation Cloud Migration Kubernetes Migration Cloud Cost Optimisation AI-Powered Operations Data Platform Modernisation SRE & Observability Legacy Modernisation Managed IT Services 🔐 Private AI DeploymentNEW Products ✨ ZippyOPS AINEW 🛡️ ArmorPlane 🔒 DevSecOpsAsService 🖥️ LabAsService 🤝 Collab 🧪 SandboxAsService 🎬 DemoAsService Bootcamp 🔄 DevOps Bootcamp ☁️ Cloud Engineering 🔒 DevSecOps 🛡️ Cloud Security ⚙️ Infrastructure Automation 📡 SRE & Observability 🤖 AIOps & MLOps 🧠 AI Engineering 🎓 ZOLS — Free Learning Company About Us Projects Careers Get in Touch

Docker Best Practices for Java Applications

Docker Best Practices for Java Applications

Docker is a powerful tool for running Java applications, but creating an efficient and secure Dockerfile requires more than copying examples from the internet. In this guide, you will learn Docker best practices for Java applications, from optimizing images to securing containers, while also exploring automation strategies supported by ZippyOPS.

Optimized Docker container setup for Java applications following best practices

Introduction to Docker Best Practices for Java

Writing Dockerfiles may seem simple. However, production environments demand security, efficiency, and maintainability. Following Docker’s official guidelines ensures your containers run smoothly. Think of it like writing clean code: knowing the syntax is not enough—you need best practices to create robust containers.

In this article, we demonstrate how to transform a basic Dockerfile for a Java application into a production-ready, secure, and optimized image.

Here is a common starting Dockerfile for a Java application:

FROM eclipse-temurin:17
RUN mkdir /opt/app
ARG JAR_FILE
ADD target/${JAR_FILE} /opt/app/app.jar
CMD ["java", "-jar", "/opt/app/app.jar"]

This Dockerfile performs these actions:

  • FROM: Uses Eclipse Temurin JDK 17 as the base image.
  • RUN: Creates the /opt/app directory.
  • ARG: Sets the JAR_FILE argument to avoid hardcoding the JAR name.
  • ADD: Copies the JAR file into the container.
  • CMD: Starts the Java application.

Later sections will refine this Dockerfile using proven best practices.

Prerequisites for Docker Best Practices for Java

Before starting, ensure you have:

  • Basic knowledge of Linux commands
  • Familiarity with Java and Spring Boot
  • Basic understanding of Docker and containerization

Sample Java Application

We use a simple Spring Boot application with the Spring Web dependency. Run it locally with:

$ mvn spring-boot:run

For building the Docker image, we use the dockerfile-maven-plugin fork:

<plugin>
  <groupId>com.xenoamess.docker</groupId>
  <artifactId>dockerfile-maven-plugin</artifactId>
  <version>1.4.25</version>
  <configuration>
    <repository>mydeveloperplanet/dockerbestpractices</repository>
    <tag>${project.version}</tag>
    <buildArgs>
      <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
    </buildArgs>
  </configuration>
</plugin>

Build the project and Docker image with:

$ mvn clean verify
$ mvn dockerfile:build

Run the container:

$ docker run --name dockerbestpractices mydeveloperplanet/dockerbestpractices:0.0.1-SNAPSHOT

Test the Hello endpoint:

$ curl http://<container-ip>:8080/hello
Hello Docker!

1. Choose the Right Base Image

The base image significantly affects your container size and security. Instead of using eclipse-temurin:17, consider the lighter 17-jre-alpine image. This reduces size from 235MB to 59MB and removes unnecessary JDK tools that could pose security risks.

Always use explicit version tags like 17.0.5_8-jre-alpine@sha256:<hash> for reproducibility. Using a SHA256 hash ensures that a wrong or compromised image will fail to build.

FROM eclipse-temurin:17.0.5_8-jre-alpine@sha256:02c04793fa49ad5cd193c961403223755f9209a67894622e05438598b32f210e

Reducing image size improves distribution speed and security.

2. Avoid Running as Root

By default, containers run as root, creating potential security vulnerabilities. Instead, create a system user and group:

RUN addgroup --system javauser && adduser -S -s /usr/sbin/nologin -G javauser javauser
RUN chown -R javauser:javauser /opt/app
USER javauser

Running as a non-root user minimizes risks and aligns with industry best practices.

3. Use WORKDIR

Instead of repeatedly specifying the full path, use WORKDIR:

WORKDIR /opt/app

This ensures all subsequent commands run inside /opt/app, simplifying your Dockerfile and improving readability.

4. Prefer ENTRYPOINT Over CMD

For executable Java containers, ENTRYPOINT ensures your application always runs correctly:

ENTRYPOINT ["java", "-jar", "app.jar"]

Unlike CMD, it cannot be accidentally overridden at runtime, making container behavior predictable.

5. Use COPY Instead of ADD

COPY is preferred for local files since it only copies files, while ADD has additional features that could lead to unexpected behavior:

COPY target/${JAR_FILE} app.jar

This makes builds more reliable and easier to understand.

6. Use .dockerignore

Prevent unnecessary files from being sent to the Docker daemon. A .dockerignore file can exclude everything except the required JAR:

**/**
!target/*.jar

This speeds up builds and reduces image size, especially in projects with many dependencies like Node modules.

7. Run Docker Daemon Rootless

Running Docker as root is unnecessary and insecure. Docker v20.10 supports rootless mode, or you can use Podman for daemonless, non-root container management.

ZippyOPS Solutions for Containerized Java Applications

At ZippyOPS, we provide consulting, implementation, and managed services for DevOps, DevSecOps, DataOps, Cloud, Automated Ops, AIOps, MLOps, Microservices, Infrastructure, and Security. Leveraging Docker best practices is a core part of our solutions. Explore our offerings:

Our expertise helps organizations build secure, scalable, and efficient containerized environments.

Conclusion for Docker Best Practices for Java

Applying Docker best practices for Java ensures smaller, faster, and more secure containers. Key takeaways include:

  • Choose lightweight, explicit base images
  • Avoid running as root
  • Use WORKDIR, ENTRYPOINT, and COPY
  • Implement a .dockerignore
  • Consider rootless Docker or Podman

For end-to-end container consulting, deployment, and management, contact ZippyOPS at sales@zippyops.com.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top