Entrypoint: stop with Keycloak, persist setup marker with data, add KC_SKIP_DEFAULT_SETUP - #16
Merged
Merged
Conversation
…SETUP
The entrypoint now waits on Keycloak instead of sleep infinity, so the
container exits (with Keycloak's status) when Keycloak does and Docker
restart policies apply. SIGTERM/SIGINT are passed on to Keycloak for a
clean shutdown instead of a kill after 10s.
With the default dev-file database the setup-complete marker moves to
${KC_HOME}/data, next to the database, so a recreated container with a
data volume skips setup. Other databases keep the old location.
KC_SKIP_DEFAULT_SETUP=true skips the unmodified default scripts while
still running user-provided ones.
Also fixes top-level `return 0` when KC_BACKEND_URL is empty and a missing
`;` after sourcing *.env files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
slominskir
approved these changes
Sep 28, 2026
slominskir
left a comment
Member
There was a problem hiding this comment.
LGTM. This better aligns this container with app database containers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes entrypoint problems found when running this image with
restart: unless-stoppedand a volume on/opt/keycloak/data(Sync Board). Existing users see no change unless they opt in, with the exceptions listed under Behavior changes.Changes
1. The container now stops when Keycloak stops, and
docker stopshuts Keycloak down cleanly (container-entrypoint.sh)waits on Keycloak's PID instead ofsleep infinity, then exits with Keycloak's status. If Keycloak crashes, the container exits and Docker's restart policy applies.KC_BACKEND_URL, the wait loop now exits too instead of polling forever.2. The
setup-completemarker is stored with the database (container-entrypoint.sh,container-healthcheck.sh)KC_DBunset ordev-file), the marker is now${KC_HOME}/data/setup-complete, next to the H2 database. A container recreated on the same data volume keeps its realm and skips setup instead of re-runningkcadm creates that fail.data/is in the container layer, as the old marker was.KC_DB=oracle, as in this repo'scompose.yaml), the marker stays at${KC_HOME}/setup-complete, exactly as before. A marker indata/would say nothing about whether an external database has been set up. It could even skip setup on a freshly wiped database if someone mounts a data volume. The README explains this and suggestsKC_SKIP_DEFAULT_SETUPor idempotent scripts when the database outlives the container.kc-lib.shbecause users who mount their own copy ofkc-lib.shwould then break the healthcheck.3. New opt-in
KC_SKIP_DEFAULT_SETUP=true/container-entrypoint-initdb.dthat are unmodified copies of the image's/defaults(00_config.env,01_base.sh,02_accounts.sh). Keycloak starts with only the master realm and bootstrap admin, and still becomes healthy.02_accounts.shmount. So the variable is a supported replacement for the tmpfs trick, and users can still add their own scripts.4. Small fixes
KC_BACKEND_URL: the top-levelreturn 0(an error outside a function) is replaced by waiting on Keycloak without running setup. Before, the script carried on and polled an empty URL forever.*.envbranch: added the missing;after. "${f}", so theechono longer passes its words as arguments to the sourced file.The README also gets a short Notes on Setup and Persistence section.
VERSIONand workflows are unchanged.Behavior changes to note for the release
docker stopnow exits with code 143 (Keycloak's status after a graceful SIGTERM shutdown), after about 1–2 s. Before, it took 10 s and exited with 137 (killed).kcadm"Conflict" errors, and then writes the new marker. Later recreates skip setup. Users who hide the defaults (like Sync Board's tmpfs) see nothing.Testing
Built locally with
docker build -t jeffersonlab/keycloak:dev ..Standalone image (scripted, dev-file DB unless noted):
test-realm, 4 users, marker indata/,00_config.envsourced cleanly, healthydocker stop: 1–2 s, exit 143, log showsStopping Keycloak...andKeycloak stopped in 1.09s(the published:3image: 10 s, exit 137)kill -9of the Java process with--restart unless-stopped: container exits (logsKeycloak exited with status 137), restarts (RestartCount=1), skips setup, healthy again/opt/keycloak/data, add a user, stop and remove, recreate: setup skipped, no conflicts, realm and extra user keptKC_SKIP_DEFAULT_SETUP=true: healthy, notest-realm, 3 defaults logged as skippedKC_SKIP_DEFAULT_SETUP=trueplus a mounted99_extra.sh: the extra script runsKC_DB=postgres: marker at${KC_HOME}/setup-complete, none indata/, realm created, healthyKC_BACKEND_URL: Keycloak runs, no setup attempted,docker stopin 1–2 sSync Board (the
keycloakservice pointed at:devby a local, uncommitted override; existingkcdatavolume; tmpfs over/container-entrypoint-initdb.d):pnpm c:up: healthy on the existing volume.pnpm kc:setup: "Nothing was missing."pnpm test:integrationagainst the dev server: 20/20 pass.docker restart: 1 s.--force-recreate: "Setup already run; skipping", still healthy.Not tested: the Oracle path in this repo's
compose.yaml. It's covered by the same non-dev-file branch as T6.Note for local builds: on this Docker 29 / containerd 2 host, the
dnf installstep hangs (rpm looping over a hugenofilelimit) unless you build with--ulimit nofile=1024:1024. CI is unaffected.🤖 Generated with Claude Code