From 8b6da2d7a20d3cab15140d333d0dbd64ff4ec704 Mon Sep 17 00:00:00 2001 From: Jonas Heinrich Date: Thu, 21 Aug 2025 11:04:07 +0200 Subject: [PATCH] update module --- module.nix | 60 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/module.nix b/module.nix index 7803b2c..33b863d 100644 --- a/module.nix +++ b/module.nix @@ -5,34 +5,67 @@ ... }: let - cfg = config.services.fragdenrat; - + dataDir = "/var/lib/fragdenrat"; + manageCmd = "${pkgs.fragdenrat}/bin/fragdenrat-manage"; + pythonPath = "${pkgs.fragdenrat}/share:${pkgs.fragdenrat.pythonPath}"; + envVars = [ + "PYTHONPATH=${pythonPath}" + "DJANGO_SETTINGS_MODULE=fragdenrat.settings" + "FRAGDENRAT_DATA_DIR=${dataDir}" + ]; in { - options = { services.fragdenrat = { - enable = lib.mkEnableOption "FragDenRat web app"; - }; }; config = lib.mkIf cfg.enable { + # Ensure data dir exists with proper perms + systemd.tmpfiles.rules = [ + "d ${dataDir} 0750 fragdenrat fragdenrat -" + "d ${dataDir}/staticfiles 0750 fragdenrat fragdenrat -" + ]; + + # One-shot setup: migrate DB and collect static into dataDir + systemd.services.fragdenrat-setup = { + description = "Initialize FragDenRat database and static files"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-online.target" ]; + serviceConfig = { + Type = "oneshot"; + User = "fragdenrat"; + Group = "fragdenrat"; + WorkingDirectory = dataDir; + Environment = envVars; + }; + script = '' + set -euo pipefail + ${manageCmd} migrate --noinput + ${manageCmd} collectstatic --noinput + ''; + }; + + # uWSGI app services.uwsgi = { enable = true; plugins = [ "python3" ]; - + postActivation = '' + # Ensure setup runs before uwsgi serves + ${config.systemd.package}/bin/systemctl start fragdenrat-setup.service + ''; instance = { type = "emperor"; vassals = { fragdenrat = { type = "normal"; - chdir = "${pkgs.fragdenrat}/share/fragdenrat"; + # Use data dir as working directory + chdir = dataDir; - # Absolute WSGI entrypoint + # Absolute WSGI entrypoint in Nix store wsgi-file = "${pkgs.fragdenrat}/share/fragdenrat/wsgi.py"; callable = "application"; @@ -49,15 +82,12 @@ in need-app = true; "no-orphans" = true; - env = [ - # Parent dir must be on sys.path so `import fragdenrat` resolves - "PYTHONPATH=${pkgs.fragdenrat}/share:${pkgs.fragdenrat.pythonPath}" - "DJANGO_SETTINGS_MODULE=fragdenrat.settings" - ]; + env = envVars; settings = { - "static-map" = "/static=${pkgs.fragdenrat}/share/fragdenrat/assets"; - # Mirror PYTHONPATH for uWSGI setting + # Serve collected static files from dataDir + "static-map" = "/static=${dataDir}/staticfiles"; + # Python import path for the app and its deps pythonpath = "${pkgs.fragdenrat}/share"; }; };