Docker#
Rig ships the Docker image ghcr.io/brutasse/rig. The release job builds
it for every release, tagged vX.Y.Z and latest. The image is
multi-arch (linux/amd64, linux/arm64).
The image contains:
- the
rigbinary at/usr/local/bin/rig. The resolver kernel jar, the rig.runner jar, and the vendored nREPL jar are embedded in it (go:embed) and pre-materialized into the state dir at their content-sha paths: first use reads the store and writes nothing, so the image works with a read-only root file system for the tool jars. Hot commands append the runner jar to the project classpath, sotestand stage 3 ofcheckneed it. The artifact cache is still a runtime store — warm it in an earlier layer or mount a writable dir; - a Temurin 21 JDK, so the image is a standalone Clojure base.
As an app base#
In a dev container or CI job, rig must work from the first layer. The
tool jars are embedded in the binary and pre-materialized in the image, so
rig fetches nothing from GitHub. It fetches only from your artifact
repositories.
FROM ghcr.io/brutasse/rig:latest
WORKDIR /app
COPY . .
RUN rig check && rig testAs an app entrypoint#
rig launch is the production entrypoint. It runs the built artifact with
Rig's production JVM flag set: G1, exit-on-OOM, and loopback-only JMX on
10101. You can override the flags per module with :rig/launch-opts and
per deployment with the RIG_LAUNCH_OPTS env var. rig launch replaces
its own process with the JVM, so the app is the container's PID 1. It is
offline by definition. rig build bakes the launch plan into the
artifact. Production launch covers the full
workflow: declaring launch opts, the Docker images (slim and workspace
variants), process and lifecycle, and per-deployment overrides.
Multi-stage#
When your app image has its own base, copy the binary out of the image:
FROM eclipse-temurin:21-jdk-jammy
WORKDIR /app
COPY --from=ghcr.io/brutasse/rig:latest /usr/local/bin/rig /usr/local/bin/
COPY . .
RUN rig check && rig testThe binary carries its tool jars, so rig needs no GitHub access at
runtime. It only talks to your artifact repositories. The build consumes
the committed deps.lock: rig check fails when the lockfile is missing
or stale. Locking is workstation work.
Pinned JVMs#
Base the image on the declared JDK. The :rig/jvm "21" pin in the root
deps.edn becomes eclipse-temurin:21-jdk (the jammy variant above). Your
build compiles with the JDK of the image. The state dir holds no
rig-managed JDK for the pin, so Rig falls back to the system java, which
satisfies the pin. There is no RUN rig jvm install step. The JDK of the
image is the build JVM. When the base image carries no matching JDK, the
build downloads the newest matching release on demand (--offline fails
instead).
The runtime side of the same pin is in Production launch: the base of the app container must carry that JDK.
Non-root users#
The state dir is under /root. For a non-root build user, copy it to the
home dir of that user, or point every invocation at a shared dir with
--cache-dir /opt/rig-cache. The dir must be writable.
Offline builds#
The tool jars are pre-materialized in the image, but the artifact cache
is cold. rig check in the Dockerfile fetches from your repositories and
checks the hashes against the lockfile. For hermetic --offline builds,
first warm the state dir in an earlier layer (or cache it across runs). See
CI.