Files
authelia/authelia.spec
T
zpericic ca1b8cf1ba Run quadlets as rootless user units
Quadlet does not support User= in system units: the generated pod
service writes its conmon pidfile to %t/%N.pid, which resolves to
/run/authelia-pod.pid and is unwritable by the authelia user, so
authelia-pod.service always failed with status 125. See
podman-systemd.unit(5).

- Move all quadlet files and drop-ins to the rootless search path
  /etc/containers/systemd/users/126; units now run in the authelia
  user's systemd manager, started at boot via linger
- Drop the [Service] User=/HOME overrides from the quadlet files
- Enable the pod via WantedBy=default.target
- Make /etc/authelia authelia-owned so rootless podman can relabel
  the config bind mount (:z)
- Replace system-unit systemd macros in the -container scriptlets
  with systemctl --user -M authelia@ daemon-reload / stop
2026-08-06 22:11:57 +02:00

313 lines
12 KiB
RPMSpec

# Build the native binary -service subpackage by default.
# Disable to build without the upstream release tarballs (container-only):
# rpmbuild -bb --without service authelia.spec
# mock --without=service ...
%bcond_without service
# Prebuilt upstream binary: no debuginfo to extract
%global debug_package %{nil}
# Fixed UID/GID of the authelia user (see authelia.sysusers)
%global authelia_uid 126
# Rootless quadlet search path for the authelia user. Quadlets do not
# support User=, so the units run in the authelia user's systemd manager
# (started at boot via linger); /usr/share/containers/systemd is only
# searched for rootful quadlets. See podman-systemd.unit(5).
%global quadletdir %{_sysconfdir}/containers/systemd/users/%{authelia_uid}
Name: authelia
Version: 4.39.20
Release: 2%{?dist}
Summary: Authelia - authentication and authorization server
License: Apache-2.0
Group: System Environment/Base
URL: https://www.authelia.com
%if %{with service}
Source0: https://github.com/authelia/authelia/releases/download/v%{version}/authelia-v%{version}-linux-amd64.tar.gz
Source1: https://github.com/authelia/authelia/releases/download/v%{version}/authelia-v%{version}-linux-arm64.tar.gz
%endif
Source10: authelia.service
Source11: authelia.sysusers
Source12: configuration.yml
Source13: users_database.yml
Source14: authelia.container
Source15: authelia.pod
Source16: authelia-pod-enable.conf
Source17: authelia-db.container
Source18: authelia-db-pod.conf
Source19: authelia-db-publish.conf
Source20: authelia-db-credentials.conf
Source21: authelia-container-database.conf
Source22: authelia-service-database.conf
Source23: authelia-redis.container
Source24: authelia-redis-pod.conf
Source25: authelia-redis-publish.conf
Source26: authelia-container-session.conf
Source27: authelia-service-session.conf
%if %{with service}
ExclusiveArch: x86_64 aarch64
%else
BuildArch: noarch
%endif
BuildRequires: systemd-rpm-macros
%description
Authelia is an open-source authentication and authorization server
providing single sign-on (SSO) and two-factor authentication (2FA) for
applications behind a reverse proxy.
This base package ships the authelia user (UID 126), the configuration
in /etc/authelia and the data directory. Install either
authelia-service (native binary) or authelia-container (rootless Podman
quadlet) to actually run the server.
%if %{with service}
%package service
Summary: Authelia systemd service (native binary)
Requires: %{name} = %{version}-%{release}
Conflicts: %{name}-container
%{?systemd_requires}
%description service
Runs Authelia as a native binary under systemd, listening on
127.0.0.1:9091.
%endif
%package container
Summary: Authelia container (rootless Podman quadlet)
Requires: %{name} = %{version}-%{release}
Requires: podman
Requires: containers-common
Requires: systemd-container
%if %{with service}
Conflicts: %{name}-service
%endif
%description container
Runs Authelia as a rootless Podman container (quadlet) under the
authelia user, in a pod publishing 127.0.0.1:9091. The optional
authelia-postgresql and authelia-redis containers join the same pod.
%package postgresql
Summary: PostgreSQL storage backend for Authelia
Requires: %{name} = %{version}-%{release}
Requires: podman
Requires: containers-common
Requires: systemd-container
%description postgresql
Ships a PostgreSQL container (authelia-db) running rootless under the
authelia user. With authelia-container it joins the authelia pod; with
authelia-service it publishes 127.0.0.1:5432. Enable it by uncommenting
the AUTHELIA_STORAGE_POSTGRES_* environment in the database.conf
drop-in and commenting out the local storage block in
/etc/authelia/configuration.yml.
%package redis
Summary: Redis session storage for Authelia
Requires: %{name} = %{version}-%{release}
Requires: podman
Requires: containers-common
Requires: systemd-container
%description redis
Ships a Redis container (authelia-redis) running rootless under the
authelia user for persistent session storage. With authelia-container
it joins the authelia pod; with authelia-service it publishes
127.0.0.1:6379. Enable it by uncommenting the AUTHELIA_SESSION_REDIS_*
environment in the session.conf drop-in.
%prep
%setup -q -c -T
%if %{with service}
%ifarch x86_64
tar -xzf %{SOURCE0} authelia
%endif
%ifarch aarch64
tar -xzf %{SOURCE1} authelia
%endif
%endif
%install
%{__rm} -rf %{buildroot}
# Base: sysusers, config
install -p -D -m 644 %{SOURCE11} %{buildroot}%{_sysusersdir}/authelia.conf
install -d -m 750 %{buildroot}%{_sysconfdir}/authelia
install -m 640 %{SOURCE12} %{buildroot}%{_sysconfdir}/authelia/configuration.yml
install -m 640 %{SOURCE13} %{buildroot}%{_sysconfdir}/authelia/users_database.yml
# Base: data dirs. /var/lib/authelia is the authelia user's HOME and holds
# the rootless podman storage for the container variants; only data/ (and
# the db dirs) are mounted into containers, since podman refuses relabeling
# of $HOME itself.
install -d -m 750 %{buildroot}%{_sharedstatedir}/authelia
install -d -m 750 %{buildroot}%{_sharedstatedir}/authelia/data
%if %{with service}
# Service subpackage
install -p -D -m 755 authelia %{buildroot}%{_libexecdir}/authelia
install -p -D -m 644 %{SOURCE10} %{buildroot}%{_unitdir}/authelia.service
install -p -D -m 644 %{SOURCE19} %{buildroot}%{quadletdir}/authelia-db.container.d/publish.conf
install -p -D -m 644 %{SOURCE25} %{buildroot}%{quadletdir}/authelia-redis.container.d/publish.conf
%endif
# Container subpackage
install -p -D -m 644 %{SOURCE14} %{buildroot}%{quadletdir}/authelia.container
install -p -D -m 644 %{SOURCE15} %{buildroot}%{quadletdir}/authelia.pod
install -p -D -m 644 %{SOURCE16} %{buildroot}%{quadletdir}/authelia.pod.d/enable.conf
install -p -D -m 644 %{SOURCE18} %{buildroot}%{quadletdir}/authelia-db.container.d/pod.conf
install -p -D -m 644 %{SOURCE24} %{buildroot}%{quadletdir}/authelia-redis.container.d/pod.conf
# PostgreSQL subpackage
install -d -m 750 %{buildroot}%{_sharedstatedir}/authelia/postgresql
install -p -D -m 644 %{SOURCE17} %{buildroot}%{quadletdir}/authelia-db.container
install -p -D -m 644 %{SOURCE20} %{buildroot}%{quadletdir}/authelia-db.container.d/credentials.conf
install -p -D -m 644 %{SOURCE21} %{buildroot}%{quadletdir}/authelia.container.d/database.conf
install -p -D -m 644 %{SOURCE22} %{buildroot}%{_sysconfdir}/systemd/system/authelia.service.d/database.conf
# Redis subpackage
install -d -m 750 %{buildroot}%{_sharedstatedir}/authelia/redis
install -p -D -m 644 %{SOURCE23} %{buildroot}%{quadletdir}/authelia-redis.container
install -p -D -m 644 %{SOURCE26} %{buildroot}%{quadletdir}/authelia.container.d/session.conf
install -p -D -m 644 %{SOURCE27} %{buildroot}%{_sysconfdir}/systemd/system/authelia.service.d/session.conf
%pre
%sysusers_create_compat %{SOURCE11}
%post
# Rootless podman under the authelia system user (container variants)
# needs a lingering user session (/run/user/126) and a subuid/subgid
# range for the in-container users.
if [ $1 -eq 1 ]; then
loginctl enable-linger authelia || :
fi
if ! grep -q "^authelia:" /etc/subuid 2>/dev/null; then
NEXT=$(awk -F: '{n=$2+$3} END{print n+0}' /etc/subuid 2>/dev/null)
[ "$NEXT" -lt 524288 ] && NEXT=524288
END=$((NEXT + 65535))
usermod --add-subuids "$NEXT-$END" --add-subgids "$NEXT-$END" authelia 2>/dev/null || :
fi
%if %{with service}
%post service
%systemd_post authelia.service
%posttrans service
ln -sf %{_libexecdir}/authelia %{_bindir}/authelia
%preun service
%systemd_preun authelia.service
%postun service
%systemd_postun_with_restart authelia.service
if [ $1 -eq 0 ]; then
rm -f %{_bindir}/authelia
fi
%endif
%post container
# Quadlets run in the authelia user's systemd manager (started via
# linger). Reload it so the units appear without a reboot; if the
# manager is not running yet this is a no-op until next boot.
systemctl --user -M authelia@ daemon-reload >/dev/null 2>&1 || :
%preun container
if [ $1 -eq 0 ]; then
systemctl --user -M authelia@ stop authelia-pod.service >/dev/null 2>&1 || :
fi
%postun container
systemctl --user -M authelia@ daemon-reload >/dev/null 2>&1 || :
%clean
%{__rm} -rf %{buildroot}
%files
%defattr(-,root,root,-)
%{_sysusersdir}/authelia.conf
# authelia-owned so rootless podman can relabel (:z) the config mount
%dir %attr(0750,authelia,authelia) %{_sysconfdir}/authelia
%config(noreplace) %attr(0640,authelia,authelia) %{_sysconfdir}/authelia/configuration.yml
%config(noreplace) %attr(0640,authelia,authelia) %{_sysconfdir}/authelia/users_database.yml
%dir %attr(0750,authelia,authelia) %{_sharedstatedir}/authelia
%dir %attr(0750,authelia,authelia) %{_sharedstatedir}/authelia/data
%if %{with service}
%files service
%defattr(-,root,root,-)
%{_libexecdir}/authelia
%ghost %{_bindir}/authelia
%attr(0644,root,root) %{_unitdir}/authelia.service
%dir %{_sysconfdir}/containers/systemd/users
%dir %{quadletdir}
%dir %{quadletdir}/authelia-db.container.d
%{quadletdir}/authelia-db.container.d/publish.conf
%dir %{quadletdir}/authelia-redis.container.d
%{quadletdir}/authelia-redis.container.d/publish.conf
%endif
%files container
%defattr(-,root,root,-)
%dir %{_sysconfdir}/containers/systemd/users
%dir %{quadletdir}
%{quadletdir}/authelia.container
%{quadletdir}/authelia.pod
%dir %{quadletdir}/authelia.pod.d
%config(noreplace) %{quadletdir}/authelia.pod.d/enable.conf
%dir %{quadletdir}/authelia-db.container.d
%{quadletdir}/authelia-db.container.d/pod.conf
%dir %{quadletdir}/authelia-redis.container.d
%{quadletdir}/authelia-redis.container.d/pod.conf
%files postgresql
%defattr(-,root,root,-)
%dir %attr(0750,authelia,authelia) %{_sharedstatedir}/authelia/postgresql
%dir %{_sysconfdir}/containers/systemd/users
%dir %{quadletdir}
%{quadletdir}/authelia-db.container
%dir %{quadletdir}/authelia-db.container.d
%config(noreplace) %{quadletdir}/authelia-db.container.d/credentials.conf
%dir %{quadletdir}/authelia.container.d
%config(noreplace) %{quadletdir}/authelia.container.d/database.conf
%dir %{_sysconfdir}/systemd/system/authelia.service.d
%config(noreplace) %{_sysconfdir}/systemd/system/authelia.service.d/database.conf
%files redis
%defattr(-,root,root,-)
%dir %attr(0750,authelia,authelia) %{_sharedstatedir}/authelia/redis
%dir %{_sysconfdir}/containers/systemd/users
%dir %{quadletdir}
%{quadletdir}/authelia-redis.container
%dir %{quadletdir}/authelia.container.d
%config(noreplace) %{quadletdir}/authelia.container.d/session.conf
%dir %{_sysconfdir}/systemd/system/authelia.service.d
%config(noreplace) %{_sysconfdir}/systemd/system/authelia.service.d/session.conf
%changelog
* Thu Aug 06 2026 Zoran Pericic <zpericic@netst.org> - 4.39.20-2
- Run quadlets as proper rootless user units in
/etc/containers/systemd/users/126 instead of system units with
User=authelia: quadlet does not support User= (the pod's conmon
pidfile at %%t/%%N.pid is unwritable in the system /run), see
podman-systemd.unit(5)
- Enable via WantedBy=default.target in the authelia user manager
- Make /etc/authelia authelia-owned so rootless podman can relabel
the config bind mount
* Thu Aug 06 2026 Zoran Pericic <zpericic@netst.org> - 4.39.20-1
- Initial package with service, container, postgresql and redis
subpackages
- Fixed UID/GID 126 for the authelia user
- Rootless quadlet (vaultwarden style) with an authelia pod publishing
127.0.0.1:9091; db and redis containers join the pod
- Container images pinned by digest
- Native -service subpackage built conditionally (--without service)