{ lib, python3, nebula, runCommand, writeShellApplication, ... }: let pythonEnv = python3.withPackages ( ps: with ps; [ fastapi uvicorn httpx qrcode pillow # qrcode SVG path image factory dependency jinja2 python-multipart # needed for FastAPI Form() parsing ] ); # Install the app source as a proper Python package so uvicorn can import it. appPkg = runCommand "nebula-ui-app" { } '' pkgdir=$out/lib/python${python3.pythonVersion}/site-packages/nebula_ui mkdir -p "$pkgdir" cp ${./app.py} "$pkgdir/__init__.py" cp -r ${./templates} "$pkgdir/templates" ''; in writeShellApplication { name = "nebula-ui"; runtimeInputs = [ pythonEnv nebula # provides nebula-cert on PATH ]; text = '' export PYTHONPATH="${appPkg}/lib/python${python3.pythonVersion}/site-packages''${PYTHONPATH:+:$PYTHONPATH}" exec uvicorn nebula_ui:app \ --host "''${NEBULA_UI_LISTEN_HOST:-127.0.0.1}" \ --port "''${NEBULA_UI_LISTEN_PORT:-8473}" ''; meta = { description = "Web UI for managing a Nebula overlay network — stats, cert signing, QR codes"; mainProgram = "nebula-ui"; license = lib.licenses.mit; platforms = lib.platforms.linux; }; }