Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FreeIPA Docker

FreeIPA server running in Docker on Debian 13 / cgroups v2.

Quick start

./setup.sh      # generate .env and docker-compose.yml
make start      # start (installs IPA on first run, ~5 min)
make logs       # follow installation progress
make status     # check service health after install

Makefile targets

Target Description
make setup Re-run interactive setup wizard
make start Start the container
make stop Stop the container gracefully
make restart Restart the container
make logs Follow live logs
make status Container status + ipactl status
make shell Open bash inside the container
make update Pull new image and recreate (data preserved)
make clean Destructive — wipe data and force reinstall

Required docker-compose settings

These settings are non-obvious and all required. Removing any of them breaks the install.

cgroup: host + /sys/fs/cgroup:/sys/fs/cgroup:rw

FreeIPA runs systemd as PID 1. On Debian 13 with cgroups v2 and Docker's systemd cgroup driver, systemd inside a container cannot create its own cgroup namespace without access to the host's cgroup tree.

Without these: container exits immediately with code 255 (systemd fails to start).

No privileged: true

Using privileged: true causes a hard failure during installation:

GSS ERROR gss_acquire_cred_from() failed: SPNEGO cannot find mechanisms to negotiate
KerberosError: No valid Negotiate header in server response
FreeIPA server configuration failed.

The installer runs ipa-client-install --on-master as a final step. This authenticates to the local Apache via GSSAPI/SPNEGO using gssproxy. In a privileged container, something in the kernel's security context breaks gssproxy's ability to provide SPNEGO credentials to mod_auth_gssapi.

Remove privileged: true entirely. The container does not need it.

sysctls: - net.ipv6.conf.all.disable_ipv6=0

FreeIPA requires the IPv6 loopback interface (::1) to be active, even when you're not using IPv6 for anything. Without this sysctl, some internal Kerberos operations that bind to ::1 fail.

This replaces the sysctl -w call that fix-permissions.sh was previously doing at runtime.

--skip-mem-check in IPA_SERVER_INSTALL_OPTS

The IPA installer detects it is running in a container and checks available RAM by reading:

  • cgroup v2: /sys/fs/cgroup/memory.max and /sys/fs/cgroup/memory.current

With cgroup: host, the container sees the full host cgroup tree. The root cgroup does not have memory.max at /sys/fs/cgroup/memory.max — that file lives in the container's actual cgroup slice (e.g. /sys/fs/cgroup/system.slice/docker-xxx.scope/). The installer cannot find it and throws:

Unable to determine the amount of available RAM
FreeIPA server configuration failed.

--skip-mem-check bypasses this check. The host has sufficient RAM; the check is just broken by the cgroup namespace setup.

tmpfs: /run and /tmp

Standard requirement for any container running systemd. Without tmpfs on /run, systemd's socket and PID files conflict across restarts.

Scripts

scripts/fix-permissions.sh

Runs as a background loop during installation. Keeps /var/lib/ipa/gssproxy/ owned root:ipaapi (0:289) with mode 770, and http.keytab with mode 660.

The IPA installer (or the volume template initialization) resets this directory to root:root 700. If gssproxy cannot read its keytab because of wrong permissions, authentication fails. The script detects and corrects this faster than the installer can reset it.

scripts/ipa-server-configure-first.wrapper

Replaces the stock /usr/sbin/ipa-server-configure-first during installation. Starts fix-permissions.sh in the background, runs the original installer, then kills the background fixer when done.

First-run behavior

  1. Container starts, populate-volume-from-template copies defaults from the image's /data-template into ./data/
  2. Installer runs (~5 minutes). Watch with make logs.
  3. On success: container exits with code 123 (systemd shuts down) and Docker restarts it
  4. Second start: IPA services come up normally (ipactl start)

Installation is complete when you see:

FreeIPA server configured.

Data persistence

All IPA state lives in ./data/. The container can be destroyed and recreated without losing data. IPA is considered "installed" when ./data/etc/ipa/ca.crt exists.

To force a full reinstall: make clean.

About

freeipa docker compose for Debian 13 host

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages