Skip to content

Commit ad4d204

Browse files
committed
Upgrade GraalVM to v25.0.1, default to distroless images with -shell
variants, add multiarch support
1 parent 0724400 commit ad4d204

File tree

6 files changed

+410
-84
lines changed

6 files changed

+410
-84
lines changed

.github/workflows/docker-image.yml

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,37 @@ jobs:
2525
username: ${{ secrets.DOCKER_USER }}
2626
password: ${{ secrets.DOCKER_TOKEN }}
2727

28-
- name: Build and push multi-arch Docker images
28+
- name: Build and push distroless image (default)
2929
uses: docker/build-push-action@v6
3030
with:
31-
platforms: |
32-
linux/amd64,
33-
linux/arm64
31+
context: .
32+
file: ./Dockerfile.distroless
33+
platforms: linux/amd64,linux/arm64
3434
push: true
3535
pull: true
3636
no-cache: false
37+
build-args: |
38+
GRAALVM_VERSION=25.0.1
3739
tags: |
38-
softinstigate/graalvm:latest,
40+
softinstigate/graalvm:latest
3941
softinstigate/graalvm:${{ github.ref_name }}
42+
softinstigate/graalvm:25
43+
softinstigate/graalvm:25.0
44+
softinstigate/graalvm:25.0.0
45+
46+
- name: Build and push shell variant
47+
uses: docker/build-push-action@v6
48+
with:
49+
context: .
50+
file: ./Dockerfile
51+
platforms: linux/amd64,linux/arm64
52+
push: true
53+
pull: true
54+
no-cache: false
55+
build-args: |
56+
GRAALVM_VERSION=25.0.1
57+
tags: |
58+
softinstigate/graalvm:${{ github.ref_name }}-shell
59+
softinstigate/graalvm:25-shell
60+
softinstigate/graalvm:25.0-shell
61+
softinstigate/graalvm:25.0.0-shell

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,7 @@ Temporary Items
5252
!.vscode/extensions.json
5353
*.code-workspace
5454

55-
# End of https://www.toptal.com/developers/gitignore/api/maven,vscode,osx
55+
# End of https://www.toptal.com/developers/gitignore/api/maven,vscode,osx
56+
57+
# Claude Code
58+
.claude

Dockerfile

Lines changed: 83 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,95 @@
1-
FROM debian:stable-slim
1+
# GraalVM Docker Image with Shell
2+
# Multi-arch: linux/amd64, linux/arm64
3+
# Expected size: ~365MB
24

3-
LABEL maintainer="SoftInstigate <info@softinstigate.com>"
5+
FROM debian:stable-slim AS downloader
46

5-
ARG JAVA_VERSION="25-graalce"
7+
ARG GRAALVM_VERSION=25.0.1
8+
ARG GRAALVM_JAVA_VERSION=25
9+
ARG TARGETARCH
610

7-
ENV SDKMAN_DIR=/root/.sdkman
11+
WORKDIR /tmp
812

9-
COPY bin/entrypoint.sh /root
13+
# Map Docker's TARGETARCH to GraalVM's architecture naming
14+
RUN case "${TARGETARCH}" in \
15+
amd64) echo "linux-x64" > /tmp/graalvm_arch ;; \
16+
arm64) echo "linux-aarch64" > /tmp/graalvm_arch ;; \
17+
*) echo "Unsupported architecture: ${TARGETARCH}" && exit 1 ;; \
18+
esac
1019

