diff --git a/modules/chia.nix b/modules/chia.nix index 69aa086..a4531b6 100644 --- a/modules/chia.nix +++ b/modules/chia.nix @@ -34,9 +34,7 @@ in config = lib.mkIf cfg.enable { environment.systemPackages = [ ctl ]; - users.groups.chia = { - gid = config.ids.gids.chia; - }; + users.groups.chia.gid = config.ids.gids.chia; users.users.chia = { home = cfg.path; createHome = true; diff --git a/modules/ids.nix b/modules/ids.nix index 929acfc..e8d2581 100644 --- a/modules/ids.nix +++ b/modules/ids.nix @@ -7,6 +7,7 @@ unifi = 183; chia = 185; gitea = 186; + inventree = 188; ## Consistent People jake = 1000; @@ -17,6 +18,7 @@ unifi = 183; chia = 185; gitea = 186; + inventree = 188; ## Consistent Groups mediaaccess = 1200; diff --git a/modules/locations.nix b/modules/locations.nix index 3fe9db5..e5a30be 100644 --- a/modules/locations.nix +++ b/modules/locations.nix @@ -23,6 +23,7 @@ in downloads = "tywin.storage.ts.hillion.co.uk"; gitea = "boron.cx.ts.hillion.co.uk"; homeassistant = "microserver.home.ts.hillion.co.uk"; + inventree = "boron.cx.ts.hillion.co.uk"; mastodon = ""; matrix = "boron.cx.ts.hillion.co.uk"; tang = [ diff --git a/modules/services/authoritative_dns.nix b/modules/services/authoritative_dns.nix index 98b57a7..d877987 100644 --- a/modules/services/authoritative_dns.nix +++ b/modules/services/authoritative_dns.nix @@ -40,6 +40,7 @@ in restic.tywin.storage 21600 CNAME tywin.storage.ts.hillion.co.uk. sonarr.downloads 21600 CNAME tywin.storage.ts.hillion.co.uk. zigbee2mqtt.home 21600 CNAME router.home.ts.hillion.co.uk. + inventree 21600 CNAME boron.cx.ts.hillion.co.uk. '' + (makeRecords "A" config.custom.dns.authoritative.ipv4.uk.co.hillion.ts) + "\n\n" + (makeRecords "AAAA" config.custom.dns.authoritative.ipv6.uk.co.hillion.ts); }; diff --git a/modules/services/default.nix b/modules/services/default.nix index 23ab028..1464b6c 100644 --- a/modules/services/default.nix +++ b/modules/services/default.nix @@ -6,6 +6,7 @@ ./downloads.nix ./gitea/default.nix ./homeassistant.nix + ./inventree.nix ./mastodon/default.nix ./matrix.nix ./tang.nix diff --git a/modules/services/inventree.nix b/modules/services/inventree.nix new file mode 100644 index 0000000..dd9f036 --- /dev/null +++ b/modules/services/inventree.nix @@ -0,0 +1,147 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.custom.services.inventree; + + version = "0.15.8"; + staticFiles = pkgs.fetchzip { + url = "https://github.com/inventree/InvenTree/releases/download/${version}/frontend-build.zip"; + stripRoot = false; + hash = "sha256-wM0/06eLAY6faCZiHslPnQi+WOlOo3AuvGqV3rcNbso="; + }; +in +{ + options.custom.services.inventree = { + enable = lib.mkEnableOption "inventree"; + + path = lib.mkOption { + type = lib.types.str; + default = "/var/lib/inventree"; + }; + + domain = lib.mkOption { + type = lib.types.str; + default = "inventree.ts.hillion.co.uk"; + }; + + hostPort = lib.mkOption { + type = lib.types.port; + default = 4864; + }; + }; + + config = lib.mkIf cfg.enable { + users.groups.inventree.gid = config.ids.gids.inventree; + users.users.inventree = { + home = cfg.path; + createHome = true; + isSystemUser = true; + group = "inventree"; + uid = config.ids.uids.inventree; + }; + users.users.caddy.extraGroups = [ "inventree" ]; + + services.postgresql = { + enable = true; + enableTCPIP = true; + + ensureDatabases = [ "inventree" ]; + ensureUsers = [{ + name = "inventree"; + ensureClauses.login = true; + }]; + authentication = [ "hostnossl inventree inventree 10.88.0.0 255.255.0.0 scram-sha-256" ]; + }; + + systemd.tmpfiles.rules = [ "L+ ${cfg.path}/static - - - - ${staticFiles}" ]; + + services.caddy = { + enable = true; + virtualHosts.${cfg.domain}.extraConfig = '' + bind ${config.custom.dns.tailscale.ipv4} ${config.custom.dns.tailscale.ipv6} + tls { + ca https://ca.ts.hillion.co.uk:8443/acme/acme/directory + } + + encode zstd gzip + + request_body { + max_size 100MB + } + + + handle_path /static/* { + header Allow GET,HEAD,OPTIONS + header Access-Control-Allow-Origin * + header Access-Control-Allow-Methods GET,HEAD,OPTIONS + header Access-Control-Allow-Headers Authorization,Content-Type,User-Agent + + @cors_preflight{static} method OPTIONS + + handle @cors_preflight{static} { + respond "" 204 + } + + root * ${cfg.path}/static + file_server + } + + handle_path /media/* { + header Allow GET,HEAD,OPTIONS + header Access-Control-Allow-Origin * + header Access-Control-Allow-Methods GET,HEAD,OPTIONS + header Access-Control-Allow-Headers Authorization,Content-Type,User-Agent + + @cors_preflight{media} method OPTIONS + + handle @cors_preflight{media} { + respond "" 204 + } + + root * ${cfg.path}/media + file_server + + header Content-Disposition attachment + + forward_auth http://localhost:${toString cfg.hostPort} { + uri /auth/ + } + } + + reverse_proxy http://localhost:${toString cfg.hostPort} + ''; + }; + + virtualisation.oci-containers.containers.inventree = { + image = "inventree/inventree:${version}"; + + ports = [ "${toString cfg.hostPort}:8000" ]; + extraOptions = [ + "--uidmap=0:${toString config.users.users.inventree.uid}:1" + "--gidmap=0:${toString config.users.groups.inventree.gid}:1" + ]; + volumes = [ "${cfg.path}:/home/inventree/data" ]; + environment = { + INVENTREE_SITE_URL = "https://${cfg.domain}"; + + INVENTREE_DEBUG = "False"; + INVENTREE_LOG_LEVEL = "WARNING"; + + # Database setup + INVENTREE_DB_ENGINE = "postgresql"; + INVENTREE_DB_NAME = "inventree"; + INVENTREE_DB_HOST = "host.containers.internal"; + INVENTREE_DB_PORT = "5432"; + + INVENTREE_DB_USER = "inventree"; + INVENTREE_DB_PASSWORD = "inventree"; + + # Web server + INVENTREE_GUNICORN_TIMEOUT = "90"; + + # Migrations + INVENTREE_AUTO_UPDATE = "True"; + }; + }; + }; +}