Add docker-images: one Spring Boot 4 service packaged nine ways
Companion code for "Dockerizing Spring Boot 4: Layered Jars, Buildpacks, Distroless and Image Size Benchmarks". Fat jar on JDK and JRE, layered jar on Debian, Alpine and distroless, jlink, the JDK 25 AOT cache, Paketo buildpacks and Jib, each measured for size on disk and pushed, rebuild delta, startup, user and shell. Also PID 1 and signal handling, the jdeps module gap, AOT cache mismatches and buildpacks memory calculation. Transcripts in docs/output/, regenerated by scripts/run-all.sh. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01C3TETMrqVUWeFkNtz3Jbo3
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build every image variant from target/app.jar. Tag suffix is $1 (default: none).
|
||||
# ./scripts/build-images.sh -> sbd/docker-images:<variant>
|
||||
# ./scripts/build-images.sh -r2 -> sbd/docker-images:<variant>-r2
|
||||
# Buildpacks and Jib need extra flags in a network-restricted environment; set
|
||||
# BUILDPACKS_ARGS / JIB_ARGS (scripts/run-all.sh shows the sandbox values).
|
||||
set -euo pipefail
|
||||
source "$(dirname "$0")/env.sh"
|
||||
SUFFIX="${1:-}"
|
||||
cd "$MODULE_DIR"
|
||||
for v in "${VARIANTS[@]}"; do
|
||||
case "$v" in
|
||||
buildpacks)
|
||||
mvn -q -o -DskipTests ${BUILDPACKS_ARGS:-} -Dbuildpacks.image="sbd/docker-images:buildpacks$SUFFIX" \
|
||||
spring-boot:build-image > /dev/null ;;
|
||||
jib)
|
||||
mvn -q -o -DskipTests ${JIB_ARGS:-} -Djib.to.image="sbd/docker-images:jib$SUFFIX" jib:dockerBuild > /dev/null ;;
|
||||
*)
|
||||
docker build -q -f "docker/Dockerfile.$v" -t "sbd/docker-images:$v$SUFFIX" . > /dev/null ;;
|
||||
esac
|
||||
echo "built sbd/docker-images:$v$SUFFIX"
|
||||
done
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
# The AOT cache trained in image aot-cache, run by its own JVM and by a different JVM build.
|
||||
# -> docs/output/aot-cache-mismatch.txt
|
||||
set -uo pipefail
|
||||
source "$(dirname "$0")/env.sh"
|
||||
cd "$MODULE_DIR"
|
||||
docker build -q -f docker/Dockerfile.aot-cache-mismatch -t sbd/docker-images:aot-cache-mismatch . > /dev/null
|
||||
{
|
||||
for t in aot-cache aot-cache-mismatch; do
|
||||
name="aot-$$"; docker rm -f "$name" > /dev/null 2>&1
|
||||
docker run -d --name "$name" "sbd/docker-images:$t" > /dev/null
|
||||
for _ in $(seq 1 200); do docker logs "$name" 2>&1 | grep -q 'Started ImagesApplication' && break; sleep 0.1; done
|
||||
echo "## sbd/docker-images:$t"
|
||||
docker logs "$name" 2>&1 | grep -E '\[aot\]|Starting ImagesApplication|Started ImagesApplication' \
|
||||
| sed -E 's/^[0-9T:.-]+Z +INFO 1 --- \[docker-images\] \[ +main\] com.ankurm.images.ImagesApplication +: //' | cut -c1-120
|
||||
echo "exit status while running: $(docker inspect -f '{{.State.Status}}' "$name")"
|
||||
docker rm -f "$name" > /dev/null
|
||||
echo
|
||||
done
|
||||
} | tee "$OUT/aot-cache-mismatch.txt"
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
# Where the buildpacks image's size goes, and why its JRE is bigger than Temurin's.
|
||||
# -> docs/output/buildpacks-layers.txt
|
||||
set -uo pipefail
|
||||
source "$(dirname "$0")/env.sh"
|
||||
W=$(mktemp -d)
|
||||
{
|
||||
echo "# docker history sbd/docker-images:buildpacks"
|
||||
docker history --no-trunc --format '{{.Size}}\t{{.CreatedBy}}' sbd/docker-images:buildpacks | cut -c1-110
|
||||
echo
|
||||
cid=$(docker create sbd/docker-images:buildpacks); docker export "$cid" | tar -x -C "$W" layers/paketo-buildpacks_bellsoft-liberica/jre; docker rm "$cid" > /dev/null
|
||||
cid=$(docker create eclipse-temurin:25-jre); docker export "$cid" | tar -x -C "$W" opt/java/openjdk; docker rm "$cid" > /dev/null
|
||||
L="$W/layers/paketo-buildpacks_bellsoft-liberica/jre"; T="$W/opt/java/openjdk"
|
||||
echo "# The two JREs, in MB (du -sm)"
|
||||
printf '%-44s %6s\n' "BellSoft Liberica JRE (buildpacks) total" "$(du -sm "$L" | cut -f1)"
|
||||
printf '%-44s %6s\n' " lib/server" "$(du -sm "$L/lib/server" | cut -f1)"
|
||||
printf '%-44s %6s\n' " lib/client" "$(du -sm "$L/lib/client" | cut -f1)"
|
||||
printf '%-44s %6s\n' "Temurin JRE (eclipse-temurin:25-jre) total" "$(du -sm "$T" | cut -f1)"
|
||||
printf '%-44s %6s\n' " lib/server" "$(du -sm "$T/lib/server" | cut -f1)"
|
||||
printf '%-44s %6s\n' " lib/client" "$( [ -d "$T/lib/client" ] && du -sm "$T/lib/client" | cut -f1 || echo absent)"
|
||||
} | tee "$OUT/buildpacks-layers.txt"
|
||||
rm -rf "$W"
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
# The buildpacks image under common container memory limits. The Paketo memory calculator runs
|
||||
# before the JVM and refuses to launch if its fixed regions do not fit.
|
||||
# -> docs/output/buildpacks-memory.txt
|
||||
set -uo pipefail
|
||||
source "$(dirname "$0")/env.sh"
|
||||
run() { # label, docker args...
|
||||
local label="$1"; shift
|
||||
local name="bpm-$$"; docker rm -f "$name" > /dev/null 2>&1
|
||||
docker run -d --name "$name" "$@" sbd/docker-images:buildpacks > /dev/null
|
||||
for _ in $(seq 1 100); do
|
||||
docker logs "$name" 2>&1 | grep -qE 'Started ImagesApplication|failed to launch' && break; sleep 0.1
|
||||
done
|
||||
echo "## $label"
|
||||
docker logs "$name" 2>&1 | grep -E 'Calculated JVM Memory|unable to calculate|fixed memory regions|failed to launch|Started ImagesApplication' \
|
||||
| sed -E 's/^[0-9T:.-]+Z +INFO 1 --- \[docker-images\] \[ +main\] com.ankurm.images.ImagesApplication +: //; s/\x1b\[[0-9;]*m//g' | cut -c1-230
|
||||
echo "state: $(docker inspect -f '{{.State.Status}} (exit {{.State.ExitCode}})' "$name")"
|
||||
echo
|
||||
docker rm -f "$name" > /dev/null
|
||||
}
|
||||
{
|
||||
run "docker run -m 512m" -m 512m
|
||||
run "docker run -m 768m" -m 768m
|
||||
run "docker run -m 512m -e BPL_JVM_THREAD_COUNT=50" -m 512m -e BPL_JVM_THREAD_COUNT=50
|
||||
} | tee "$OUT/buildpacks-memory.txt"
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
# The jlink image built from jdeps' module list alone runs fine - and exports fewer metrics.
|
||||
# Diffs /actuator/prometheus metric names against the full-JRE image. -> docs/output/jlink-metrics.txt
|
||||
set -uo pipefail
|
||||
source "$(dirname "$0")/env.sh"
|
||||
names() {
|
||||
local name="jl-$$-$2"
|
||||
docker rm -f "$name" > /dev/null 2>&1
|
||||
docker run -d --name "$name" -p "$2:8080" "$1" > /dev/null
|
||||
for _ in $(seq 1 300); do curl -s -o /dev/null "localhost:$2/actuator/health" && break; sleep 0.1; done
|
||||
curl -s -o /dev/null "localhost:$2/api/items"
|
||||
curl -s "localhost:$2/actuator/prometheus" | grep -v '^#' | sed 's/[{ ].*//' | sort -u
|
||||
docker logs "$name" 2>&1 | grep -E ' WARN ' | sed 's/^.* WARN [0-9]* --- \[[^]]*\] \[ *[^]]*\] //' >&2
|
||||
docker rm -f "$name" > /dev/null
|
||||
}
|
||||
{
|
||||
echo "# jlink modules chosen by jdeps alone:"
|
||||
docker run --rm --entrypoint /opt/jre/bin/java sbd/docker-images:jlink-jdeps-only --list-modules | sed 's/@.*//' | tr '\n' ' '; echo
|
||||
echo
|
||||
echo "# WARN lines at startup of the jdeps-only image:"
|
||||
names sbd/docker-images:jlink-jdeps-only 18101 2>&1 >/tmp/jl-a.txt | sed 's/^/ /'
|
||||
names sbd/docker-images:layered-distroless 18102 2>/dev/null > /tmp/jl-b.txt
|
||||
names sbd/docker-images:jlink-distroless 18103 2>/dev/null > /tmp/jl-c.txt
|
||||
echo
|
||||
echo "# Metric names: full JRE $(wc -l < /tmp/jl-b.txt), jdeps-only $(wc -l < /tmp/jl-a.txt), jdeps + jdk.management $(wc -l < /tmp/jl-c.txt)"
|
||||
echo "# Present with the full JRE, missing from the jdeps-only image:"
|
||||
comm -23 /tmp/jl-b.txt /tmp/jl-a.txt | sed 's/^/ /'
|
||||
echo "# Missing from jdeps + jdk.management: $(comm -23 /tmp/jl-b.txt /tmp/jl-c.txt | wc -l)"
|
||||
comm -23 /tmp/jl-b.txt /tmp/jl-c.txt | sed 's/^/ /'
|
||||
echo "# (jvm_gc_concurrent_phase_time_* is registered lazily, after the first G1 concurrent cycle -"
|
||||
echo "# whether it appears within a few seconds of startup varies run to run, in either image.)"
|
||||
} | tee "$OUT/jlink-metrics.txt"
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
# Who is PID 1, does SIGTERM reach the JVM, and how long does `docker stop` take?
|
||||
# -> docs/output/pid1-and-signals.txt
|
||||
set -uo pipefail
|
||||
source "$(dirname "$0")/env.sh"
|
||||
probe() {
|
||||
local tag="$1" name="sig-$$"
|
||||
docker rm -f "$name" > /dev/null 2>&1
|
||||
docker run -d --name "$name" "sbd/docker-images:$tag" > /dev/null
|
||||
for _ in $(seq 1 200); do docker logs "$name" 2>&1 | grep -q 'Started ImagesApplication' && break; sleep 0.1; done
|
||||
local pid1
|
||||
# NUL-separated argv; translate in the pipe (a shell variable cannot hold NUL bytes)
|
||||
pid1=$(docker exec "$name" cat /proc/1/cmdline 2>/dev/null | tr '\0' ' ')
|
||||
case "$pid1" in ""|*"exec failed"*) pid1="(image has no cat; ENTRYPOINT is exec form)" ;; esac
|
||||
local t0 t1; t0=$(date +%s%N); docker stop "$name" > /dev/null; t1=$(date +%s%N)
|
||||
local code; code=$(docker inspect -f '{{.State.ExitCode}}' "$name")
|
||||
local graceful; graceful=$(docker logs "$name" 2>&1 | grep -c 'Commencing graceful shutdown' || true)
|
||||
printf '%-22s PID 1: %-58s docker stop: %5d ms exit code: %-4s graceful-shutdown log lines: %s\n' \
|
||||
"$tag" "${pid1:0:58}" "$(( (t1 - t0) / 1000000 ))" "$code" "$graceful"
|
||||
docker rm -f "$name" > /dev/null
|
||||
}
|
||||
{
|
||||
echo "# docker stop sends SIGTERM to PID 1, waits 10 s, then SIGKILL. Exit code 143 = the JVM handled"
|
||||
echo "# SIGTERM (128+15). 137 = it was killed (128+9)."
|
||||
echo
|
||||
for t in layered-jre shell-form shell-form-alpine shell-form-wrapper layered-distroless; do probe "$t"; done
|
||||
echo
|
||||
echo "# What /bin/sh is in each base image:"
|
||||
echo "eclipse-temurin:25-jre -> $(docker run --rm --entrypoint readlink eclipse-temurin:25-jre -f /bin/sh)"
|
||||
echo "eclipse-temurin:25-jre-alpine -> $(docker run --rm --entrypoint readlink eclipse-temurin:25-jre-alpine -f /bin/sh)"
|
||||
} | tee "$OUT/pid1-and-signals.txt"
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
MODULE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
OUT="$MODULE_DIR/docs/output"
|
||||
REGISTRY="${REGISTRY:-localhost:5000}" # any registry you can push to; see docs/02-measuring-size.md
|
||||
REPO="$REGISTRY/sbd-docker-images"
|
||||
mkdir -p "$OUT"
|
||||
# Every variant the article measures, in the order the table lists them.
|
||||
VARIANTS=(fatjar-jdk fatjar-jre layered-jre layered-alpine layered-distroless jlink-distroless aot-cache buildpacks jib)
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
# For -Pno-maven-central only: download the one Maven Central artifact the Spring Boot buildpack
|
||||
# fetches during a build, and check it against the sha256 the buildpack expects (which is also
|
||||
# the name of the mapping file next to it).
|
||||
set -euo pipefail
|
||||
D="$(cd "$(dirname "$0")/.." && pwd)/bindings/dependency-mapping"
|
||||
curl -sfL -o "$D/spring-cloud-bindings-2.0.4.jar" \
|
||||
https://repo1.maven.org/maven2/org/springframework/cloud/spring-cloud-bindings/2.0.4/spring-cloud-bindings-2.0.4.jar
|
||||
echo "32e47c2139d6379836910f0d1cc253a019ac282f3aeea12237069f00046279ad $D/spring-cloud-bindings-2.0.4.jar" | sha256sum -c
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
# "A developer changed one line": bump BuildInfo.REVISION, rebuild every variant, and count the
|
||||
# layers - and bytes - that differ from the previous build. That is what CI pushes and what every
|
||||
# node pulls on the next rollout. -> docs/output/rebuild-delta.txt
|
||||
# Run scripts/measure.sh first: it pushes the revision-1 images this compares against.
|
||||
set -euo pipefail
|
||||
source "$(dirname "$0")/env.sh"
|
||||
cd "$MODULE_DIR"
|
||||
FILE=src/main/java/com/ankurm/images/BuildInfo.java
|
||||
trap 'sed -i "s/REVISION = \"2\"/REVISION = \"1\"/" "$FILE"; mvn -q -o -DskipTests package' EXIT
|
||||
sed -i 's/REVISION = "1"/REVISION = "2"/' "$FILE"
|
||||
mvn -q -o -DskipTests package
|
||||
./scripts/build-images.sh -r2 > /dev/null
|
||||
|
||||
layers() { crane manifest "$1" | python3 -c 'import json,sys
|
||||
for l in json.load(sys.stdin)["layers"]: print(l["digest"], l["size"])'; }
|
||||
|
||||
{
|
||||
echo "# One-line code change (BuildInfo.REVISION 1 -> 2), every variant rebuilt."
|
||||
echo "# 'new layers' = layer digests in revision 2 that revision 1 did not have: what a push uploads"
|
||||
echo "# and what a node that already runs revision 1 downloads."
|
||||
echo
|
||||
printf '%-20s %12s %14s %14s %s\n' variant "new layers" "bytes to push" "image total" "share"
|
||||
for v in "${VARIANTS[@]}"; do
|
||||
docker tag "sbd/docker-images:$v-r2" "$REPO:$v-r2" && docker push -q "$REPO:$v-r2" > /dev/null
|
||||
layers "$REPO:$v" | sort > /tmp/r1; layers "$REPO:$v-r2" | sort > /tmp/r2
|
||||
new=$(comm -13 <(cut -d' ' -f1 /tmp/r1) <(cut -d' ' -f1 /tmp/r2))
|
||||
count=$(echo "$new" | grep -c . || true)
|
||||
bytes=0; for d in $new; do bytes=$(( bytes + $(grep "^$d " /tmp/r2 | cut -d' ' -f2) )); done
|
||||
total=$(awk '{s+=$2} END {print s}' /tmp/r2)
|
||||
printf '%-20s %6s of %-3s %13sK %13sM %5.1f%%\n' "$v" "$count" "$(wc -l < /tmp/r2)" "$(( bytes / 1000 ))" "$(( total / 1000000 ))" \
|
||||
"$(python3 -c "print(100*$bytes/$total)")"
|
||||
done
|
||||
} | tee "$OUT/rebuild-delta.txt"
|
||||
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env bash
|
||||
# Measure every variant: size on disk, size over the wire, layers, user, shell, packages,
|
||||
# startup to readiness, and memory at idle. -> docs/output/image-matrix.txt
|
||||
# Needs a registry at $REGISTRY (crane registry serve --address localhost:5000 is enough).
|
||||
set -uo pipefail
|
||||
source "$(dirname "$0")/env.sh"
|
||||
RUNS="${RUNS:-3}"
|
||||
PORT=18090
|
||||
|
||||
compressed() { # image in registry -> "bytes layers"
|
||||
crane manifest "$1" | python3 -c 'import json,sys
|
||||
m=json.load(sys.stdin); L=m["layers"]
|
||||
print(sum(l["size"] for l in L)+m["config"]["size"], len(L))'
|
||||
}
|
||||
|
||||
packages() { # count OS packages from the image filesystem, without running anything in it
|
||||
local cid; cid=$(docker create "$1" /x 2>/dev/null)
|
||||
docker export "$cid" > /tmp/img-fs.tar; docker rm "$cid" > /dev/null
|
||||
local n=""
|
||||
if tar -tf /tmp/img-fs.tar var/lib/dpkg/status > /dev/null 2>&1; then
|
||||
n=$(tar -xOf /tmp/img-fs.tar var/lib/dpkg/status | grep -c '^Package:')
|
||||
n="$n (dpkg)"
|
||||
elif [ "$(tar -tf /tmp/img-fs.tar | grep -c '^var/lib/dpkg/status.d/.')" -gt 0 ]; then
|
||||
# distroless and Paketo "tiny" keep one status file per package (plus .md5sums) in status.d/
|
||||
n=$(tar -tf /tmp/img-fs.tar | grep -E '^var/lib/dpkg/status.d/[^/]+$' | grep -vc '\.md5sums$')
|
||||
n="$n (status.d)"
|
||||
elif tar -tf /tmp/img-fs.tar lib/apk/db/installed > /dev/null 2>&1; then
|
||||
n=$(tar -xOf /tmp/img-fs.tar lib/apk/db/installed | grep -c '^P:')
|
||||
n="$n (apk)"
|
||||
else n="?"; fi
|
||||
rm -f /tmp/img-fs.tar; echo "$n"
|
||||
}
|
||||
|
||||
startup() { # image -> "ms_to_ready startedIn rss"
|
||||
local name="measure-$$" t0 t1
|
||||
docker rm -f "$name" > /dev/null 2>&1
|
||||
t0=$(date +%s%N)
|
||||
docker run -d --name "$name" -p "$PORT:8080" "$1" > /dev/null
|
||||
for _ in $(seq 1 600); do
|
||||
if [ "$(curl -s -o /dev/null -w '%{http_code}' localhost:$PORT/actuator/health/readiness)" = 200 ]; then break; fi
|
||||
sleep 0.05
|
||||
done
|
||||
t1=$(date +%s%N)
|
||||
for _ in 1 2 3 4 5; do curl -s -o /dev/null localhost:$PORT/api/items; done
|
||||
sleep 2
|
||||
local rss started
|
||||
rss=$(docker stats --no-stream --format '{{.MemUsage}}' "$name" | awk '{print $1}')
|
||||
started=$(docker logs "$name" 2>&1 | grep -o 'Started ImagesApplication in [0-9.]* seconds' | awk '{print $4}')
|
||||
docker rm -f "$name" > /dev/null
|
||||
echo "$(( (t1 - t0) / 1000000 )) ${started:-?} $rss"
|
||||
}
|
||||
|
||||
{
|
||||
echo "# Spring Boot 4.1.1 application (webmvc + actuator + validation + prometheus), fat jar $(du -h "$MODULE_DIR/target/app.jar" | cut -f1)"
|
||||
echo "# Docker Engine $(docker version --format '{{.Server.Version}}'), classic overlay2 store. $RUNS startup runs each, median shown."
|
||||
echo "# 'on disk' = docker image inspect .Size (uncompressed). 'pushed' = layer blobs + config in the registry (compressed)."
|
||||
echo
|
||||
printf '%-20s %9s %9s %7s %-9s %-6s %-16s %9s %9s %9s %s\n' variant "on disk" pushed layers user shell packages "ready ms" "Started" "RSS" "JVM"
|
||||
for v in "${VARIANTS[@]}"; do
|
||||
img="sbd/docker-images:$v"
|
||||
docker tag "$img" "$REPO:$v" && docker push -q "$REPO:$v" > /dev/null
|
||||
disk=$(docker image inspect -f '{{.Size}}' "$img")
|
||||
read -r wire layers < <(compressed "$REPO:$v")
|
||||
user=$(docker image inspect -f '{{.Config.User}}' "$img"); user="${user:-root}"
|
||||
if docker run --rm --entrypoint /bin/sh "$img" -c true > /dev/null 2>&1; then shell=yes; else shell=no; fi
|
||||
pkgs=$(packages "$img")
|
||||
samples=()
|
||||
for _ in $(seq 1 "$RUNS"); do samples+=("$(startup "$img")"); done
|
||||
median=$(printf '%s\n' "${samples[@]}" | sort -n | sed -n "$(( (RUNS + 1) / 2 ))p")
|
||||
read -r ready started rss <<< "$median"
|
||||
name="measure-$$"; docker run -d --name "$name" -p "$PORT:8080" "$img" > /dev/null
|
||||
for _ in $(seq 1 600); do curl -s -o /dev/null localhost:$PORT/api/runtime && break; sleep 0.05; done
|
||||
jvm=$(curl -s localhost:$PORT/api/runtime | python3 -c 'import json,sys; r=json.load(sys.stdin); print(r["java.vendor"].split()[0], r["java.version"])')
|
||||
docker rm -f "$name" > /dev/null
|
||||
printf '%-20s %8sM %8sM %7s %-9s %-6s %-16s %9s %9s %9s %s\n' "$v" \
|
||||
"$(( disk / 1000000 ))" "$(( wire / 1000000 ))" "$layers" "$user" "$shell" "$pkgs" "$ready" "${started}s" "$rss" "$jvm"
|
||||
done
|
||||
} | tee "$OUT/image-matrix.txt"
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
# Regenerate every transcript under docs/output/ (about 15 minutes; startup is measured three
|
||||
# times per image). Stop anything else CPU-hungry first - a parallel job skewed one startup figure
|
||||
# by two seconds while this was being written.
|
||||
#
|
||||
# Needs: Docker, crane (github.com/google/go-containerregistry) for the size-over-the-wire numbers,
|
||||
# and the base images listed in docs/01-the-variants.md. In a network-restricted build environment
|
||||
# set BUILDPACKS_ARGS and JIB_ARGS - the values used for the committed output are the defaults below.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
source scripts/env.sh
|
||||
export BUILDPACKS_ARGS="${BUILDPACKS_ARGS--Pcorporate-proxy,no-maven-central -Dspring-boot.build-image.pullPolicy=IF_NOT_PRESENT}"
|
||||
export JIB_ARGS="${JIB_ARGS--Djib.from.image=docker://eclipse-temurin:25-jre}"
|
||||
|
||||
crane registry serve --address "$REGISTRY" > /tmp/registry.log 2>&1 &
|
||||
REG_PID=$!
|
||||
trap 'kill $REG_PID 2>/dev/null' EXIT
|
||||
sleep 1
|
||||
|
||||
mvn -q -DskipTests package
|
||||
./scripts/build-images.sh
|
||||
docker build -q -f docker/Dockerfile.jlink-distroless --build-arg EXTRA_MODULES= -t sbd/docker-images:jlink-jdeps-only . > /dev/null
|
||||
for v in shell-form shell-form-alpine shell-form-wrapper; do
|
||||
docker build -q -f "docker/Dockerfile.$v" -t "sbd/docker-images:$v" . > /dev/null
|
||||
done
|
||||
|
||||
./scripts/measure.sh
|
||||
./scripts/measure-rebuild.sh
|
||||
./scripts/demo-signals.sh
|
||||
./scripts/demo-jlink-metrics.sh
|
||||
./scripts/demo-aot-mismatch.sh
|
||||
./scripts/demo-buildpacks-memory.sh
|
||||
./scripts/demo-buildpacks-layers.sh
|
||||
echo "Regenerated: $(ls docs/output | wc -l) files in docs/output/"
|
||||
Reference in New Issue
Block a user