Drop the nixpkgs packageOverrides approach for Python deps. Instead, use uv + fixed-output derivation to install from PyPI where cp314 wheels already exist. Eliminates the entire class of Python 3.14 nixpkgs compat issues (astor, dacite, exceptiongroup, pydantic-core). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.8 KiB
| title | modified | status | requires | tags | ||||
|---|---|---|---|---|---|---|---|---|
| Build Authentik Python Backend | 2026-02-28 | active |
|
|
Build Authentik Python Backend
Build authentik-django — the Python/Django application that forms the core backend of authentik.
Context
Authentik 2026.2.0 requires Python 3.14 (requires-python = "==3.14.*"). The nixpkgs reference derivation (2025.12.4) builds all 60+ Python deps through nix's python3.override with packageOverrides. This approach breaks on Python 3.14 because many nixpkgs python314 packages haven't been updated — astor, dacite, exceptiongroup, and pydantic-core all fail to build.
Instead of carrying individual overrides for each broken package, we use uv to install Python dependencies from PyPI, where upstream maintainers have already published Python 3.14-compatible wheels. Nix provides only the Python interpreter and system libraries.
Approach: uv + fixed-output derivation
Nix builds are sandboxed with no network access. The pattern is:
- Fixed-output derivation (FOD) — downloads all wheels/sdists from PyPI. FODs are allowed network access because the output hash is declared upfront (like
fetchurl). Locked by authentik'suv.lock. - Main derivation — builds a Python venv from the downloaded packages using
uv pip install --find-links <FOD> --no-index. No network needed.
This aligns with how authentik upstream builds (they use uv as their package manager).
What to Do
- Create a FOD that runs
uv pip downloadto fetch all Python dependencies locked byuv.lock - Create the main derivation that:
- Sets up a Python 3.14 venv via
uv - Installs all dependencies from the FOD (offline,
--no-index) - Installs the 4 in-tree packages from the monorepo source (
ak-guardian,django-channels-postgres,django-dramatiq-postgres,django-postgres-cache) - Installs authentik itself
- Sets up a Python 3.14 venv via
- Apply
substituteInPlacepatches for Nix store paths insettings.py,default.yml,email/utils.py,files/backends/file.py - Copy lifecycle scripts,
manage.py, blueprints, and web assets into the output - Verify:
python -c "import authentik"succeeds
Key Details
- Nix provides:
python314,uv, system libraries (libxml2,libxslt,openssl,libffi,zlib, etc.) - PyPI provides: all Python packages (via pre-built
cp314wheels where available, sdist builds otherwise) - The FOD hash must be recomputed when
uv.lockchanges manylinuxwheels bundle some.sofiles — acceptable for a container image- The 4 in-tree packages are installed from monorepo source, not PyPI
- Standard
djangorestframework3.16.1 from PyPI (no longer forked as of 2026.2.0)
Related
- build-authentik-from-source — Parent goal
- authentik-go-server-derivation — Depends on this for lifecycle scripts and web assets