Build and run Ballerina GraalVM native executables locally or in a Docker container. Use when the user wants native image compilation, faster startup, or smaller container images for Ballerina projects.
Help the user build a GraalVM native executable from their Ballerina project. Ask which approach they prefer if not specified: local or container (Docker).
GraalVM native image builds are resource-intensive (high memory + CPU) and time-consuming (minutes to tens of minutes). Always inform the user and get explicit consent before running bal build --graalvm.
When the build is part of a larger setup (e.g., Docker Compose, CI pipeline):
docker compose build will run the GraalVM build inside the container naturally).bal build --graalvm when the user's intent is to set up infrastructure — configure first, build later.If a build is running, provide periodic status updates since it takes significant time.
| Requirement | Local | Container |
|---|---|---|
| Ballerina Swan Lake (latest) | Yes | Yes |
| GraalVM (Java 21 for Update 11+) | Yes | No (built inside container) |
GRAALVM_HOME or JAVA_HOME set | Yes | No |
| Docker (8GB+ memory recommended) | No | Yes |
Install GraalVM locally via SDKMAN!: sdk install java 21.0.2-graalce (latest JDK 21 CE is 21.0.2, not 21.0.6 — verify at graalvm/graalvm-ce-builds releases)
java -version (should show GraalVM).bal build --graalvm./target/bin/<project-name>bal test --graalvmbal build --graalvm --cloud=docker to generate the Dockerfile (multi-stage: GraalVM build -> distroless runtime).docker compose build runs.docker run -d -p <port>:<port> <project-name>:latestghcr.io/ballerina-platform/ballerina returns 403 — use ballerina/ballerina from Docker Hub, or use the GraalVM base with Ballerina zip.ballerina/ballerina is Alpine (musl) — GraalVM CE binaries are glibc-based. Installing GraalVM into this image causes Unable to load jimage library errors. Do NOT mix them.ghcr.io/graalvm/native-image-community:21 (Oracle Linux, glibc) as build stage, install Ballerina via the platform-independent zip from GitHub releases.dist.ballerina.io returns 403. Use GitHub releases instead: https://github.com/ballerina-platform/ballerina-distribution/releases/download/v{version}/ballerina-{version}-swan-lake.zip.zip works on all architectures (JVM-based).ballerina/ballerina runs as non-root — use USER root before installing to /opt or system dirs.docker-compose.yml version key is obsolete — modern Docker Compose ignores it. Omit it.Pass options via CLI or Ballerina.toml:
CLI:
bal build --graalvm --graalvm-build-options="-H:+StaticExecutableWithDynamicLibC"
Ballerina.toml:
[build-options]
graalvmBuildOptions = "--verbose -H:+StaticExecutableWithDynamicLibC"
Add to Ballerina.toml:
[platform.java21]
graalvmCompatible = true