How to Deploy Kotlin to Docker Without Writing a Dockerfile

M
Miget Team
Writer
January 12, 2026
4 min read

You can containerize any Kotlin application without writing a Dockerfile using migetpacks. It auto-detects Kotlin projects from build.gradle.kts or .kt files, uses the Gradle wrapper for correct versioning, and produces an optimized Eclipse Temurin JRE image. One command, zero configuration.


Why Is Writing a Dockerfile for Kotlin So Complicated?

A production-ready Kotlin Dockerfile requires:

  • Multi-stage builds to separate Gradle from runtime
  • JDK version selection (17, 21, etc.)
  • Gradle wrapper handling for version consistency
  • Proper caching of Gradle dependencies
  • Choosing between JDK and JRE runtime images
  • JVM memory configuration for containers

The Kotlin/Gradle combination with its DSL files and wrapper scripts makes Docker configuration verbose and error-prone.

How Do I Containerize a Kotlin App Without a Dockerfile?

Open your terminal, navigate to your Kotlin project, and run:

cd ~/projects/my-kotlin-api

docker run --rm \
  -v "$PWD":/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=my-kotlin-api:latest \
  miget/migetpacks:latest

That's it. migetpacks will:

  1. Detect Kotlin from build.gradle.kts, settings.gradle.kts, or .kt files
  2. Read Kotlin version from gradle.properties or build files
  3. Use Gradle wrapper if present
  4. Run gradle build with dependency caching
  5. Output a slim JRE-based production image

How Does migetpacks Detect Kotlin?

migetpacks detects a Kotlin application when any of these conditions are met:

  • settings.gradle.kts exists
  • .kt files exist in src/ directory
  • build.gradle.kts contains the kotlin plugin
  • build.gradle (Groovy DSL) contains a Kotlin plugin reference

Kotlin detection takes priority over Java/Gradle detection.

How Are Versions Detected?

Kotlin Version

SourceExample
.kotlin-version2.1.0
gradle.properties (kotlin.version)kotlin.version=2.1.0
build.gradle.kts (plugin version)kotlin("jvm") version "2.1.0"
DefaultLatest stable

Java Version

SourceExample
system.propertiesjava.runtime.version=21
Default21

What Does the Generated Dockerfile Look Like?

# Build stage
FROM gradle:jdk21 AS builder
WORKDIR /build

ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF-8"

COPY gradlew ./
COPY gradle/ gradle/
COPY build.gradle* settings.gradle* ./

RUN ./gradlew dependencies --no-daemon || true

COPY . .

RUN ./gradlew build -x test --no-daemon \
    && rm -rf src/ gradle/ gradlew* build.gradle* settings.gradle*

# Runtime stage
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=builder --chown=1000:1000 /build /app

You never write or maintain this file - migetpacks handles it automatically.

What JVM Configuration Is Applied?

migetpacks sets production-optimized JVM settings:

VariableValue
JAVA_OPTS-Dfile.encoding=UTF-8 -XX:MaxRAMPercentage=80.0
JAVA_TOOL_OPTIONS-Dfile.encoding=UTF-8

How Do I Build a Ktor App?

Ktor works out of the box:

cd ~/projects/my-ktor-app

docker run --rm \
  -v "$PWD":/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=my-ktor:latest \
  miget/migetpacks:latest

The default run command:

java -jar build/libs/*.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

Stay UpdatedWith Latest Posts

Subscribe to our newsletter and never miss a new blog post, update, or special offer from the Miget team.