From 3f3853d973da07f07ae6f061a52c14d7a28f7c97 Mon Sep 17 00:00:00 2001 From: YUVRAJ Date: Tue, 17 Mar 2026 12:27:23 +0530 Subject: [PATCH] feat: separate keycloak config and user exports #304 --- scripts/realm_export.sh | 62 +++++++++++++++++++++++++++-------- scripts/realm_import_users.sh | 48 +++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 14 deletions(-) create mode 100755 scripts/realm_import_users.sh diff --git a/scripts/realm_export.sh b/scripts/realm_export.sh index cc80ed643..f73b22564 100755 --- a/scripts/realm_export.sh +++ b/scripts/realm_export.sh @@ -1,21 +1,55 @@ #!/bin/bash +set -euo pipefail -SCRIPT_PATH="$(readlink -f "$0")" -SCRIPT_DIR="$(dirname "$SCRIPT_PATH")" +# Set defaults, but allow overrides via environment variables +KEYCLOAK_CONTAINER="${KEYCLOAK_CONTAINER:-keycloak}" +KEYCLOAK_REALM="${KEYCLOAK_REALM:-aiod}" +EXPORT_DIR="${EXPORT_DIR:-./keycloak-exports}" -cd $SCRIPT_DIR/.. +REALM_FILE="aiod-realm.json" +USERS_FILE="aiod-users.json" +CONTAINER_TMP="/tmp/keycloak-export" -source .env -[ ! -f override.env ] && touch override.env -source override.env -DATA_PATH=$(realpath "$DATA_PATH") -LOCAL_BACKUP_PATH="$DATA_PATH"/keycloak_realm +log() { + echo "[realm_export] $1" +} -docker exec -i keycloak /bin/bash -c "/opt/keycloak/bin/kc.sh export --file /tmp/aiod.json --realm aiod --users realm_file" - -if [ ! -d "$LOCAL_BACKUP_PATH" ]; then - mkdir "$LOCAL_BACKUP_PATH" +# Bail out early if the container isn't up +if ! docker inspect --format '{{.State.Running}}' "${KEYCLOAK_CONTAINER}" 2>/dev/null | grep -q "^true$"; then + echo "Error: Container '${KEYCLOAK_CONTAINER}' doesn't seem to be running." >&2 + echo "Make sure Keycloak is up before running the backup script." >&2 + exit 1 fi -docker cp keycloak:/tmp/aiod.json "$LOCAL_BACKUP_PATH"/aiod.json -docker exec -i keycloak /bin/bash -c "rm /tmp/aiod.json" +# Prep the local and container directories +mkdir -p "${EXPORT_DIR}" +docker exec "${KEYCLOAK_CONTAINER}" mkdir -p "${CONTAINER_TMP}" + +# --- 1. Export the realm config (skipping users) --- +log "Exporting realm config to ${REALM_FILE}..." + +docker exec "${KEYCLOAK_CONTAINER}" \ + /opt/keycloak/bin/kc.sh export \ + --dir "${CONTAINER_TMP}" \ + --realm "${KEYCLOAK_REALM}" \ + --users skip + +# kc.sh generates the file as -realm.json, pull it out and rename it +docker cp "${KEYCLOAK_CONTAINER}:${CONTAINER_TMP}/${KEYCLOAK_REALM}-realm.json" "${EXPORT_DIR}/${REALM_FILE}" +log "✔ Realm config saved." + +# --- 2. Export the user data --- +log "Exporting user data to ${USERS_FILE}..." + +docker exec "${KEYCLOAK_CONTAINER}" \ + /opt/keycloak/bin/kc.sh export \ + --dir "${CONTAINER_TMP}" \ + --realm "${KEYCLOAK_REALM}" \ + --users realm_file + +# Keycloak chunks user exports, giving it a '-0' suffix. +# Grab it and rename it to our clean target filename. +docker cp "${KEYCLOAK_CONTAINER}:${CONTAINER_TMP}/${KEYCLOAK_REALM}-users-0.json" "${EXPORT_DIR}/${USERS_FILE}" +log "✔ User data saved." + +# Clean up the temp folder inside the container so we don' \ No newline at end of file diff --git a/scripts/realm_import_users.sh b/scripts/realm_import_users.sh new file mode 100755 index 000000000..49455c4c2 --- /dev/null +++ b/scripts/realm_import_users.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# script to import users into keycloak without breaking the realm config +# fixes issue #304 + +set -euo pipefail # stop on errors + +# set variables or use defaults +KEYCLOAK_CONTAINER="${KEYCLOAK_CONTAINER:-keycloak}" +KEYCLOAK_REALM="${KEYCLOAK_REALM:-aiod}" +EXPORT_DIR="${EXPORT_DIR:-./keycloak-exports}" + +# get file from args or use default +USERS_FILE="${1:-${EXPORT_DIR}/aiod-users.json}" +CONTAINER_TMP="/tmp/keycloak-import" + +# check if backup file actually exists +if [[ ! -f "${USERS_FILE}" ]]; then + echo "error: can't find the users file at ${USERS_FILE}" >&2 + echo "run the export script first or pass the exact path" >&2 + exit 1 +fi + +# check if docker container is running +if ! docker inspect --format '{{.State.Running}}' "${KEYCLOAK_CONTAINER}" 2>/dev/null | grep -q "^true$"; then + echo "error: keycloak container isn't running right now" >&2 + exit 1 +fi + +echo "importing users from ${USERS_FILE}..." + +# make temp dir inside container +docker exec "${KEYCLOAK_CONTAINER}" mkdir -p "${CONTAINER_TMP}" + +# copy backup file into the container +docker cp "${USERS_FILE}" "${KEYCLOAK_CONTAINER}:${CONTAINER_TMP}/aiod-users.json" + +# run the import +# using --override false so we don't accidentally overwrite existing users +docker exec "${KEYCLOAK_CONTAINER}" \ + /opt/keycloak/bin/kc.sh import \ + --dir "${CONTAINER_TMP}" \ + --realm "${KEYCLOAK_REALM}" \ + --override false + +# clean up temp files +docker exec "${KEYCLOAK_CONTAINER}" rm -rf "${CONTAINER_TMP}" + +echo "done! users imported safely." \ No newline at end of file