1120
RUN apt-get update \
12-
&& apt-get install -y --no-install-recommends ca-certificates curl locales unzip zip \
21+
&& apt-get install -y --no-install-recommends \
22+
ca-certificates \
23+
curl \
24+
&& rm -rf /var/lib/apt/lists/*
25+
26+
# Download and extract GraalVM directly
27+
RUN GRAALVM_ARCH=$(cat /tmp/graalvm_arch) \
28+
&& curl -fsSL "https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-${GRAALVM_VERSION}/graalvm-community-jdk-${GRAALVM_VERSION}_${GRAALVM_ARCH}_bin.tar.gz" \
29+
-o graalvm.tar.gz \
30+
&& mkdir -p /opt/graalvm \
31+
&& tar -xzf graalvm.tar.gz -C /opt/graalvm --strip-components=1 \
32+
&& rm graalvm.tar.gz
33+
34+
# Remove unnecessary components to save space
35+
# Remove GUI libraries since RESTHeart is a server application
36+
RUN cd /opt/graalvm \
37+
&& rm -rf \
38+
lib/src.zip \
39+
lib/visualvm \
40+
lib/static \
41+
lib/svm \
42+
jmods \
43+
man \
44+
demo \
45+
sample \
46+
include \
47+
&& cd lib \
48+
&& rm -rf \
49+
libnative-image*.so \
50+
libawt*.so \
51+
libjavafx*.so \
52+
libprism*.so \
53+
libglass*.so \
54+
libfx*.so \
55+
libjfx*.so \
56+
libgstreamer*.so \
57+
libsplashscreen.so \
58+
libjavajpeg.so \
59+
libfontmanager.so \
60+
liblcms.so \
61+
libmlib_image.so \
62+
ct.sym \
63+
2>/dev/null || true
64+
65+
# Final stage
66+
FROM debian:stable-slim
67+
68+
LABEL maintainer="SoftInstigate <info@softinstigate.com>"
69+
LABEL description="GraalVM image with shell for debugging"
70+
LABEL org.opencontainers.image.source="https://github.com/SoftInstigate/graalvm-docker"
71+
72+
# Copy only the JVM from builder
73+
COPY --from=downloader /opt/graalvm /opt/graalvm
74+
75+
# Install minimal runtime dependencies
76+
RUN apt-get update \
77+
&& apt-get install -y --no-install-recommends \
78+
ca-certificates \
79+
locales \
1380
&& echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen \
1481
&& locale-gen en_US.UTF-8 \
1582
&& apt-get -y autoremove \
16-
&& rm -rf /var/lib/apt/lists/* \
17-
&& curl 'https://get.sdkman.io' | bash \
18-
&& echo "sdkman_auto_answer=true" > "${SDKMAN_DIR}/etc/config" \
19-
&& echo "sdkman_auto_selfupdate=false" >> "${SDKMAN_DIR}/etc/config" \
20-
&& echo "sdkman_insecure_ssl=true" >> "${SDKMAN_DIR}/etc/config" \
21-
&& chmod +x "${SDKMAN_DIR}/bin/sdkman-init.sh" \
22-
&& bash -c "source ${SDKMAN_DIR}/bin/sdkman-init.sh \
23-
&& sdk version \
24-
&& sdk install java ${JAVA_VERSION} \
25-
&& rm -rf ${SDKMAN_DIR}/archives/* \
26-
&& rm -rf ${SDKMAN_DIR}/tmp/*"
83+
&& rm -rf /var/lib/apt/lists/*
2784

28-
WORKDIR /opt/app
85+
ENV JAVA_HOME=/opt/graalvm
86+
ENV PATH="${JAVA_HOME}/bin:${PATH}"
87+
ENV LANG=en_US.UTF-8
88+
ENV LANGUAGE=en_US:en
89+
ENV LC_ALL=en_US.UTF-8
90+
ENV JAVA_OPTS="-Djava.awt.headless=true"
2991

30-
SHELL ["/bin/bash", "-i", "-c"]
92+
WORKDIR /opt/app
3193

32-
ENTRYPOINT [ "/root/entrypoint.sh" ]
94+
# Use shell entrypoint for flexibility
95+
CMD ["/bin/sh"]

Dockerfile.distroless

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Distroless GraalVM Docker Image
2+
# No shell, no package manager, no login capability
3+
# Multi-arch: linux/amd64, linux/arm64
4+
# Maximum security - only runtime dependencies
5+
# Expected size: ~285MB
6+
7+
FROM debian:stable-slim AS downloader
8+
9+
ARG GRAALVM_VERSION=25.0.1
10+
ARG GRAALVM_JAVA_VERSION=25
11+
ARG TARGETARCH
12+
13+
WORKDIR /tmp
14+
15+
# Map Docker's TARGETARCH to GraalVM's architecture naming
16+
RUN case "${TARGETARCH}" in \
17+
amd64) echo "linux-x64" > /tmp/graalvm_arch ;; \
18+
arm64) echo "linux-aarch64" > /tmp/graalvm_arch ;; \
19+
*) echo "Unsupported architecture: ${TARGETARCH}" && exit 1 ;; \
20+
esac
21+
22+
RUN apt-get update \
23+
&& apt-get install -y --no-install-recommends \
24+
ca-certificates \
25+
curl \
26+
&& rm -rf /var/lib/apt/lists/*
27+
28+
# Download and extract GraalVM directly
29+
RUN GRAALVM_ARCH=$(cat /tmp/graalvm_arch) \
30+
&& curl -fsSL "https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-${GRAALVM_VERSION}/graalvm-community-jdk-${GRAALVM_VERSION}_${GRAALVM_ARCH}_bin.tar.gz" \
31+
-o graalvm.tar.gz \
32+
&& mkdir -p /opt/graalvm \
33+
&& tar -xzf graalvm.tar.gz -C /opt/graalvm --strip-components=1 \
34+
&& rm graalvm.tar.gz
35+
36+
# Aggressive cleanup - remove everything not needed for runtime
37+
# Remove GUI libraries since RESTHeart is a server application
38+
RUN cd /opt/graalvm \
39+
&& rm -rf \
40+
lib/src.zip \
41+
lib/visualvm \
42+
lib/static \
43+
lib/svm \
44+
jmods \
45+
man \
46+
demo \
47+
sample \
48+
include \
49+
&& cd lib \
50+
&& rm -rf \
51+
libawt*.so \
52+
libjavafx*.so \
53+
libprism*.so \
54+
libglass*.so \
55+
libfx*.so \
56+
libjfx*.so \
57+
libgstreamer*.so \
58+
libsplashscreen.so \
59+
libjavajpeg.so \
60+
libfontmanager.so \
61+
liblcms.so \
62+
libmlib_image.so \
63+
libnative-image*.so \
64+
ct.sym \
65+
2>/dev/null || true \
66+
&& cd /opt/graalvm \
67+
&& find . -name "*.diz" -delete \
68+
&& find . -name "*.debuginfo" -delete 2>/dev/null || true
69+
70+
# Build minimal runtime deps layer
71+
FROM debian:stable-slim AS runtime-deps
72+
73+
ARG TARGETARCH
74+
75+
RUN apt-get update \
76+
&& apt-get install -y --no-install-recommends \
77+
zlib1g \
78+
&& rm -rf /var/lib/apt/lists/*
79+
80+
# Copy libs to a common location based on architecture
81+
RUN mkdir -p /staging/lib && \
82+
case "${TARGETARCH}" in \
83+
amd64) cp -P /lib/x86_64-linux-gnu/libz.so* /staging/lib/ || \
84+
cp -P /usr/lib/x86_64-linux-gnu/libz.so* /staging/lib/ ;; \
85+
arm64) cp -P /lib/aarch64-linux-gnu/libz.so* /staging/lib/ || \
86+
cp -P /usr/lib/aarch64-linux-gnu/libz.so* /staging/lib/ ;; \
87+
esac
88+
89+
# Use Google's distroless base - no shell, no package manager
90+
FROM gcr.io/distroless/base-debian12:nonroot
91+
92+
LABEL maintainer="SoftInstigate <info@softinstigate.com>"
93+
LABEL description="Distroless GraalVM image with no shell - maximum security"
94+
LABEL org.opencontainers.image.source="https://github.com/SoftInstigate/graalvm-docker"
95+
96+
# Copy required runtime libraries
97+
COPY --from=runtime-deps /staging/lib/* /lib/
98+
99+
# Copy only the JVM from builder
100+
COPY --from=downloader /opt/graalvm /opt/graalvm
101+
102+
# Copy CA certificates for HTTPS
103+
COPY --from=downloader /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
104+
105+
ENV JAVA_HOME=/opt/graalvm
106+
ENV PATH=/opt/graalvm/bin
107+
ENV LANG=en_US.UTF-8
108+
ENV JAVA_OPTS="-Djava.awt.headless=true"
109+
110+
WORKDIR /opt/app
111+
112+
# No shell available - direct Java execution only
113+
ENTRYPOINT ["/opt/graalvm/bin/java"]

0 commit comments

Comments
 (0)