How to Deploy Java to Docker Without Writing a Dockerfile
You can containerize any Java application without writing a Dockerfile using migetpacks. It auto-detects Maven or Gradle, reads your Java version from pom.xml or system.properties, builds an optimized JAR, and produces a production-ready image with Eclipse Temurin. One command, zero configuration.
Why Is Writing a Dockerfile for Java So Complicated?
A production-ready Java Dockerfile requires:
- Multi-stage builds to separate Maven/Gradle from runtime
- Choosing between JDK versions (8, 11, 17, 21)
- Proper layer ordering for dependency caching
- JVM memory configuration (
-XX:MaxRAMPercentage) - Choosing between JRE and JDK runtime images
- Handling Gradle wrapper vs system Gradle
- Cleaning up source code after compilation
Get any of this wrong and you end up with 800MB images or JVMs that crash with OOM errors.
How Do I Containerize a Java App Without a Dockerfile?
Open your terminal, navigate to your Java project, and run:
cd ~/projects/my-spring-app
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-spring-app:latest \
miget/migetpacks:latest
That's it. migetpacks will:
- Detect Java from
pom.xmlorbuild.gradle - Detect Maven or Gradle automatically
- Read Java version from project files
- Use Gradle wrapper if present
- Build with proper caching
- Output a slim JRE-based production image
How Does migetpacks Detect My Java Version?
Version is resolved in this order:
| Source | Example |
|---|---|
.java-version | 21 |
system.properties | java.runtime.version=21 |
pom.xml (<java.version> or <maven.compiler.release>) | <java.version>21</java.version> |
| Default | 21 |
Legacy version formats are normalized (e.g., 1.8 becomes 8).
What Build Tools Does migetpacks Support?
migetpacks automatically detects your build tool:
| File Present | Build Tool | Build Image |
|---|---|---|
pom.xml | Maven | maven:3-eclipse-temurin-{version} |
build.gradle or build.gradle.kts | Gradle | gradle:jdk{version} |
If gradlew is present, migetpacks uses the Gradle Wrapper for version compatibility.
What Does the Generated Dockerfile Look Like?
For Maven projects:
# Build stage
FROM maven:3-eclipse-temurin-21 AS builder
WORKDIR /build
COPY pom.xml ./
RUN mvn dependency:go-offline -B || true
COPY . .
RUN mvn package -DskipTests -B \
&& rm -rf src/ .mvn/ mvnw* pom.xml
# Runtime stage
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=builder --chown=1000:1000 /build /app
For Gradle projects:
FROM gradle:jdk21 AS builder
WORKDIR /build
COPY build.gradle* settings.gradle* ./
RUN gradle dependencies --no-daemon || true
COPY . .
RUN gradle build -x test --no-daemon \
&& rm -rf src/ gradle/ gradlew* build.gradle*
You never write or maintain these files - migetpacks handles it automatically.
What JVM Configuration Is Applied?
migetpacks sets production-optimized JVM settings:
| Variable | Value |
|---|---|
JAVA_OPTS | -Dfile.encoding=UTF-8 -XX:MaxRAMPercentage=80.0 |
JAVA_TOOL_OPTIONS | -Dfile.encoding=UTF-8 |
MaxRAMPercentage=80.0 ensures the JVM uses container memory limits correctly.
How Do I Build a Spring Boot App?
Spring Boot works out of the box. Just navigate to your project:
cd ~/projects/my-spring-boot-app
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-spring:latest \
miget/migetpacks:latest
The default run command becomes:
java -jar target/*.jar
How Do I Build Secure Distroless Images?
Enable Docker Hardened Images for minimal containers:
docker run --rm \
-v "$PWD":/workspace/source \
-v /var/run/docker.sock:/var/run/docker.sock \
-e OUTPUT_IMAGE=my-app:latest \
-e USE_DHI=true \
miget/migetpacks:latest
DHI uses distroless Eclipse Temurin images - no shell, no package manager, minimal attack surface.
Next Steps
- Full Java documentation - version detection, caching, JVM tuning
- Deploy on Miget - unlimited apps, one price
- Star on GitHub - migetpacks is open source
- Related guides: Kotlin, Scala, Clojure