{ config, lib, pkgs, sources, ... }: let inherit (lib) mapAttrsToList optionals; host = "vote.dgnum.eu"; port = 9888; python3 = let nix-pkgs = import sources.nix-pkgs { inherit pkgs; }; in pkgs.python3.override { packageOverrides = _: _: { inherit (nix-pkgs) authens django-background-tasks django-browser-reload django-bulma-forms django-translated-fields loadcredential ; }; }; pythonEnv = { debug ? false, }: python3.withPackages ( ps: [ ps.django ps.gunicorn ps.markdown ps.numpy ps.networkx ps.psycopg ps.authens ps.django-background-tasks ps.django-bulma-forms ps.django-translated-fields ps.loadcredential ] ++ (optionals debug [ ps.django-browser-reload ps.django-debug-toolbar ]) ); manage = pkgs.writeShellApplication { name = "kadenios-manage"; runtimeInputs = path ++ [ config.systemd.package pkgs.util-linux ]; text = '' MainPID=$(systemctl show -p MainPID --value django-kadenios.service) nsenter -e -a -t "$MainPID" -G follow -S follow python ${sources.kadenios}/manage.py "$@" ''; }; staticDrv = pkgs.stdenv.mkDerivation { name = "kadenios-static"; src = sources.kadenios; nativeBuildInputs = [ (pythonEnv { debug = true; }) ]; configurePhase = '' export KADENIOS_STATIC_ROOT=$out/static export KADENIOS_DEBUG=true export CREDENTIALS_DIRECTORY=$(pwd)/.credentials ''; doBuild = false; installPhase = '' mkdir -p $out/static python3 manage.py collectstatic ''; }; environment = builtins.mapAttrs (_: builtins.toJSON) { KADENIOS_ALLOWED_HOSTS = [ "vote.dgnum.eu" ]; KADENIOS_STATIC_ROOT = staticDrv; KADENIOS_DATABASES = { default = { ENGINE = "django.db.backends.postgresql"; NAME = "kadenios"; }; }; KADENIOS_EMAIL_HOST_USER = "web-services@infra.dgnum.eu"; KADENIOS_EMAIL_USE_SSL = true; KADENIOS_FROM_EMAIL = "Kadenios "; KADENIOS_SERVER_EMAIL = "kadenios@infra.dgnum.eu"; }; path = [ (pythonEnv { }) ]; in { environment.systemPackages = [ manage ]; systemd.services = { django-kadenios = { description = "ENS simple voting server"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" "postgresql.service" ]; serviceConfig = { DynamicUser = true; LoadCredential = mapAttrsToList (name: value: "${name}:${value}") { SECRET_KEY = config.age.secrets."kadenios-secret_key_file".path; EMAIL_HOST_PASSWORD = config.age.secrets."kadenios-email_password_file".path; }; StateDirectory = "django-kadenios"; User = "kadenios"; }; inherit environment path; script = '' python3 ${sources.kadenios}/manage.py migrate gunicorn app.wsgi --pythonpath ${sources.kadenios} -b 127.0.0.1:${builtins.toString port} --workers=2 --threads=4 ''; }; django-kadenios-tasks = { description = "Background tasks worker for Kadenios"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" "postgresql.service" "django-kadenios.service" ]; serviceConfig = { DynamicUser = true; LoadCredential = mapAttrsToList (name: value: "${name}:${value}") { SECRET_KEY = config.age.secrets."kadenios-secret_key_file".path; EMAIL_HOST_PASSWORD = config.age.secrets."kadenios-email_password_file".path; }; StateDirectory = "django-kadenios"; User = "kadenios"; WorkingDirectory = sources.kadenios; }; inherit environment path; script = '' python3 manage.py process_tasks ''; }; }; dgn-web.simpleProxies.kadenios = { inherit host port; vhostConfig.locations."/static/".root = staticDrv; }; services.postgresql = { ensureDatabases = [ "kadenios" ]; ensureUsers = [ { name = "kadenios"; ensureDBOwnership = true; } ]; }; }