#!/usr/bin/env bash # run.sh — Start the FreeIPA stack with correct cgroup namespace on any host. # # Usage: # ./run.sh # freeipa only # ./run.sh all # freeipa + postgres + keycloak # ./run.sh down # stop and remove containers # # Why this exists: # The FreeIPA container runs systemd (/sbin/init) and requires the host cgroup # namespace on systems that use cgroup v2 (WSL2, recent Fedora/Ubuntu, etc.). # Docker Compose's schema does not expose a cgroupns_mode field, so this script # starts the freeipa container via `docker run --cgroupns host` and defers the # rest of the stack to `docker compose up`. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" [[ -f .env ]] || { echo "ERROR: .env not found. Copy .env.example and fill in values."; exit 1; } # shellcheck disable=SC1091 source .env MODE="${1:-}" stop_freeipa() { docker rm -f freeipa 2>/dev/null || true } start_freeipa() { stop_freeipa # Ensure the compose-managed network exists before docker run uses it docker compose up --no-start freeipa 2>/dev/null || true NETWORK=$(docker network ls --filter name=ipa-net --format '{{.Name}}' | grep ipa-net | head -1) if [[ -z "$NETWORK" ]]; then # Label the network exactly as compose would so a later # `docker compose up` (checkmk/postgres/keycloak) adopts it instead of # failing with "network exists but was not created by compose". docker network create --subnet=172.30.0.0/24 \ --label com.docker.compose.network=ipa-net \ --label com.docker.compose.project=image \ --label com.docker.compose.version=2 \ ipa-net NETWORK=ipa-net fi # Ensure the data volumes exist (cmk-creds is shared with the checkmk # container: CheckMK writes automation.secret there, the IPA container's # ansipa-checkmk-setup.sh reads it — without this mount the whole # dev_mon_* CheckMK integration silently never activates) docker volume create freeipa-data 2>/dev/null || true docker volume create cmk-creds 2>/dev/null || true docker run -d \ --name freeipa \ --hostname "${IPA_HOSTNAME:-ipa.example.com}" \ --privileged \ --cgroupns host \ --tmpfs /run \ --tmpfs /tmp \ -v /sys/fs/cgroup:/sys/fs/cgroup:rw \ -v freeipa-data:/data \ -v cmk-creds:/cmk-creds \ --network "$NETWORK" \ --ip 172.30.0.10 \ -e IPA_DOMAIN="${IPA_DOMAIN:?}" \ -e IPA_REALM="${IPA_REALM:-}" \ -e IPA_ADMIN_PASSWORD="${IPA_ADMIN_PASSWORD:?}" \ -e IPA_DM_PASSWORD="${IPA_DM_PASSWORD:?}" \ -e IPA_SETUP_DNS="${IPA_SETUP_DNS:-false}" \ -e IPA_DNS_FORWARDER="${IPA_DNS_FORWARDER:-}" \ -e IPA_SETUP_KRA="${IPA_SETUP_KRA:-false}" \ -e SMB_SCAN_PASSWORD="${SMB_SCAN_PASSWORD:?}" \ -e LUKS_KEY_UPLOAD_PASSWORD="${LUKS_KEY_UPLOAD_PASSWORD:?}" \ -e CMK_URL="http://172.30.0.12:5000" \ -e CMK_ADVERTISED_URL="${CMK_ADVERTISED_URL:-}" \ -e CMK_SITE_ID="${CMK_SITE_ID:-cmk}" \ -p 389:389 \ -p 636:636 \ -p 88:88 \ -p 88:88/udp \ -p 464:464 \ -p 464:464/udp \ -p 443:443 \ -p 445:445 \ -p 139:139 \ -p 137:137/udp \ -p 138:138/udp \ freeipa-server:local echo "FreeIPA container started. Watch first-boot progress:" echo " docker exec freeipa journalctl -f -u ipa-first-boot.service" echo " (first-boot takes ~10 min)" } case "$MODE" in down) stop_freeipa docker compose down echo "Stack stopped." ;; all) start_freeipa docker compose up -d postgres keycloak checkmk echo "Full stack started (freeipa + postgres + keycloak + checkmk)." ;; "") start_freeipa ;; *) echo "Usage: $0 [all|down]" exit 1 ;; esac