blumeops/docs/how-to/authentik/authentik-python-backend-derivation.md
Erich Blume f65106dcef C2(authentik-source-build): plan pivot to uv-based Python packaging
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>
2026-03-01 11:45:39 -08:00

2.8 KiB

title modified status requires tags
Build Authentik Python Backend 2026-02-28 active
mirror-authentik-build-deps
how-to
authentik
nix

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:

  1. 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's uv.lock.
  2. 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

  1. Create a FOD that runs uv pip download to fetch all Python dependencies locked by uv.lock
  2. 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
  3. Apply substituteInPlace patches for Nix store paths in settings.py, default.yml, email/utils.py, files/backends/file.py
  4. Copy lifecycle scripts, manage.py, blueprints, and web assets into the output
  5. 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 cp314 wheels where available, sdist builds otherwise)
  • The FOD hash must be recomputed when uv.lock changes
  • manylinux wheels bundle some .so files — acceptable for a container image
  • The 4 in-tree packages are installed from monorepo source, not PyPI
  • Standard djangorestframework 3.16.1 from PyPI (no longer forked as of 2026.2.0)