From b80563f0ed328e27c4475e203c68ca53bfd56045 Mon Sep 17 00:00:00 2001 From: pazpi Date: Mon, 15 Jul 2024 23:03:00 +0200 Subject: [PATCH] Prove --- lxc-nix | 1 - lxc-nix/buildLxcImage.sh | 12 ++ lxc-nix/configuration.nix | 131 +++++++++++++ lxc-nix/modules/qbittorrent.nix | 126 ++++++++++++ lxc-nix/modules/rutorrent.nix | 325 +++++++++++++++++++++++++++++++ lxc-nix/packages/rutorrent.nix | 27 +++ lxc-nix/parameters.nix | 10 + lxc-nix/services/networking.nix | 26 +++ lxc-nix/services/qbittorrent.nix | 29 +++ lxc-nix/services/rutorrent.nix | 69 +++++++ 10 files changed, 755 insertions(+), 1 deletion(-) delete mode 160000 lxc-nix create mode 100755 lxc-nix/buildLxcImage.sh create mode 100644 lxc-nix/configuration.nix create mode 100644 lxc-nix/modules/qbittorrent.nix create mode 100644 lxc-nix/modules/rutorrent.nix create mode 100644 lxc-nix/packages/rutorrent.nix create mode 100644 lxc-nix/parameters.nix create mode 100644 lxc-nix/services/networking.nix create mode 100644 lxc-nix/services/qbittorrent.nix create mode 100644 lxc-nix/services/rutorrent.nix diff --git a/lxc-nix b/lxc-nix deleted file mode 160000 index 171675d..0000000 --- a/lxc-nix +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 171675dae9dd0e673416badf01ef4cc1ee33c96c diff --git a/lxc-nix/buildLxcImage.sh b/lxc-nix/buildLxcImage.sh new file mode 100755 index 0000000..c4a3e46 --- /dev/null +++ b/lxc-nix/buildLxcImage.sh @@ -0,0 +1,12 @@ +#! /usr/bin/env nix-shell +#! nix-shell -p nixos-generators +#! nix-shell -i bash +set -xe + +CONFIGURATIONNIX=$1 +METAIMG=$(nixos-generate -f lxc-metadata) +# IMG_PROXMOX=`nixos-generate -c ${CONFIGURATIONNIX} -f proxmox-lxc` +IMG=$(nixos-generate -c "${CONFIGURATIONNIX}" -f lxc) + +lxc image delete nixos || echo true +lxc image import --alias nixos "${METAIMG}" "${IMG}" diff --git a/lxc-nix/configuration.nix b/lxc-nix/configuration.nix new file mode 100644 index 0000000..c37a4c3 --- /dev/null +++ b/lxc-nix/configuration.nix @@ -0,0 +1,131 @@ +{ config, pkgs, ... }: + +let + + parameters = import ./parameters.nix { }; + + # GID = 888; + # user = "rtorrent"; + # passwordHash = "$y$j9T$dA94KVg1/jYLqclQQbTDk.$cnfxBWUN8P4shr8Kkipv5bU/RCtQNoAwYFDZ0X/BYs5"; + + timeZone = "Europe/Rome"; + defaultLocale = "en_US.UTF-8"; +in +{ + imports = [ + + # Need to load some defaults for running in an lxc container. + # This is explained in: + # https://github.com/nix-community/nixos-generators/issues/79 + # "${modulesPath}/virtualisation/lxc-container.nix" + + # ./modules/qbittorrent.nix + #./modules/rutorrent.nix + + # ./services/qbittorrent.nix + #./services/rutorrent.nix + ./services/networking.nix + ]; + + # This doesn't do _everything_ we need, because `boot.isContainer` is + # specifically talking about light-weight NixOS containers, not LXC. But it + # does at least gives us something to start with. + boot.isContainer = true; + + networking = { + hostName = parameters.containerName; + }; + + nixpkgs.config.allowUnfree = true; + + # Extra packages + # environment.systemPackages = with pkgs; [ ]; + + services = { + openssh.enable = true; + tailscale = { + enable = false; + useRoutingFeatures = "both"; + extraUpFlags = [ "--exit-node=${parameters.tailscaleExitNodeIP}" ]; + authKeyFile = builtins.toFile "authKey" ''${parameters.tailscaleAuthKey}''; + }; + }; + + time.timeZone = parameters.timeZone; + + i18n = { + defaultLocale = defaultLocale; + extraLocaleSettings = { + LC_ADDRESS = defaultLocale; + LC_IDENTIFICATION = defaultLocale; + LC_MEASUREMENT = defaultLocale; + LC_MONETARY = defaultLocale; + LC_NAME = defaultLocale; + LC_PAPER = defaultLocale; + LC_TELEPHONE = defaultLocale; + # LC_NUMERIC = defaultLocale; + # LC_TIME = defaultLocale; + }; + }; + + users = { + + # If set to false, the contents of the user and group files will simply + # be replaced on system activation. + # This also holds for the user passwords. + # All changed passwords will be reset according + # to the `users.users` configuration on activation. + mutableUsers = false; + + users.root = { + hashedPassword = "$6$gir1YD6tNdC9xAj0$zLr1yt/ea9PvwygjHfQVnPmeCd1.2zrAKWiN80duidwOkZF6hwm06ta6J3O9uw6F3uUHC0N7iiKYhCgXXR.Q7/"; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDhiGLc/whCY3lCmDiRlYnMJOLiO/gvcRj/sKVEFVAhQ pazpi@deadbeef" + ]; + }; + + users.pazpi = { + isNormalUser = true; + shell = pkgs.bash; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDhiGLc/whCY3lCmDiRlYnMJOLiO/gvcRj/sKVEFVAhQ pazpi@deadbeef" + ]; + }; + + # groups = { + # qbittorrent = { gid = GID; }; + # }; + + # users."${user}" = { + # isNormalUser = true; + # group = "qbittorrent"; + # extraGroups = [ "user" "multimedia" ]; + # # initialHashedPassword = passwordHash; + # }; + }; + + # # Enable passwordless sudo. + # security.sudo.extraRules = [ + # { + # users = [ user ]; + # commands = [ + # { + # command = "ALL"; + # options = [ "NOPASSWD" ]; + # } + # ]; + # } + # ]; + + # Supress systemd units that don't work because of LXC. + # https://blog.xirion.net/posts/nixos-proxmox-lxc/#configurationnix-tweak + systemd.suppressedSystemUnits = [ + "dev-mqueue.mount" + "sys-kernel-debug.mount" + "sys-fs-fuse-connections.mount" + ]; + + nix.settings.experimental-features = [ "nix-command" "flakes" ]; + + system.stateVersion = "24.05"; +} diff --git a/lxc-nix/modules/qbittorrent.nix b/lxc-nix/modules/qbittorrent.nix new file mode 100644 index 0000000..b319c9b --- /dev/null +++ b/lxc-nix/modules/qbittorrent.nix @@ -0,0 +1,126 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.qbittorrent; + UID = 888; + GID = 888; +in +{ + options.services.qbittorrent = { + enable = mkEnableOption (lib.mdDoc "qBittorrent headless"); + + dataDir = mkOption { + type = types.path; + default = "/var/lib/qbittorrent"; + description = lib.mdDoc '' + The directory where qBittorrent stores its data files. + ''; + }; + + user = mkOption { + type = types.str; + default = "qbittorrent"; + description = lib.mdDoc '' + User account under which qBittorrent runs. + ''; + }; + + group = mkOption { + type = types.str; + default = "qbittorrent"; + description = lib.mdDoc '' + Group under which qBittorrent runs. + ''; + }; + + port = mkOption { + type = types.port; + default = 8080; + description = lib.mdDoc '' + qBittorrent web UI port. + ''; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + Open services.qBittorrent.port to the outside network. + ''; + }; + + package = mkOption { + type = types.package; + default = pkgs.qbittorrent-nox; + defaultText = literalExpression "pkgs.qbittorrent-nox"; + description = lib.mdDoc '' + The qbittorrent package to use. + ''; + }; + }; + + config = mkIf cfg.enable { + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = [ cfg.port ]; + }; + + systemd.services.qbittorrent = { + # based on the plex.nix service module and + # https://github.com/qbittorrent/qBittorrent/blob/master/dist/unix/systemd/qbittorrent-nox%40.service.in + description = "qBittorrent-nox service"; + documentation = [ "man:qbittorrent-nox(1)" ]; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Type = "simple"; + User = cfg.user; + Group = cfg.group; + + # Run the pre-start script with full permissions (the "!" prefix) so it + # can create the data directory if necessary. + ExecStartPre = + let + preStartScript = pkgs.writeScript "qbittorrent-run-prestart" '' + #!${pkgs.bash}/bin/bash + + # Create data directory if it doesn't exist + if ! test -d "$QBT_PROFILE"; then + echo "Creating initial qBittorrent data directory in: $QBT_PROFILE" + install -d -m 0755 -o "${cfg.user}" -g "${cfg.group}" "$QBT_PROFILE" + fi + ''; + in + "!${preStartScript}"; + + #ExecStart = "${pkgs.qbittorrent-nox}/bin/qbittorrent-nox"; + ExecStart = "${cfg.package}/bin/qbittorrent-nox"; + # To prevent "Quit & shutdown daemon" from working; we want systemd to + # manage it! + #Restart = "on-success"; + #UMask = "0002"; + #LimitNOFILE = cfg.openFilesLimit; + }; + + environment = { + QBT_PROFILE = cfg.dataDir; + QBT_WEBUI_PORT = toString cfg.port; + QBT_EULA = "accept"; + # QBT_EULA = toString cfg.acceptEula; + }; + }; + + # users.users = mkIf (cfg.user == "qbittorrent") { + # qbittorrent = { + # group = cfg.group; + # uid = UID; + # }; + # }; + + # users.groups = mkIf (cfg.group == "qbittorrent") { + # qbittorrent = { gid = GID; }; + # }; + }; +} diff --git a/lxc-nix/modules/rutorrent.nix b/lxc-nix/modules/rutorrent.nix new file mode 100644 index 0000000..54eaab5 --- /dev/null +++ b/lxc-nix/modules/rutorrent.nix @@ -0,0 +1,325 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.rutorrent; + + rutorrentPkgs = import ../packages/rutorrent.nix { inherit pkgs; inherit lib; }; + + rtorrentPluginDependencies = with pkgs; { + _task = [ procps ]; + unpack = [ unzip unrar ]; + rss = [ curl ]; + mediainfo = [ mediainfo ]; + spectrogram = [ sox ]; + screenshots = [ ffmpeg ]; + }; + + phpPluginDependencies = with pkgs; { + _cloudflare = [ python3 ]; + }; + + getPluginDependencies = dependencies: concatMap (p: attrByPath [ p ] [ ] dependencies); + +in +{ + options = { + services.rutorrent = { + enable = mkEnableOption "ruTorrent"; + + hostName = mkOption { + type = types.str; + description = "FQDN for the ruTorrent instance."; + }; + + dataDir = mkOption { + type = types.str; + default = "/var/lib/rutorrent"; + description = "Storage path of ruTorrent."; + }; + + user = mkOption { + type = types.str; + default = "rutorrent"; + description = '' + User which runs the ruTorrent service. + ''; + }; + + group = mkOption { + type = types.str; + default = "rutorrent"; + description = '' + Group which runs the ruTorrent service. + ''; + }; + + rpcSocket = mkOption { + type = types.str; + default = config.services.rtorrent.rpcSocket; + defaultText = "config.services.rtorrent.rpcSocket"; + description = '' + Path to rtorrent rpc socket. + ''; + }; + + plugins = mkOption { + type = with types; listOf (either str package); + default = [ "httprpc" ]; + example = literalExample ''[ "httprpc" "data" "diskspace" "edit" "erasedata" "theme" "trafic" ]''; + description = '' + List of plugins to enable. See the list of available plugins. Note: the unpack plugin needs the nonfree unrar package. + You need to either enable one of the rpc or httprpc plugin or enable the option. + ''; + }; + + poolSettings = mkOption { + type = with types; attrsOf (oneOf [ str int bool ]); + default = { + "pm" = "dynamic"; + "pm.max_children" = 32; + "pm.start_servers" = 2; + "pm.min_spare_servers" = 2; + "pm.max_spare_servers" = 4; + "pm.max_requests" = 500; + }; + description = '' + Options for ruTorrent's PHP pool. See the documentation on php-fpm.conf for details on configuration directives. + ''; + }; + + nginx = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable nginx virtual host management. + Further nginx configuration can be done by adapting services.nginx.virtualHosts.<name>. + See for further information. + ''; + }; + + exposeInsecureRPC2mount = mkOption { + type = types.bool; + default = false; + description = '' + If you do not enable one of the rpc or httprpc plugins you need to expose an RPC mount through scgi using this option. + Warning: This allow to run arbitrary commands, as the rtorrent user, so make sure to use authentification. The simplest way would be to use the services.nginx.virtualHosts.<name>.basicAuth option. + ''; + }; + }; + }; + }; + + config = mkIf cfg.enable (mkMerge [ + { + assertions = + let + usedRpcPlugins = intersectLists cfg.plugins [ "httprpc" "rpc" ]; + in + [ + { + assertion = (length usedRpcPlugins < 2); + message = "Please specify only one of httprpc or rpc plugins"; + } + { + assertion = !(length usedRpcPlugins > 0 && cfg.nginx.exposeInsecureRPC2mount); + message = "Please do not use exposeInsecureRPC2mount if you use one of httprpc or rpc plugins"; + } + ]; + + warnings = + let + nginxVhostCfg = config.services.nginx.virtualHosts."${cfg.hostName}"; + in + [ ] + ++ (optional (cfg.nginx.exposeInsecureRPC2mount && (nginxVhostCfg.basicAuth == { } || nginxVhostCfg.basicAuthFile == null)) '' + You are using exposeInsecureRPC2mount without using basic auth on the virtual host. The exposed rpc mount allow for remote command execution. + + Please make sure it is not accessible from the outside. + ''); + + systemd = { + services = { + rtorrent.path = getPluginDependencies rtorrentPluginDependencies cfg.plugins; + rutorrent-setup = + let + rutorrentConfig = pkgs.writeText "rutorrent-config.php" '' + false, + 'proto' => 'http', // 'http' or 'https' + 'host' => 'PROXY_HOST_HERE', + 'port' => 3128 + ); + + @define('RPC_TIME_OUT', 5, true); // in seconds + + @define('LOG_RPC_CALLS', false, true); + @define('LOG_RPC_FAULTS', true, true); + + // for php + @define('PHP_USE_GZIP', false, true); + @define('PHP_GZIP_LEVEL', 2, true); + + $schedule_rand = 10; // rand for schedulers start, +0..X seconds + + $do_diagnostic = true; + $log_file = '${cfg.dataDir}/logs/errors.log'; // path to log file (comment or leave blank to disable logging) + + $saveUploadedTorrents = true; // Save uploaded torrents to profile/torrents directory or not + $overwriteUploadedTorrents = false; // Overwrite existing uploaded torrents in profile/torrents directory or make unique name + + $topDirectory = '/'; // Upper available directory. Absolute path with trail slash. + $forbidUserSettings = false; + + $scgi_port = 0; + $scgi_host = "unix://${cfg.rpcSocket}"; + + $XMLRPCMountPoint = "/RPC2"; // DO NOT DELETE THIS LINE!!! DO NOT COMMENT THIS LINE!!! + + $pathToExternals = array( + "php" => "${pkgs.php}/bin/php", // Something like /usr/bin/php. If empty, will be found in PATH. + "curl" => "${pkgs.curl}/bin/curl", // Something like /usr/bin/curl. If empty, will be found in PATH. + "gzip" => "${pkgs.gzip}/bin/gzip", // Something like /usr/bin/gzip. If empty, will be found in PATH. + "id" => "${pkgs.coreutils}/bin/id", // Something like /usr/bin/id. If empty, will be found in PATH. + "stat" => "${pkgs.coreutils}/bin/stat", // Something like /usr/bin/stat. If empty, will be found in PATH. + "pgrep" => "${pkgs.procps}/bin/pgrep", // TODO why can't we use phpEnv.PATH + ); + + $localhosts = array( // list of local interfaces + "127.0.0.1", + "localhost", + ); + + $profilePath = '${cfg.dataDir}/share'; // Path to user profiles + $profileMask = 0770; // Mask for files and directory creation in user profiles. + // Both Webserver and rtorrent users must have read-write access to it. + // For example, if Webserver and rtorrent users are in the same group then the value may be 0770. + + $tempDirectory = null; // Temp directory. Absolute path with trail slash. If null, then autodetect will be used. + + $canUseXSendFile = false; // If true then use X-Sendfile feature if it exist + + $locale = "UTF8"; + + $throttleMaxSpeed = 327625*1024; + ''; + in + { + wantedBy = [ "multi-user.target" ]; + before = [ "phpfpm-rutorrent.service" ]; + script = '' + ln -sf ${rutorrentPkgs}/{css,images,js,lang,index.html} ${cfg.dataDir}/ + mkdir -p ${cfg.dataDir}/{conf,logs,plugins} ${cfg.dataDir}/share/{settings,torrents,users} + ln -sf ${rutorrentPkgs}/conf/{access.ini,plugins.ini} ${cfg.dataDir}/conf/ + ln -sf ${rutorrentConfig} ${cfg.dataDir}/conf/config.php + + cp -r ${rutorrentPkgs}/php ${cfg.dataDir}/ + + ${optionalString (cfg.plugins != []) + ''cp -r ${concatMapStringsSep " " (p: "${rutorrentPkgs}/plugins/${p}") cfg.plugins} ${cfg.dataDir}/plugins/''} + + chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}/{conf,share,logs,plugins} + chmod -R 755 ${cfg.dataDir}/{conf,share,logs,plugins} + ''; + serviceConfig.Type = "oneshot"; + }; + }; + + tmpfiles.rules = [ "d '${cfg.dataDir}' 0775 ${cfg.user} ${cfg.group} -" ]; + }; + + users.groups."${cfg.group}" = { }; + + users.users = { + "${cfg.user}" = { + home = cfg.dataDir; + group = cfg.group; + extraGroups = [ config.services.rtorrent.group ]; + description = "ruTorrent Daemon user"; + isSystemUser = true; + }; + + "${config.services.rtorrent.user}" = { + extraGroups = [ cfg.group ]; + }; + }; + } + + (mkIf cfg.nginx.enable (mkMerge [ + { + + networking.firewall = { + allowedTCPPorts = [ 80 443 ]; + }; + + services = { + + nginx = { + enable = true; + user = cfg.user; + group = cfg.group; + virtualHosts = { + ${cfg.hostName} = { + root = cfg.dataDir; + locations = { + "~ [^/]\.php(/|$)" = { + extraConfig = '' + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + if (!-f $document_root$fastcgi_script_name) { + return 404; + } + + # Mitigate https://httpoxy.org/ vulnerabilities + fastcgi_param HTTP_PROXY ""; + + fastcgi_pass unix:${config.services.phpfpm.pools.rutorrent.socket}; + fastcgi_index index.php; + + include ${pkgs.nginx}/conf/fastcgi.conf; + ''; + }; + }; + }; + }; + }; + + phpfpm.pools.rutorrent = + let + envPath = lib.makeBinPath (getPluginDependencies phpPluginDependencies cfg.plugins); + pool = { + user = cfg.user; + group = config.services.rtorrent.group; + settings = mapAttrs (name: mkDefault) + { + "listen.owner" = config.services.nginx.user; + "listen.group" = config.services.nginx.group; + } // cfg.poolSettings; + }; + in + if (envPath == "") then pool else pool // { phpEnv.PATH = envPath; }; + + }; + } + + (mkIf cfg.nginx.exposeInsecureRPC2mount { + services.nginx.virtualHosts."${cfg.hostName}".locations."/RPC2" = { + extraConfig = '' + include ${pkgs.nginx}/conf/scgi_params; + scgi_pass unix:${cfg.rpcSocket}; + ''; + }; + }) + ])) + ]); +} diff --git a/lxc-nix/packages/rutorrent.nix b/lxc-nix/packages/rutorrent.nix new file mode 100644 index 0000000..8907240 --- /dev/null +++ b/lxc-nix/packages/rutorrent.nix @@ -0,0 +1,27 @@ +{ pkgs ? import { }, lib, }: + +with pkgs; + +stdenv.mkDerivation rec { + pname = "rutorrent"; + version = "4.2.9"; + + src = fetchFromGitHub { + owner = "Novik"; + repo = "ruTorrent"; + rev = "v${version}"; + sha256 = "qgtP8IOJ5R8IWXf34MSa5WiH68oRG2j/IjGC2TPfQc0="; + }; + + installPhase = '' + mkdir -p $out/ + cp -r . $out/ + ''; + + meta = with lib; { + description = "Yet another web front-end for rTorrent"; + homepage = "https://github.com/Novik/ruTorrent"; + license = licenses.gpl3Plus; + platforms = platforms.unix; + }; +} diff --git a/lxc-nix/parameters.nix b/lxc-nix/parameters.nix new file mode 100644 index 0000000..5011ac7 --- /dev/null +++ b/lxc-nix/parameters.nix @@ -0,0 +1,10 @@ +{ ... }: +{ + containerName = "nixos-test"; # Name of the container, used for nginx virtualhost and for tailscale machine name + timeZone = "Europe/Rome"; # TimeZone + + downloadDir = "/mnt/data"; # Main download folder + + tailscaleAuthKey = "tskey-auth-kmgDY87CNTRL-urQA7eRn235t8Sjs6hW3259wJHE63Kvd"; + tailscaleExitNodeIP = "100.81.1.32"; # vps +} diff --git a/lxc-nix/services/networking.nix b/lxc-nix/services/networking.nix new file mode 100644 index 0000000..3fd223e --- /dev/null +++ b/lxc-nix/services/networking.nix @@ -0,0 +1,26 @@ +{ ... }: +{ + + networking = { + + # If you prefer DHCP + # interfaces.eth0.useDHCP = true; + + # We don't use DHCP, so we configure it statically. + interfaces.eth0.ipv4.addresses = [{ + address = "10.42.135.101"; + prefixLength = 24; + }]; + + # We can access the internet through this interface. + defaultGateway = { + address = "10.42.135.1"; + interface = "eth0"; + }; + + # Since we don't use DHCP, we need to set our own nameservers. + nameservers = [ "1.1.1.1" "1.0.0.1" ]; + + }; + +} diff --git a/lxc-nix/services/qbittorrent.nix b/lxc-nix/services/qbittorrent.nix new file mode 100644 index 0000000..36114e6 --- /dev/null +++ b/lxc-nix/services/qbittorrent.nix @@ -0,0 +1,29 @@ +# qBittorrent service activation +# +# The shell script 'fixdlperms' is also created and should be added to the +# "Run external program on finished" section with the full path: +# /run/current-system/sw/bin/fixdlperms + +{ pkgs, ... }: + +let + downloadDir = "/data/multimedia/downloads"; + fixDownloadPerms = pkgs.writeShellScriptBin "fixdlperms" '' + find ${downloadDir} -type d -exec chmod 2775 {} + + find ${downloadDir} -type f -exec chmod 0664 {} + + ''; +in +{ + services.qbittorrent = { + enable = true; + openFirewall = true; + dataDir = "/srv/qbittorrent"; + port = 58080; + user = "qbittorrent"; + }; + + # Allow qbittorrent to save files in the multimedia share + # users.users.qbittorrent.extraGroups = [ "multimedia" ]; + + environment.systemPackages = [ fixDownloadPerms ]; +} diff --git a/lxc-nix/services/rutorrent.nix b/lxc-nix/services/rutorrent.nix new file mode 100644 index 0000000..166a3f2 --- /dev/null +++ b/lxc-nix/services/rutorrent.nix @@ -0,0 +1,69 @@ +{ config, ... }: +let + parameters = import ../parameters.nix { }; +in +{ + services = { + + rtorrent = { + enable = true; + openFirewall = true; + downloadDir = parameters.downloadDir; + }; + + rutorrent = { + enable = true; + hostName = parameters.containerName; + plugins = [ + "_cloudflare" + "_getdir" + "_noty2" + "_task" + "autotools" + "check_port" + "chunks" + "cookies" + "cpuload" + # "сreate" + "data" + "datadir" + "diskspace" + "edit" + "erasedata" + "extratio" + "extsearch" + "feeds" + "filedrop" + "geoip" + "history" + "httprpc" + "ipad" + "loginmgr" + "lookat" + "mediainfo" + "ratio" + "retrackers" + "rss" + "rssurlrewrite" + "rutracker_check" + "scheduler" + "screenshots" + "seedingtime" + "show_peers_like_wtorrent" + "source" + "spectrogram" + "theme" + "throttle" + "tracklabels" + "trafic" + "unpack" + "uploadeta" + ]; + nginx = { + enable = true; + # exposeInsecureRPC2mount = true; + }; + }; + + }; +}