Cookbook: Container and Sidecar Deployment¶
Situation: You want to record GC data inside a Docker container with minimal
footprint and pull the .cjfr files out for offline analysis; without the container
needing cjfr inflate capability.
Build the base image with the inflaterless agent¶
FROM eclipse-temurin:21-jre
# ~1.5 MB agent JAR; no inflate, no JMC dependencies
ADD https://github.com/parttimenerd/condensed-data/releases/latest/download/condensed-data-linux-amd64-inflaterless.jar \
/opt/cjfr/cjfr-agent.jar
# Mount point for recordings
RUN mkdir -p /var/rec
VOLUME /var/rec
Start with rotating recording¶
ENV JAVA_TOOL_OPTIONS="-javaagent:/opt/cjfr/cjfr-agent.jar=start,/var/rec/app_\$index.cjfr,rotating,max-files=5,max-size=100m"
Or pass it at docker run time:
docker run \
-v /host/recordings:/var/rec \
-e JAVA_TOOL_OPTIONS="-javaagent:/opt/cjfr/cjfr-agent.jar=start,/var/rec/app_\$index.cjfr,rotating,max-files=5,max-size=100m" \
myapp:latest
Escape $index
docker run -e "…" (shell string): the shell expands $index to empty
before Docker sees it. Use \$index in double-quoted strings.
Dockerfile ENV line: Docker performs its own variable substitution on
ENV values using declared ARG/ENV. Use \$index to pass the literal
placeholder through to the JVM.
Pull recordings and analyse on the host¶
The container only needs the inflaterless JAR. Inflation uses the full JAR on your workstation:
# Copy from container
docker cp mycontainer:/var/rec/. ./recordings/
# Summary; no inflate needed
cjfr summary recordings/app_0.cjfr recordings/app_1.cjfr
# Inflate the interesting window
cjfr inflate --start="2024-05-24 14:00:00" --duration=1h \
recordings/app_0.cjfr recordings/app_1.cjfr \
recordings/incident.jfr
For absolute minimum JAR size (~450 KB)¶
Use the minimal variant; LZ4FRAMED and GZIP, ProGuard-optimised:
The recording format is identical; any full JAR can inflate it.
Kubernetes: volume-mount + init container pattern¶
volumes:
- name: gc-recordings
emptyDir: {}
initContainers:
- name: cjfr-agent
image: curlimages/curl
command:
- sh
- -c
- |
curl -L -o /agent/cjfr-agent.jar \
https://github.com/parttimenerd/condensed-data/releases/latest/download/condensed-data-linux-amd64-inflaterless.jar
volumeMounts:
- name: gc-recordings
mountPath: /agent
containers:
- name: myapp
env:
- name: JAVA_TOOL_OPTIONS
# Kubernetes env values are not shell-expanded; $index reaches the JVM literally
value: "-javaagent:/agent/cjfr-agent.jar=start,/var/rec/app_$index.cjfr,rotating,max-files=10,max-size=100m"
volumeMounts:
- name: gc-recordings
mountPath: /var/rec