{ description = "Your self-hosted, globally interconnected microblogging community"; inputs.flake-utils.url = "github:numtide/flake-utils"; inputs.nixpkgs = { url = "github:NixOS/nixpkgs/840c782d507d60aaa49aa9e3f6d0b0e780912742"; flake = false; }; inputs.etherpad-lite = { url = "github:ether/etherpad-lite/1.8.3"; flake = false; }; inputs.mypackages.url = "path:../mypackages"; outputs = { self, nixpkgs, etherpad-lite, flake-utils, mypackages }: flake-utils.lib.eachSystem ["x86_64-linux"] (system: let pkgs = import nixpkgs { inherit system; overlays = []; }; version = (builtins.fromJSON (builtins.readFile ./flake.lock)).nodes.etherpad-lite.original.ref; inherit (pkgs) callPackage; in rec { packages.etherpad-lite = callPackage ./. { inherit (mypackages.mylibs) nodeEnv; src = etherpad-lite // { inherit version; }; }; defaultPackage = packages.etherpad-lite; legacyPackages.etherpad-lite = packages.etherpad-lite; checks = { build = defaultPackage; }; } ) // rec { overlays = { etherpad-lite = final: prev: { etherpad-lite = self.defaultPackage."${final.system}"; }; }; overlay = overlays.etherpad-lite; nixosModule = { lib, pkgs, config, ... }: let name = "etherpad-lite"; cfg = config.services.etherpad-lite; in { options.services.etherpad-lite = { enable = lib.mkEnableOption "Enable Etherpad lite’s service"; user = lib.mkOption { type = lib.types.str; default = name; description = "User account under which Etherpad lite runs"; }; group = lib.mkOption { type = lib.types.str; default = name; description = "Group under which Etherpad lite runs"; }; dataDir = lib.mkOption { type = lib.types.path; default = "/var/lib/${name}"; description = '' The directory where Etherpad lite stores its data. ''; }; socketsDir = lib.mkOption { type = lib.types.path; default = "/run/${name}"; description = '' The directory where Etherpad lite stores its sockets. ''; }; configFile = lib.mkOption { type = lib.types.path; description = '' The config file path for Etherpad lite. ''; }; sessionKeyFile = lib.mkOption { type = lib.types.path; description = '' The Session key file path for Etherpad lite. ''; }; apiKeyFile = lib.mkOption { type = lib.types.path; description = '' The API key file path for Etherpad lite. ''; }; package = lib.mkOption { type = lib.types.package; default = pkgs.etherpad-lite; description = '' Etherpad lite package to use. ''; example = lib.literalExample '' pkgs.webapps.etherpad-lite.withModules (p: [ p.ep_align ]); ''; }; modules = lib.mkOption { type = lib.types.listOf lib.types.package; default = []; description = '' Etherpad lite modules to use. DEPRECATED: use package directly ''; }; # Output variables workdir = lib.mkOption { type = lib.types.package; default = cfg.package.withModules (_: cfg.modules); description = '' Adjusted Etherpad lite package with plugins ''; readOnly = true; }; systemdStateDirectory = lib.mkOption { type = lib.types.str; # Use ReadWritePaths= instead if varDir is outside of /var/lib default = assert lib.strings.hasPrefix "/var/lib/" cfg.dataDir; lib.strings.removePrefix "/var/lib/" cfg.dataDir; description = '' Adjusted Etherpad lite data directory for systemd ''; readOnly = true; }; systemdRuntimeDirectory = lib.mkOption { type = lib.types.str; # Use ReadWritePaths= instead if socketsDir is outside of /run default = assert lib.strings.hasPrefix "/run/" cfg.socketsDir; lib.strings.removePrefix "/run/" cfg.socketsDir; description = '' Adjusted Etherpad lite sockets directory for systemd ''; readOnly = true; }; sockets = lib.mkOption { type = lib.types.attrsOf lib.types.path; default = { node = "${cfg.socketsDir}/etherpad-lite.sock"; }; readOnly = true; description = '' Etherpad lite sockets ''; }; }; config = lib.mkIf cfg.enable { nixpkgs.overlays = [ self.overlay ]; systemd.services.etherpad-lite-cleanup = { description = "Etherpad-lite cleanup old mypads"; after = [ "network.target" "postgresql.service" ]; wants = [ "postgresql.service" ]; environment.NODE_ENV = "production"; environment.HOME = cfg.workdir; path = [ cfg.workdir.nodejs ]; script = '' exec ${cfg.workdir.nodejs}/bin/node ${cfg.workdir}/node_modules/ep_mypads/scripts/mypads-jobqueue-minion.js \ --settings ${cfg.configFile} \ --oneshot ''; serviceConfig = { DynamicUser = true; User = cfg.user; Group = cfg.group; WorkingDirectory = "%T"; PrivateTmp = true; NoNewPrivileges = true; PrivateDevices = true; ProtectHome = true; ProtectControlGroups = true; ProtectKernelModules = true; Type = "oneshot"; }; }; systemd.services.etherpad-lite = { description = "Etherpad-lite"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" "postgresql.service" ]; wants = [ "postgresql.service" ]; environment.NODE_ENV = "production"; environment.HOME = cfg.workdir; path = [ cfg.workdir.nodejs ]; script = '' exec ${cfg.workdir.nodejs}/bin/node ${cfg.workdir}/src/node/server.js \ --sessionkey ${cfg.sessionKeyFile} \ --apikey ${cfg.apiKeyFile} \ --settings ${cfg.configFile} ''; postStart = '' while [ ! -S ${cfg.sockets.node} ]; do sleep 0.5 done chmod a+w ${cfg.sockets.node} ''; serviceConfig = { DynamicUser = true; User = cfg.user; Group = cfg.group; WorkingDirectory = cfg.workdir; PrivateTmp = true; NoNewPrivileges = true; PrivateDevices = true; ProtectHome = true; ProtectControlGroups = true; ProtectKernelModules = true; Restart = "always"; Type = "simple"; TimeoutSec = 60; RuntimeDirectory = cfg.systemdRuntimeDirectory; StateDirectory= cfg.systemdStateDirectory; ExecStartPre = [ "+${pkgs.coreutils}/bin/install -d -m 0755 -o ${cfg.user} -g ${cfg.group} ${cfg.dataDir}/var ${cfg.dataDir}/ep_initialized" "+${pkgs.coreutils}/bin/chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir} ${cfg.configFile} ${cfg.sessionKeyFile} ${cfg.apiKeyFile}" ]; }; }; }; }; }; }