From 48b5f485bdf5437e168da7aa52ca51e8315100db Mon Sep 17 00:00:00 2001 From: Luana Date: Fri, 15 Nov 2024 23:53:50 -0300 Subject: [PATCH] nixos/porn-vault: init module --- .../manual/release-notes/rl-2411.section.md | 2 + nixos/modules/module-list.nix | 1 + .../web-apps/porn-vault/default-config.nix | 158 ++++++++++++++++++ .../services/web-apps/porn-vault/default.nix | 129 ++++++++++++++ 4 files changed, 290 insertions(+) create mode 100644 nixos/modules/services/web-apps/porn-vault/default-config.nix create mode 100644 nixos/modules/services/web-apps/porn-vault/default.nix diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md index 000df6e978b445..fc46f6b53e66e5 100644 --- a/nixos/doc/manual/release-notes/rl-2411.section.md +++ b/nixos/doc/manual/release-notes/rl-2411.section.md @@ -87,6 +87,8 @@ - [Goatcounter](https://www.goatcounter.com/), an easy web analytics platform with no tracking of personal data. Available as [services.goatcounter](options.html#opt-services.goatcocunter.enable). +- [Porn-Vault](https://gitlab.com/porn-vault/porn-vault), a porn organizing web app. Available as [services.porn-vault](#opt-services.porn-vault.enable). + - [Privatebin](https://github.com/PrivateBin/PrivateBin/), a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Available as [services.privatebin](#opt-services.privatebin.enable). - [UWSM](https://github.com/Vladimir-csp/uwsm), a wayland session manager to wrap Wayland compositors into useful systemd units such as `graphical-session.target`. Available as [programs.uwsm](#opt-programs.uwsm.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index eef106a91229c1..ef994f4016d6d5 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1494,6 +1494,7 @@ ./services/web-apps/pingvin-share.nix ./services/web-apps/plantuml-server.nix ./services/web-apps/plausible.nix + ./services/web-apps/porn-vault/default.nix ./services/web-apps/powerdns-admin.nix ./services/web-apps/pretalx.nix ./services/web-apps/pretix.nix diff --git a/nixos/modules/services/web-apps/porn-vault/default-config.nix b/nixos/modules/services/web-apps/porn-vault/default-config.nix new file mode 100644 index 00000000000000..a3872c7cf5c7ad --- /dev/null +++ b/nixos/modules/services/web-apps/porn-vault/default-config.nix @@ -0,0 +1,158 @@ +# See https://gitlab.com/porn-vault/porn-vault/-/blob/dev/config.example.json +{ + auth = { + password = null; + }; + binaries = { + ffmpeg = "ffmpeg"; + ffprobe = "ffprobe"; + izzyPort = 8000; + imagemagick = { + convertPath = "convert"; + montagePath = "montage"; + identifyPath = "identify"; + }; + }; + import = { + images = [ + { + path = "/media/porn-vault/images"; + include = [ ]; + exclude = [ ]; + extensions = [ + ".jpg" + ".jpeg" + ".png" + ".gif" + ]; + enable = true; + } + ]; + videos = [ + { + path = "/media/porn-vault/videos"; + include = [ ]; + exclude = [ ]; + extensions = [ + ".mp4" + ".mov" + ".webm" + ]; + enable = true; + } + ]; + scanInterval = 10800000; + }; + log = { + level = "debug"; + maxSize = "20m"; + maxFiles = "5"; + writeFile = [ + { + level = "debug"; + prefix = "errors-"; + silent = false; + } + ]; + }; + matching = { + applyActorLabels = [ + "event:actor:create" + "event:actor:find-unmatched-scenes" + "plugin:actor:create" + "event:scene:create" + "plugin:scene:create" + "event:image:create" + "plugin:marker:create" + "event:marker:create" + ]; + applySceneLabels = true; + applyStudioLabels = [ + "event:studio:create" + "event:studio:find-unmatched-scenes" + "plugin:studio:create" + "event:scene:create" + "plugin:scene:create" + ]; + extractSceneActorsFromFilepath = true; + extractSceneLabelsFromFilepath = true; + extractSceneMoviesFromFilepath = true; + extractSceneStudiosFromFilepath = true; + matcher = { + type = "word"; + options = { + ignoreSingleNames = false; + ignoreDiacritics = true; + enableWordGroups = true; + wordSeparatorFallback = true; + camelCaseWordGroups = true; + overlappingMatchPreference = "longest"; + groupSeparators = [ + "[\\s',()[\\]{}*\\.]" + ]; + wordSeparators = [ + "[-_]" + ]; + filepathSeparators = [ + "[/\\\\&]" + ]; + }; + }; + matchCreatedActors = true; + matchCreatedStudios = true; + matchCreatedLabels = true; + }; + persistence = { + backup = { + enable = true; + maxAmount = 10; + }; + libraryPath = "/media/porn-vault/lib"; + }; + plugins = { + allowActorThumbnailOverwrite = false; + allowMovieThumbnailOverwrite = false; + allowSceneThumbnailOverwrite = false; + allowStudioThumbnailOverwrite = false; + createMissingActors = false; + createMissingLabels = false; + createMissingMovies = false; + createMissingStudios = false; + events = { + actorCreated = [ ]; + actorCustom = [ ]; + sceneCreated = [ ]; + sceneCustom = [ ]; + movieCustom = [ ]; + studioCreated = [ ]; + studioCustom = [ ]; + }; + register = { }; + markerDeduplicationThreshold = 5; + }; + processing = { + generatePreviews = true; + readImagesOnImport = false; + generateImageThumbnails = true; + }; + server = { + https = { + certificate = ""; + enable = false; + key = ""; + }; + }; + transcode = { + hwaDriver = null; + vaapiDevice = "/dev/dri/renderD128"; + h264 = { + preset = "veryfast"; + crf = 23; + }; + webm = { + deadline = "realtime"; + cpuUsed = 3; + crf = 31; + }; + }; +} diff --git a/nixos/modules/services/web-apps/porn-vault/default.nix b/nixos/modules/services/web-apps/porn-vault/default.nix new file mode 100644 index 00000000000000..62645950e9d2b2 --- /dev/null +++ b/nixos/modules/services/web-apps/porn-vault/default.nix @@ -0,0 +1,129 @@ +{ + config, + pkgs, + lib, + ... +}: + +let + cfg = config.services.porn-vault; + configFormat = pkgs.formats.json { }; + defaultConfig = import ./default-config.nix; + inherit (lib) + mkIf + mkEnableOption + mkPackageOption + mkOption + getExe + literalExpression + types + ; +in +{ + options = { + services.porn-vault = { + enable = lib.mkEnableOption "Porn-Vault"; + + package = lib.mkPackageOption pkgs "porn-vault" { }; + + autoStart = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Whether to start porn-vault automatically. + ''; + }; + + port = lib.mkOption { + type = lib.types.port; + default = 3000; + description = '' + Which port Porn-Vault will use. + ''; + }; + + openFirewall = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Whether to open the Porn-Vault port in the firewall. + ''; + }; + + settings = { + enable = mkOption { + description = "Enable Porn-Vault configuration via Nix"; + default = true; + }; + + settings = mkOption { + type = configFormat.type; + description = '' + Configuration for Porn-Vault. The attributes are serialized to JSON in config.json. + + See https://gitlab.com/porn-vault/porn-vault/-/blob/dev/config.example.json + ''; + default = defaultConfig; + apply = lib.recursiveUpdate defaultConfig; + }; + }; + + configFolder = lib.mkOption { + type = lib.types.str; + default = "/etc/porn-vault"; + description = '' + Folder Porn-vault should look for its config in (logs will be stored there too), in case non-nixed configuration is wanted. Folder must be created and populated manually. + + If manually set (to anything other than "/etc/porn-vault"), configuration declared via settings.enable and settings.settings will be ignored by Porn-Vault. + ''; + }; + + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + + systemd.services.porn-vault = { + description = "Porn-Vault server"; + environment = { + PV_CONFIG_FOLDER = cfg.configFolder; + NODE_ENV = "production"; + DATABASE_NAME = "production"; + PORT = toString cfg.port; + }; + serviceConfig = { + ExecStart = getExe cfg.package; + CacheDirectory = "porn-vault"; + # Hardening options + CapabilityBoundingSet = [ "CAP_SYS_NICE" ]; + AmbientCapabilities = [ "CAP_SYS_NICE" ]; + LockPersonality = true; + NoNewPrivileges = true; + PrivateTmp = true; + ProtectControlGroups = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = true; + ReadWritePaths = cfg.configFolder; + RestrictNamespaces = true; + RestrictSUIDSGID = true; + Restart = "on-failure"; + RestartSec = 0; + }; + wantedBy = mkIf cfg.autoStart [ "multi-user.target" ]; + wants = [ "network.target" ]; + }; + + environment.etc = mkIf cfg.settings.enable { + "porn-vault/config.json".source = configFormat.generate "config.json" cfg.settings.settings; + }; + + networking.firewall = lib.mkIf cfg.openFirewall { + allowedTCPPorts = [ cfg.port ]; + }; + }; + + meta.maintainers = [ lib.maintainers.luNeder ]; +}