blumeops/containers/authentik/authentik-server.nix
Erich Blume efa9806bfa
All checks were successful
Build Container / detect (push) Successful in 3s
Build Container (Nix) / detect (push) Successful in 1s
Build Container / build (authentik) (push) Successful in 2s
Build Container (Nix) / build (authentik) (push) Successful in 22s
C2: Build authentik from source (Mikado chain) (#274)
## Mikado Chain: build-authentik-from-source

Replace `pkgs.authentik` from nixpkgs with a custom Nix derivation built from source.
This removes the dependency on the nixpkgs packaging timeline and gives full version control.

Target version: **2025.12.4** (nixpkgs reference, upgrading from deployed 2025.10.1).

### Dependency Graph

```
build-authentik-from-source (goal)
├── authentik-go-server-derivation
│   ├── authentik-api-client-generation  ← IN PROGRESS
│   └── authentik-python-backend-derivation
├── authentik-web-ui-derivation
│   └── authentik-api-client-generation  ← IN PROGRESS
└── authentik-python-backend-derivation
```

### Ready Leaves
- `authentik-api-client-generation` — Go + TypeScript client generation from OpenAPI schema
- `authentik-python-backend-derivation` — Django backend with 60+ deps, 4 in-tree packages

### Architecture
Ported from [nixpkgs `pkgs/by-name/au/authentik/package.nix`](https://github.com/NixOS/nixpkgs/tree/master/pkgs/by-name/au/authentik):
- `source.nix` — shared version/source fetch
- `client-go.nix` — Go API client generation
- `client-ts.nix` — TypeScript API client generation
- `api-go-vendor-hook.nix` — Go vendor directory injection hook
- (more components to follow as leaves are closed)

### Related Cards
- [[build-authentik-from-source]] — Goal card
- [[authentik-api-client-generation]]
- [[authentik-python-backend-derivation]]
- [[authentik-web-ui-derivation]]
- [[authentik-go-server-derivation]]

Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/274
2026-03-01 13:45:00 -08:00

64 lines
2.1 KiB
Nix

# Authentik Go HTTP server binary
#
# Builds cmd/server from the authentik source using buildGoModule.
# The compiled binary serves the web UI, REST API, spawns gunicorn
# for the Django backend, and runs the embedded reverse proxy outpost.
#
# Two runtime path dependencies are baked in at compile time:
# - authentik-django: lifecycle scripts (gunicorn launcher)
# - webui: static web assets (dist/ and authentik/ directories)
#
# The apiGoVendorHook replaces vendored goauthentik.io/api/v3 with
# freshly generated client-go output, but only during the real build
# (not the FOD module-download phase), so vendorHash stays stable.
#
# Output: $out/bin/authentik
{ pkgs ? import <nixpkgs> { }
, sources ? import ./sources.nix { inherit pkgs; }
, authentik-django ? import ./authentik-django.nix { inherit pkgs sources; }
, webui ? null
}:
let
apiGoVendorHook = import ./api-go-vendor-hook.nix { inherit pkgs sources; };
# Web assets path: use real webui derivation if provided, otherwise
# a placeholder directory. The placeholder allows the binary to compile
# and pass --help verification, but web serving won't work at runtime.
webAssetsPath =
if webui != null then webui
else pkgs.runCommand "webui-placeholder" { } ''
mkdir -p $out/dist $out/authentik
'';
in
pkgs.buildGoModule {
pname = "authentik-server";
inherit (sources) version src meta;
subPackages = [ "cmd/server" ];
nativeBuildInputs = [ apiGoVendorHook ];
env.CGO_ENABLED = 0;
postPatch = ''
substituteInPlace internal/gounicorn/gounicorn.go \
--replace-fail './lifecycle' "${authentik-django}/lifecycle"
substituteInPlace web/static.go \
--replace-fail './web' "${webAssetsPath}"
substituteInPlace internal/web/static.go \
--replace-fail './web' "${webAssetsPath}"
'';
# Clear postPatch during the module-download FOD phase so that
# substituteInPlace (which references authentik-django and webui
# store paths) doesn't affect vendorHash computation.
overrideModAttrs.postPatch = "";
vendorHash = "sha256-bdILiCQgDuzp+VJDVW3z2JxTtxlHkm9tmMHiA/Sx6ts=";
postInstall = ''
mv $out/bin/server $out/bin/authentik
'';
}