A minimal Docker image that packages GraalVM and Apache Maven for building JVM applications and compiling GraalVM native images. No local toolchain setup required.
Building Java applications—especially GraalVM native images—requires a specific combination of JDK, build tools, and native libraries. Developers waste time installing and maintaining these toolchains across machines, CI runners, and team environments. This image solves that problem by providing a ready-to-use, versioned build environment.
- Zero local setup — Pull the image and start building. No JDK, Maven, or GraalVM installation needed.
- Reproducible builds — Pin a tag (e.g.
25-graalce) and every developer and CI job gets the exact same toolchain. - Native image support — Includes all dependencies (
build-essential,libz-dev,zlib1g-dev) required by GraalVM'snative-imagecompiler out of the box. - Multi-arch — Works on both
linux/amd64andlinux/arm64(Apple Silicon, Graviton, etc.). - CI/CD ready — Ideal for GitHub Actions, GitLab CI, Jenkins, or any container-based pipeline.
| Use case | Example |
|---|---|
| Build a Maven project without installing Java | docker run --rm -v "$PWD":/opt/app softinstigate/graalvm-maven clean package |
| Compile a GraalVM native image | docker run --rm -v "$PWD":/opt/app softinstigate/graalvm-maven -Pnative native:compile |
| Run builds in CI with consistent tooling | Use as a container image in your CI workflow |
| Avoid version conflicts across projects | Different tags for different GraalVM/Maven versions |
- GraalVM: 25.1.3-graalce
- Maven: 3.9.16
- Architectures:
linux/amd64,linux/arm64 - Registries:
- Docker Hub:
softinstigate/graalvm-maven - GitHub Container Registry:
ghcr.io/softinstigate/graalvm-maven
- Docker Hub:
- Useful tags:
latest(tracks the most recent release)25.1.3-graalce(current)25-graalce(major version alias)- Historical examples:
24.0.2-graalce,22.0.2-graalce,21.0.2-graalce
Browse tags on:
- Docker Hub: https://hub.docker.com/r/softinstigate/graalvm-maven/tags
- GHCR: https://github.com/SoftInstigate/graalvm-maven-docker/pkgs/container/graalvm-maven
# Docker Hub
docker pull softinstigate/graalvm-maven:25.1.3-graalce
# Or GHCR
docker pull ghcr.io/softinstigate/graalvm-maven:25.1.3-graalceThe image is based on debian:stable-slim and uses SDKMAN! to install GraalVM and Maven. This approach makes version upgrades simple—just change the ARG values in the Dockerfile and rebuild.
An entrypoint script (bin/entrypoint.sh) activates SDKMAN! and delegates to mvn, so the image behaves like a standalone Maven command.
The default ENTRYPOINT is mvn. The working directory is /opt/app.
# Print Maven + Java versions
docker run --rm softinstigate/graalvm-maven --version
# Build a Maven project in the current directory
docker run -it --rm \
-v "$PWD":/opt/app \
-v "$HOME"/.m2:/root/.m2 \
softinstigate/graalvm-maven \
clean packageMounting
~/.m2speeds up builds by reusing your local Maven cache.
Use the GraalVM Native Build Tools (Maven plugin) in your project. Then run:
# Show native plugin help
docker run -it --rm -v "$PWD":/opt/app softinstigate/graalvm-maven native:help
# Typical native build (adjust for your project)
docker run -it --rm \
-v "$PWD":/opt/app \
-v "$HOME"/.m2:/root/.m2 \
softinstigate/graalvm-maven \
-Pnative -DskipTests native:compileTo build and test the image locally:
# Build the image locally (no cache)
./bin/build.sh
# Test the image
docker run -it --rm softinstigate/graalvm-maven --version
# Optional: push :latest manually (CI handles official releases)
./bin/push.sh- GitHub Actions workflow:
.github/workflows/deploy-image.yml - Trigger: push of any git tag
- Output: multi-arch images pushed to Docker Hub and GHCR with:
latestand the exact git tag name
- Maintainer flow to release a new base version:
- Update
ARG JAVA_VERSIONandARG MAVEN_VERSIONinDockerfile - Update the versions in this README
- Commit and push, then create and push a git tag (e.g.
25.1.3-graalce)
- Update
Detailed docs live in the openwiki/ directory:
- Quickstart — pull, build, and native-image usage
- Dockerfile and image structure — layer breakdown, ARG versions, SDKMAN config
- CI/CD and release process — GitHub Actions workflow, secrets, release steps
- Entrypoint script:
bin/entrypoint.sh- Sources
/root/.bashrcto activate SDKMAN! before executing Maven - Executes
mvn "$@"
- Sources
- SDKMAN! config ensures non-interactive installs and stable tool versions:
sdkman_auto_answer=truesdkman_auto_selfupdate=falsesdkman_insecure_ssl=true
-
Maven not found when overriding entrypoint:
- If you replace the entrypoint with a shell, run
source ~/.bashrcbefore usingmvn.
docker run -it --rm --entrypoint bash softinstigate/graalvm-maven source ~/.bashrc && mvn -v
- If you replace the entrypoint with a shell, run
-
Slow builds or dependency downloads:
- Ensure you mount your local Maven cache:
-v "$HOME"/.m2:/root/.m2
- Ensure you mount your local Maven cache:
-
Verify SDKMAN!/Java/Maven inside the container:
docker run -it --rm --entrypoint bash softinstigate/graalvm-maven -lc \ 'source ~/.bashrc; sdk current; java -version; mvn -version'
This repository is licensed under the Apache License 2.0.