From badbbb7e056e9252bc7ed98958a72a32957765a4 Mon Sep 17 00:00:00 2001 From: matthewcroughan Date: Wed, 17 Mar 2021 21:27:15 +0000 Subject: [PATCH] nixos/node-red: add module Adds a basic nixos module/service for node-red based on nodePackages.node-red Co-authored-by: Aaron Andersen Co-authored-by: Sandro Co-authored by: Adrian Parvin Ouano Co-authored-by: Norbert Melzer --- nixos/modules/module-list.nix | 1 + nixos/modules/services/web-apps/node-red.nix | 148 +++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 nixos/modules/services/web-apps/node-red.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 3a1907ee201..38fcacb6ec6 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -907,6 +907,7 @@ ./services/web-apps/moodle.nix ./services/web-apps/nextcloud.nix ./services/web-apps/nexus.nix + ./services/web-apps/node-red.nix ./services/web-apps/plantuml-server.nix ./services/web-apps/pgpkeyserver-lite.nix ./services/web-apps/matomo.nix diff --git a/nixos/modules/services/web-apps/node-red.nix b/nixos/modules/services/web-apps/node-red.nix new file mode 100644 index 00000000000..16cfb29cf57 --- /dev/null +++ b/nixos/modules/services/web-apps/node-red.nix @@ -0,0 +1,148 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.node-red; + defaultUser = "node-red"; + finalPackage = if cfg.withNpmAndGcc then node-red_withNpmAndGcc else cfg.package; + node-red_withNpmAndGcc = pkgs.runCommandNoCC "node-red" { + nativeBuildInputs = [ pkgs.makeWrapper ]; + } + '' + mkdir -p $out/bin + makeWrapper ${pkgs.nodePackages.node-red}/bin/node-red $out/bin/node-red \ + --set PATH '${lib.makeBinPath [ pkgs.nodePackages.npm pkgs.gcc ]}:$PATH' \ + ''; +in +{ + options.services.node-red = { + enable = mkEnableOption "the Node-RED service"; + + package = mkOption { + default = pkgs.nodePackages.node-red; + defaultText = "pkgs.nodePackages.node-red"; + type = types.package; + description = "Node-RED package to use."; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Open ports in the firewall for the server. + ''; + }; + + withNpmAndGcc = mkOption { + type = types.bool; + default = false; + description = '' + Give Node-RED access to NPM and GCC at runtime, so 'Nodes' can be + downloaded and managed imperatively via the 'Palette Manager'. + ''; + }; + + configFile = mkOption { + type = types.path; + default = "${cfg.package}/lib/node_modules/node-red/settings.js"; + defaultText = "\${cfg.package}/lib/node_modules/node-red/settings.js"; + description = '' + Path to the JavaScript configuration file. + See + for a configuration example. + ''; + }; + + port = mkOption { + type = types.port; + default = 1880; + description = "Listening port."; + }; + + user = mkOption { + type = types.str; + default = defaultUser; + description = '' + User under which Node-RED runs.If left as the default value this user + will automatically be created on system activation, otherwise the + sysadmin is responsible for ensuring the user exists. + ''; + }; + + group = mkOption { + type = types.str; + default = defaultUser; + description = '' + Group under which Node-RED runs.If left as the default value this group + will automatically be created on system activation, otherwise the + sysadmin is responsible for ensuring the group exists. + ''; + }; + + userDir = mkOption { + type = types.path; + default = "/var/lib/node-red"; + description = '' + The directory to store all user data, such as flow and credential files and all library data. If left + as the default value this directory will automatically be created before the node-red service starts, + otherwise the sysadmin is responsible for ensuring the directory exists with appropriate ownership + and permissions. + ''; + }; + + safe = mkOption { + type = types.bool; + default = false; + description = "Whether to launch Node-RED in --safe mode."; + }; + + define = mkOption { + type = types.attrs; + default = {}; + description = "List of settings.js overrides to pass via -D to Node-RED."; + example = literalExample '' + { + "logging.console.level" = "trace"; + } + ''; + }; + }; + + config = mkIf cfg.enable { + users.users = optionalAttrs (cfg.user == defaultUser) { + ${defaultUser} = { + isSystemUser = true; + }; + }; + + users.groups = optionalAttrs (cfg.group == defaultUser) { + ${defaultUser} = { }; + }; + + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = [ cfg.port ]; + }; + + systemd.services.node-red = { + description = "Node-RED Service"; + wantedBy = [ "multi-user.target" ]; + after = [ "networking.target" ]; + environment = { + HOME = cfg.userDir; + }; + serviceConfig = mkMerge [ + { + User = cfg.user; + Group = cfg.group; + ExecStart = "${finalPackage}/bin/node-red ${pkgs.lib.optionalString cfg.safe "--safe"} --settings ${cfg.configFile} --port ${toString cfg.port} --userDir ${cfg.userDir} ${concatStringsSep " " (mapAttrsToList (name: value: "-D ${name}=${value}") cfg.define)}"; + PrivateTmp = true; + Restart = "always"; + WorkingDirectory = cfg.userDir; + } + (mkIf (cfg.userDir == "/var/lib/node-red") { StateDirectory = "node-red"; }) + ]; + }; + }; +}