From 86fd95b688015f9abcc28612b1bd7622ef3e14c1 Mon Sep 17 00:00:00 2001 From: niten Date: Mon, 28 Aug 2023 17:54:22 -0700 Subject: [PATCH] Initial checkin --- authentik-container.nix | 170 +++++++++++++++++++++++++++++ flake.lock | 233 ++++++++++++++++++++++++++++++++++++++++ flake.nix | 17 +++ 3 files changed, 420 insertions(+) create mode 100644 authentik-container.nix create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/authentik-container.nix b/authentik-container.nix new file mode 100644 index 0000000..eee901a --- /dev/null +++ b/authentik-container.nix @@ -0,0 +1,170 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.services.authentikContainer; + + hostSecrets = config.fudo.secrets.host-secrets."${config.instance.hostname}"; + + mkEnvFile = envVars: + let + envLines = + mapAttrsToList (var: val: ''${var}="${toString val}"'') envVars; + in pkgs.writeText "envFile" (concatStringsSep "\n" envLines); + + postgresPasswdFile = + pkgs.lib.passwd.stablerandom-passwd-file "authentik-postgresql-passwd" + config.instance.build-seed; + +in { + options.services.authentikContainer = with types; { + enable = mkEnableOption "Enable Authentik running in an Arion container."; + + state-directory = mkOption { + type = str; + description = "Directory at which to store server state data."; + }; + + images = { + authentik = mkOption { type = str; }; + postgres = mkOption { type = str; }; + redis = mkOption { type = str; }; + }; + + uids = { + authentik = mkOption { + type = int; + default = 721; + }; + authentik-postgres = mkOption { + type = int; + default = 722; + }; + authentik-redis = mkOption { + type = int; + default = 723; + }; + }; + }; + + config = mkIf cfg.enable { + systemd = { + tmpfiles.rules = [ + "d ${cfg.state-directory}/postgres 0700 authentik-postgres root - -" + "d ${cfg.state-directory}/redis 0700 authentik-redis root - -" + "d ${cfg.state-directory}/media 0700 authentik root - -" + "d ${cfg.state-directory}/templates 0700 authentik root - -" + "d ${cfg.state-directory}/certs 0700 authentik root - -" + ]; + services.arion-authentik = { + after = [ "network-online.target" ]; + requires = [ "network-online.target" ]; + }; + }; + + users.users = { + authentik = { + isSystemUser = true; + group = "authentik"; + uid = cfg.uids.authentik; + }; + authentik-postgres = { + isSystemUser = true; + group = "authentik"; + uid = cfg.uids.authentik-postgres; + }; + authentik-redis = { + isSystemUser = true; + group = "authentik"; + uid = cfg.uids.authentik-redis; + }; + }; + + fudo.secrets.host-secrets."${hostname}" = { + authentikEnv = { + source-file = mkEnvFile { + AUTHENTIK_REDIS__HOST = "redis"; + AUTHENTIK_POSTGRESQL__HOST = "postgres"; + AUTHENTIK_POSTGRESQL__NAME = "authentik"; + AUTHENTIK_POSTGRESQL__USER = "authentik"; + AUTHENTIK_POSTGRESQL__PASSWORD = readFile postgresPasswdFile; + }; + target-file = "/run/authentik/authentik.env"; + }; + authentikPostgresEnv = { + source-file = mkEnvFile { + POSTGRES_DB = "authentik"; + POSTGRES_USER = "authentik"; + POSTGRES_PASSWORD = readFile postgresPasswdFile; + }; + target-file = "/run/authentik/postgres.env"; + }; + }; + + virtualisation.arion.projects.authentik.settings = let + image = { ... }: { + project.name = "authentik"; + services = { + postgres = { + image = cfg.images.postgres; + restart = "always"; + volumes = + [ "${cfg.state-directory}/postgres:/var/lib/postgresql/data" ]; + healthcheck = { + test = [ "CMD" "pg_isready" "-U" "postgres" ]; + start_period = "20s"; + interval = "30s"; + retries = "5"; + timeout = "3s"; + }; + user = mkUserMap cfg.uids.postgres; + env_file = [ hostSecrets.authentikPostgresEnv.target-file ]; + }; + redis = { + image = cfg.images.redis; + restart = "always"; + command = "--save 60 1 --loglevel warning"; + volumes = [ "${cfg.state-directory}:/data" ]; + healthcheck = { + test = [ "CMD" "redis-cli" "ping" ]; + start_period = "20s"; + interval = "30s"; + retries = "5"; + timeout = "3s"; + }; + user = mkUserMap cfg.uids.redis; + }; + server = { + image = cfg.images.authentik; + restart = "always"; + command = "server"; + env_file = [ hostSecrets.authentikEnv.target-file ]; + volumes = [ + "${cfg.state-directory}/media:/media" + "${cfg.state-directory}/templates:/templates" + ]; + user = mkUserMap cfg.uids.authentik; + ports = [ + "${toString cfg.ports.http}:9000" + "${toString cfg.ports.https}:9443" + ]; + depends_on = [ "postgresql" "redis" ]; + }; + worker = { + image = cfg.images.authentik; + restart = "always"; + command = "worker"; + env_file = [ hostSecrets.authentikEnv.target-file ]; + volumes = [ + "${cfg.state-directory}/media:/media" + "${cfg.state-directory}/certs:/certs" + "${cfg.state-directory}/templates:/templates" + ]; + user = mkUserMap cfg.uids.authentik; + depends_on = [ "postgresql" "redis" ]; + }; + }; + }; + in { imports = [ image ]; }; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..0054c64 --- /dev/null +++ b/flake.lock @@ -0,0 +1,233 @@ +{ + "nodes": { + "arion": { + "inputs": { + "flake-parts": "flake-parts", + "haskell-flake": "haskell-flake", + "hercules-ci-effects": "hercules-ci-effects", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1692787336, + "narHash": "sha256-WabgeYsUiMRbpb1bCT3oY6GJEciZQIf3tYD8RQAUf2c=", + "owner": "hercules-ci", + "repo": "arion", + "rev": "28902d348807c494115177595f812a3e54cc913b", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "arion", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "arion", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1675933616, + "narHash": "sha256-/rczJkJHtx16IFxMmAWu5nNYcSXNg1YYXTHoGjLrLUA=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "47478a4a003e745402acf63be7f9a092d51b83d7", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1688466019, + "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec", + "type": "github" + }, + "original": { + "id": "flake-parts", + "type": "indirect" + } + }, + "flake-parts_3": { + "inputs": { + "nixpkgs-lib": [ + "arion", + "hercules-ci-effects", + "hercules-ci-agent", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688466019, + "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "haskell-flake": { + "locked": { + "lastModified": 1675296942, + "narHash": "sha256-u1X1sblozi5qYEcLp1hxcyo8FfDHnRUVX3dJ/tW19jY=", + "owner": "srid", + "repo": "haskell-flake", + "rev": "c2cafce9d57bfca41794dc3b99c593155006c71e", + "type": "github" + }, + "original": { + "owner": "srid", + "ref": "0.1.0", + "repo": "haskell-flake", + "type": "github" + } + }, + "haskell-flake_2": { + "locked": { + "lastModified": 1684780604, + "narHash": "sha256-2uMZsewmRn7rRtAnnQNw1lj0uZBMh4m6Cs/7dV5YF08=", + "owner": "srid", + "repo": "haskell-flake", + "rev": "74210fa80a49f1b6f67223debdbf1494596ff9f2", + "type": "github" + }, + "original": { + "owner": "srid", + "ref": "0.3.0", + "repo": "haskell-flake", + "type": "github" + } + }, + "hercules-ci-agent": { + "inputs": { + "flake-parts": "flake-parts_3", + "haskell-flake": "haskell-flake_2", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1688568579, + "narHash": "sha256-ON0M56wtY/TIIGPkXDlJboAmuYwc73Hi8X9iJGtxOhM=", + "owner": "hercules-ci", + "repo": "hercules-ci-agent", + "rev": "367dd8cd649b57009a6502e878005a1e54ad78c5", + "type": "github" + }, + "original": { + "id": "hercules-ci-agent", + "type": "indirect" + } + }, + "hercules-ci-effects": { + "inputs": { + "flake-parts": "flake-parts_2", + "hercules-ci-agent": "hercules-ci-agent", + "nixpkgs": [ + "arion", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1689397210, + "narHash": "sha256-fVxZnqxMbsDkB4GzGAs/B41K0wt/e+B/fLxmTFF/S20=", + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "rev": "0a63bfa3f00a3775ea3a6722b247880f1ffe91ce", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1688322751, + "narHash": "sha256-eW62dC5f33oKZL7VWlomttbUnOTHrAbte9yNUNW8rbk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0fbe93c5a7cac99f90b60bdf5f149383daaa615f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1688049487, + "narHash": "sha256-100g4iaKC9MalDjUW9iN6Jl/OocTDtXdeAj7pEGIRh4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4bc72cae107788bf3f24f30db2e2f685c9298dc9", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1676300157, + "narHash": "sha256-1HjRzfp6LOLfcj/HJHdVKWAkX9QRAouoh6AjzJiIerU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "545c7a31e5dedea4a6d372712a18e00ce097d462", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1693183237, + "narHash": "sha256-c7OtyBkZ/vZE/WosBpRGRtkbWZjDHGJP7fg1FyB9Dsc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ea5234e7073d5f44728c499192544a84244bf35a", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-23.05", + "type": "indirect" + } + }, + "root": { + "inputs": { + "arion": "arion", + "nixpkgs": "nixpkgs_3" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..8a1e9e2 --- /dev/null +++ b/flake.nix @@ -0,0 +1,17 @@ +{ + description = "Authentik running in a container"; + + inputs = { + nixpkgs.url = "nixpkgs/nixos-23.05"; + arion.url = "github:hercules-ci/arion"; + }; + + outputs = { self, nixpkgs, arion, ... }: { + nixosModules = rec { + default = authentikContainer; + authentikContainer = { ... }: { + imports = [ arion.nixosModules.arion ./authentik-container.nix ]; + }; + }; + }; +}