210 lines
8.6 KiB
YAML
210 lines
8.6 KiB
YAML
# FreeIPA + Keycloak + PostgreSQL constellation
|
|
#
|
|
# Setup:
|
|
# cp .env.example .env && $EDITOR .env
|
|
# docker compose up -d
|
|
# docker compose logs -f freeipa # watch first-boot install (~10 min)
|
|
# # Once freeipa is healthy:
|
|
# ./keycloak-configure.sh # wire Keycloak → FreeIPA LDAP
|
|
#
|
|
# To run without Keycloak:
|
|
# docker compose up -d freeipa
|
|
#
|
|
# To scale out (clients enroll against the same IPA server):
|
|
# docker compose --profile clients up
|
|
#
|
|
# ── cgroupns NOTE ────────────────────────────────────────────────────────────
|
|
# On hosts using cgroup v2 (WSL2, recent Linux with unified hierarchy) the
|
|
# FreeIPA container runs /sbin/init (systemd) and exits immediately with code
|
|
# 255 unless the container shares the host cgroup namespace. Docker Compose
|
|
# does not yet expose a cgroupns_mode property in its schema, so use the
|
|
# provided run.sh wrapper instead of plain `docker compose up` on those hosts:
|
|
#
|
|
# ./run.sh — starts freeipa only (cgroupns host applied automatically)
|
|
# ./run.sh all — starts freeipa + postgres + keycloak
|
|
#
|
|
# On plain cgroup v1 hosts `docker compose up -d` works without run.sh.
|
|
|
|
volumes:
|
|
freeipa-data:
|
|
keycloak-db:
|
|
cmk-data: # CheckMK site data (persistent across restarts)
|
|
cmk-creds: # shared: CheckMK writes automation.secret here; FreeIPA reads it
|
|
|
|
networks:
|
|
ipa-net:
|
|
ipam:
|
|
config:
|
|
- subnet: 172.30.0.0/24
|
|
|
|
services:
|
|
|
|
# ── FreeIPA ─────────────────────────────────────────────────────────────────
|
|
freeipa:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
image: freeipa-server:local
|
|
container_name: freeipa
|
|
hostname: ${IPA_HOSTNAME:-ipa.example.com}
|
|
privileged: true
|
|
tmpfs:
|
|
- /run
|
|
- /tmp
|
|
volumes:
|
|
- freeipa-data:/data
|
|
- /sys/fs/cgroup:/sys/fs/cgroup:rw
|
|
- cmk-creds:/cmk-creds # read CMK secret + write push-mode requests for hosts
|
|
environment:
|
|
IPA_DOMAIN: ${IPA_DOMAIN:?set IPA_DOMAIN in .env}
|
|
IPA_REALM: ${IPA_REALM:-}
|
|
IPA_ADMIN_PASSWORD: ${IPA_ADMIN_PASSWORD:?set IPA_ADMIN_PASSWORD in .env}
|
|
IPA_DM_PASSWORD: ${IPA_DM_PASSWORD:?set IPA_DM_PASSWORD in .env}
|
|
IPA_SETUP_DNS: ${IPA_SETUP_DNS:-false}
|
|
IPA_DNS_FORWARDER: ${IPA_DNS_FORWARDER:-}
|
|
IPA_SETUP_KRA: ${IPA_SETUP_KRA:-false}
|
|
SMB_SCAN_PASSWORD: ${SMB_SCAN_PASSWORD:?set SMB_SCAN_PASSWORD in .env}
|
|
CMK_URL: http://172.30.0.12:5000
|
|
CMK_SITE_ID: ${CMK_SITE_ID:-cmk}
|
|
ports:
|
|
- "389:389"
|
|
- "636:636"
|
|
- "88:88"
|
|
- "88:88/udp"
|
|
- "464:464"
|
|
- "464:464/udp"
|
|
- "443:443"
|
|
- "445:445"
|
|
- "139:139"
|
|
- "137:137/udp"
|
|
- "138:138/udp"
|
|
networks:
|
|
ipa-net:
|
|
ipv4_address: 172.30.0.10
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "ipactl status 2>/dev/null | grep -q 'running'"]
|
|
interval: 30s
|
|
timeout: 15s
|
|
retries: 20
|
|
start_period: 600s
|
|
|
|
# ── PostgreSQL (Keycloak backend) ────────────────────────────────────────────
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
container_name: keycloak-db
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_DB: keycloak
|
|
POSTGRES_USER: keycloak
|
|
POSTGRES_PASSWORD: ${KC_DB_PASSWORD:?set KC_DB_PASSWORD in .env}
|
|
volumes:
|
|
- keycloak-db:/var/lib/postgresql/data
|
|
networks:
|
|
ipa-net:
|
|
healthcheck:
|
|
test: ["CMD", "pg_isready", "-U", "keycloak"]
|
|
interval: 10s
|
|
retries: 5
|
|
|
|
# ── CheckMK CE ───────────────────────────────────────────────────────────────
|
|
# Monitoring server. Clients register themselves via ansipa-enforce-policies.sh
|
|
# when added to dev_mon_base. The automation user's secret is written to the
|
|
# cmk-creds shared volume so ansipa-checkmk-setup.sh (in the freeipa container)
|
|
# can store it in the IPA dev_mon_base hostgroup description for client discovery.
|
|
#
|
|
# Web UI: http://localhost:8090/cmk/ (user: cmkadmin, pass: CMK_ADMIN_PASSWORD)
|
|
# Agent dl: http://localhost:8090/cmk/check_mk/agents/
|
|
# Note: CheckMK 2.3 uses port 5000 (OMD apache); host port 8090 maps to it.
|
|
checkmk:
|
|
image: checkmk/check-mk-raw:2.3.0-latest
|
|
container_name: checkmk
|
|
hostname: checkmk.test.local
|
|
restart: unless-stopped
|
|
# Override entrypoint to copy the auto-generated automation secret to the
|
|
# shared volume so the freeipa container can read it without docker exec.
|
|
# $$ → $ after Compose expansion (i.e., $$! → $! in bash = background PID).
|
|
command:
|
|
- bash
|
|
- -c
|
|
- >-
|
|
/docker-entrypoint.sh & CMK_PID=$$!;
|
|
until [ -f /omd/sites/${CMK_SITE_ID:-cmk}/var/check_mk/web/automation/automation.secret ];
|
|
do sleep 3; done; sleep 5;
|
|
mkdir -p /cmk-creds;
|
|
cp /omd/sites/${CMK_SITE_ID:-cmk}/var/check_mk/web/automation/automation.secret /cmk-creds/automation.secret;
|
|
chmod 644 /cmk-creds/automation.secret;
|
|
printf '<LocationMatch ^/cmk/(omd|wiki|nagvis|check_mk|pnp4nagios|api)>\n Order allow,deny\n Allow from all\n Satisfy any\n</LocationMatch>\n'
|
|
> /omd/sites/${CMK_SITE_ID:-cmk}/etc/apache/conf.d/cookie_auth.conf;
|
|
omd reload ${CMK_SITE_ID:-cmk} apache 2>/dev/null || true;
|
|
while true; do
|
|
for _req in /cmk-creds/push-mode-*.req; do
|
|
[ -f "$$_req" ] || continue;
|
|
_hn=$$(cat "$$_req");
|
|
_hk=$$(echo "$$_hn" | tr . _);
|
|
_mk=/omd/sites/${CMK_SITE_ID:-cmk}/etc/check_mk/conf.d/wato/ansipa/hosts.mk;
|
|
[ -f "$$_mk" ] || continue;
|
|
grep -q "explicit_host_conf.*$$_hk\|'$$_hn'.*push-agent" "$$_mk" 2>/dev/null && { rm -f "$$_req"; continue; };
|
|
printf '\nexplicit_host_conf.setdefault('"'"'cmk_agent_connection'"'"', {})\nexplicit_host_conf['"'"'cmk_agent_connection'"'"'].update({'"'"'%s'"'"': '"'"'push-agent'"'"'})\n' "$$_hn" >> "$$_mk";
|
|
su - ${CMK_SITE_ID:-cmk} -c 'cmk -O' 2>/dev/null || true;
|
|
rm -f "$$_req";
|
|
done;
|
|
sleep 30;
|
|
done &
|
|
wait $$CMK_PID
|
|
environment:
|
|
CMK_SITE_ID: ${CMK_SITE_ID:-cmk}
|
|
CMK_PASSWORD: ${CMK_ADMIN_PASSWORD:?set CMK_ADMIN_PASSWORD in .env}
|
|
ports:
|
|
- "8090:5000" # web UI (CheckMK 2.3 uses port 5000 for OMD apache)
|
|
- "8000:8000" # agent receiver (push mode / cmk-agent-ctl)
|
|
- "6557:6557" # livestatus (optional, for external tools)
|
|
volumes:
|
|
- cmk-data:/omd/sites
|
|
- cmk-creds:/cmk-creds
|
|
networks:
|
|
ipa-net:
|
|
ipv4_address: 172.30.0.12
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "curl -sf http://localhost:5000/${CMK_SITE_ID:-cmk}/check_mk/api/1.0/version >/dev/null 2>&1"]
|
|
interval: 30s
|
|
timeout: 15s
|
|
retries: 20
|
|
start_period: 180s
|
|
|
|
# ── Keycloak ─────────────────────────────────────────────────────────────────
|
|
# After first start, run ./keycloak-configure.sh to wire FreeIPA LDAP federation.
|
|
keycloak:
|
|
image: quay.io/keycloak/keycloak:latest
|
|
container_name: keycloak
|
|
restart: unless-stopped
|
|
# Use 'start' (not start-dev) for production; requires a TLS certificate.
|
|
command: start-dev
|
|
environment:
|
|
KC_DB: postgres
|
|
KC_DB_URL: jdbc:postgresql://postgres/keycloak
|
|
KC_DB_USERNAME: keycloak
|
|
KC_DB_PASSWORD: ${KC_DB_PASSWORD:?set KC_DB_PASSWORD in .env}
|
|
KC_HOSTNAME: ${KC_HOSTNAME:-localhost}
|
|
KC_HTTP_PORT: 8080
|
|
KC_HTTPS_PORT: 8443
|
|
KC_HTTP_ENABLED: "true"
|
|
KC_FEATURES: preview
|
|
KEYCLOAK_ADMIN: ${KC_ADMIN:-admin}
|
|
KEYCLOAK_ADMIN_PASSWORD: ${KC_ADMIN_PASSWORD:?set KC_ADMIN_PASSWORD in .env}
|
|
extra_hosts:
|
|
- "${IPA_HOSTNAME:-ipa.example.com}:172.30.0.10"
|
|
ports:
|
|
- "8080:8080"
|
|
- "8443:8443"
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
networks:
|
|
ipa-net:
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "curl -fs http://localhost:8080/health/ready || exit 1"]
|
|
interval: 20s
|
|
timeout: 10s
|
|
retries: 20
|
|
start_period: 90s
|