Detection

migetpacks detects a Clojure application when either of the following files is present in the project root:
  • project.clj (Leiningen)
  • deps.edn (Clojure CLI/tools.deps)

Version Detection

Clojure Version

Clojure version is resolved in the following priority order:
SourceExample
.clojure-version1.11.1
project.clj (org.clojure/clojure dependency)[org.clojure/clojure "1.11.1"]
deps.edn (org.clojure/clojure)org.clojure/clojure {:mvn/version "1.11.1"}
Default1.11.1

Leiningen Version

Leiningen version is detected from:
SourceExample
project.clj (:min-lein-version):min-lein-version "2.11.2"
Default2.11.2

Java Version

The JDK version used for compilation and runtime is read from:
SourceExample
system.propertiesjava.runtime.version=21
Default21

Build Process

migetpacks uses the official clojure:temurin-{java}-lein Docker image which includes Leiningen and the JDK:
# Build stage
FROM clojure:temurin-21-lein AS builder
WORKDIR /build

# Clojure build environment
ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF-8"
ENV LEIN_ROOT=1

# Layer caching: copy project.clj first
COPY project.clj ./

# Download dependencies (cached if project.clj unchanged)
RUN lein deps

# Copy source code
COPY . .

# Build uberjar and cleanup
RUN lein uberjar \
    && rm -rf src/ test/ dev/ resources/public/js/compiled

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

Uberjar Detection

migetpacks detects custom uberjar names from project.clj:
(defproject myapp "1.0.0"
  :uberjar-name "myapp-standalone.jar"
  ...)
If :uberjar-name is specified, migetpacks uses it when configuring the run command.

Run Command

The default run command for Clojure applications:
java -jar target/uberjar/*-standalone.jar
Override with RUN_COMMAND or a Procfile:
web: java -jar target/uberjar/myapp-standalone.jar

JVM Configuration

The following environment variables are set for production:
VariableValue
JAVA_OPTS-Dfile.encoding=UTF-8 -XX:MaxRAMPercentage=80.0 -Dclojure.main.report=stderr
JAVA_TOOL_OPTIONS-Dfile.encoding=UTF-8

Caching

Layer Caching

Dependencies are cached by copying project.clj before the full source:
Cached FilesPurpose
project.cljLeiningen project definition with dependencies
ScenarioDependency Install
First buildRuns
Source code change onlyCached
project.clj changeRuns

BUILD_CACHE_DIR

When BUILD_CACHE_DIR is set, Leiningen and Maven caches persist at:
Cache PathContents
lein cacheLeiningen profiles and plugins
m2 cacheMaven repository (.m2)

DHI Support

Docker Hardened Images are supported for Clojure runtime.
Clojure uses a hybrid approach: the official Clojure build image (which includes Leiningen) for building, and a DHI distroless image for runtime.
StageImage
Buildclojure:temurin-{java}-lein (official)
Runtimedhi.io/eclipse-temurin:{java}

DHI Notes

  • The build image is always the official Clojure image (DHI does not provide Clojure/Leiningen images).
  • Only the runtime stage uses DHI distroless Eclipse Temurin JRE.
  • Java version is read from system.properties (default: 21).
  • Runtime images are distroless (no shell).

Example with DHI

docker run --rm \
  -v /path/to/clojure-app:/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=my-clojure-app:latest \
  -e USE_DHI=true \
  miget/migetpacks:latest

Example

docker run --rm \
  -v /path/to/clojure-app:/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=my-clojure-app:latest \
  miget/migetpacks:latest

With custom JVM options

docker run --rm \
  -v /path/to/clojure-app:/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=my-clojure-app:latest \
  -e JAVA_OPTS="-Xmx1g -Dclojure.main.report=stderr" \
  miget/migetpacks:latest