Files

121 lines
3.7 KiB
Nix

{
config,
pkgs,
...
}: let
serviceName = "netbox";
servicePort = config.m3ta.ports.get serviceName;
staticPort = config.m3ta.ports.get "netbox-static";
hostName = "nb.l.az-gruppe.com";
staticRoot = "${config.services.netbox.dataDir}/static";
# nixpkgs >= 25.11: Plugin-Pakete liegen im passthru-Set netbox.plugins
# (python3Packages.netbox-* sind Throw-Stubs); pluginName = NetBox-Modulname
netboxPlugins = with pkgs.unstable.netbox.plugins; [
netbox-dns
netbox-qrcode
netbox-routing
netbox-topology-views
netbox-floorplan-plugin
];
in {
services.netbox = {
enable = true;
package = pkgs.unstable.netbox;
listenAddress = "127.0.0.1";
port = servicePort;
secretKeyFile = config.age.secrets.netbox-secret-key.path;
apiTokenPeppersFile = config.age.secrets.netbox-api-token-pepper.path;
settings = {
ALLOWED_HOSTS = [hostName "localhost" "127.0.0.1"];
SECURE_SSL_REDIRECT = true;
SESSION_COOKIE_SECURE = true;
CSRF_COOKIE_SECURE = true;
# NetBox aktiviert Plugins erst über PLUGINS in configuration.py —
# der NixOS-NetBox-Modul trägt sie NICHT automatisch ein.
PLUGINS = map (p: p.pluginName) netboxPlugins;
};
# installiert die Pakete in NetBox' Python-Environment (extraBuildInputs)
plugins = _: netboxPlugins;
extraConfig = ''
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
'';
};
# Der Upgrade-Guard im NetBox-Modul (preStart) vergleicht /var/lib/netbox/version
# nur mit dem BASISPAKET (services.netbox.package). Reine Config-/Plugin-
# Änderungen bei gleicher NetBox-Version überspringen damit migrate +
# collectstatic → Plugin-Tabellen fehlen ("database migration missing").
# Deshalb Migrationen/Statics hier VOR jedem netbox.service-Start ausführen
# (idempotent, entspricht dem offiziellen NetBox-Upgrade-Pfad):
systemd.services.netbox = {
wants = ["netbox-migrate.service"];
after = ["netbox-migrate.service"];
};
systemd.services.netbox-migrate = {
description = "NetBox: DB-Migrationen & Statics (v. a. Plugins)";
wants = ["network-online.target"];
after = ["network-online.target" "postgresql.service" "redis-netbox.service"];
serviceConfig = {
Type = "oneshot";
User = "netbox";
Group = "netbox";
StateDirectory = "netbox";
TimeoutStartSec = "10min";
};
script = ''
/run/current-system/sw/bin/netbox-manage migrate --no-input
/run/current-system/sw/bin/netbox-manage collectstatic --no-input
'';
};
services.nginx = {
enable = true;
virtualHosts.netbox-static = {
listen = [
{
addr = "127.0.0.1";
port = staticPort;
}
];
locations."/static/" = {
alias = "${staticRoot}/";
extraConfig = ''
expires 1h;
access_log off;
'';
};
};
};
users.users.nginx.extraGroups = ["netbox"];
# Traefik-Routing: zwei Backends (App + Static), ein Host
services.traefik.dynamicConfigOptions.http = {
services = {
${serviceName}.loadBalancer.servers = [
{url = "http://127.0.0.1:${toString servicePort}/";}
];
"${serviceName}-static".loadBalancer.servers = [
{url = "http://127.0.0.1:${toString staticPort}/";}
];
};
routers = {
${serviceName} = {
rule = "Host(`${hostName}`) && !PathPrefix(`/static`)";
tls.certResolver = "ionos";
service = serviceName;
entrypoints = "websecure";
};
"${serviceName}-static" = {
rule = "Host(`${hostName}`) && PathPrefix(`/static`)";
tls.certResolver = "ionos";
service = "${serviceName}-static";
entrypoints = "websecure";
};
};
};
}