diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index cd0ca6fcf35..3e3d7c49280 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -462,6 +462,7 @@ ./services/ttys/gpm.nix ./services/ttys/kmscon.nix ./services/web-apps/pump.io.nix + ./services/web-apps/tt-rss.nix ./services/web-servers/apache-httpd/default.nix ./services/web-servers/caddy.nix ./services/web-servers/fcgiwrap.nix @@ -471,7 +472,7 @@ ./services/web-servers/lighttpd/gitweb.nix ./services/web-servers/lighttpd/inginious.nix ./services/web-servers/nginx/default.nix - ./services/web-servers/phpfpm.nix + ./services/web-servers/phpfpm/default.nix ./services/web-servers/shellinabox.nix ./services/web-servers/tomcat.nix ./services/web-servers/uwsgi.nix diff --git a/nixos/modules/services/web-apps/tt-rss.nix b/nixos/modules/services/web-apps/tt-rss.nix new file mode 100644 index 00000000000..8ab51c006f2 --- /dev/null +++ b/nixos/modules/services/web-apps/tt-rss.nix @@ -0,0 +1,567 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.services.tt-rss; + + configVersion = 26; + + boolToString = b: if b then "true" else "false"; + + cacheDir = "cache"; + lockDir = "lock"; + feedIconsDir = "feed-icons"; + + dbPort = if cfg.database.port == null + then (if cfg.database.type == "pgsql" then 5432 else 3306) + else cfg.database.port; + + poolName = "tt-rss"; + virtualHostName = "tt-rss"; + + tt-rss-config = pkgs.writeText "config.php" '' + System), syslog - logs to system log. + Setting this to blank uses PHP logging (usually to http server + error.log). + ''; + }; + }; + }; + + + ###### implementation + + config = let + root = "/var/lib/tt-rss"; + in mkIf cfg.enable { + + services.phpfpm.pools = if cfg.pool == "${poolName}" then { + "${poolName}" = { + listen = "/var/run/phpfpm/${poolName}.sock"; + extraConfig = '' + listen.owner = nginx + listen.group = nginx + listen.mode = 0600 + user = nginx + pm = dynamic + pm.max_children = 75 + pm.start_servers = 10 + pm.min_spare_servers = 5 + pm.max_spare_servers = 20 + pm.max_requests = 500 + catch_workers_output = 1 + ''; + }; + } else {}; + + + services.nginx.virtualHosts = if cfg.virtualHost == "${virtualHostName}" then { + "${virtualHostName}" = { + root = "${root}"; + extraConfig = '' + access_log /var/log/nginx-${virtualHostName}-access.log; + error_log /var/log/nginx-${virtualHostName}-error.log; + ''; + + locations."/" = { + extraConfig = '' + index index.php; + ''; + }; + + locations."~ \.php$" = { + extraConfig = '' + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:${config.services.phpfpm.pools."${cfg.pool}".listen}; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME ${root}/$fastcgi_script_name; + + include ${pkgs.nginx}/conf/fastcgi_params; + ''; + }; + }; + } else {}; + + + systemd.services.tt-rss = let + dbService = if cfg.database.type == "pgsql" then "postgresql.service" else "mysql.service"; + in { + + description = "Tiny Tiny RSS feeds update daemon"; + + preStart = let + callSql = if cfg.database.type == "pgsql" then (e: '' + ${optionalString (cfg.database.password != null) + "PGPASSWORD=${cfg.database.password}"} ${pkgs.postgresql95}/bin/psql \ + -U ${cfg.database.user} \ + -h ${cfg.database.host} \ + --port ${toString dbPort} \ + -c '${e}' \ + ${cfg.database.name}'') + + else if cfg.database.type == "mysql" then (e: '' + echo '${e}' | ${pkgs.mysql}/bin/mysql \ + ${optionalString (cfg.database.password != null) + "-p${cfg.database.password}"} \ + -u ${cfg.database.user} \ + -h ${cfg.database.host} \ + -P ${toString dbPort} \ + ${cfg.database.name}'') + + else ""; + + in '' + rm -rf "${root}/*" + mkdir -m 755 -p "${root}" + cp -r "${pkgs.tt-rss}/"* "${root}" + ln -sf "${tt-rss-config}" "${root}/config.php" + chown -R "${cfg.user}" "${root}" + chmod -R 755 "${root}" + '' + (optionalString (cfg.database.type == "pgsql") '' + + exists=$(${callSql "select count(*) > 0 from pg_tables where tableowner = user"} \ + | tail -n+3 | head -n-2 | sed -e 's/[ \n\t]*//') + + if [ "$exists" == 'f' ]; then + ${callSql "\\i ${pkgs.tt-rss}/schema/ttrss_schema_${cfg.database.type}.sql"} + else + echo 'The database contains some data. Leaving it as it is.' + fi; + '') + (optionalString (cfg.database.type == "mysql") '' + + exists=$(${callSql "select count(*) > 0 from information_schema.tables where table_schema = schema()"} \ + | tail -n+2 | sed -e 's/[ \n\t]*//') + + if [ "$exists" == '0' ]; then + ${callSql "\\. ${pkgs.tt-rss}/schema/ttrss_schema_${cfg.database.type}.sql"} + else + echo 'The database contains some data. Leaving it as it is.' + fi; + ''); + + serviceConfig = { + User = "${cfg.user}"; + ExecStart = "${pkgs.php}/bin/php /var/lib/tt-rss/update.php --daemon"; + StandardOutput = "syslog"; + StandardError = "syslog"; + PermissionsStartOnly = true; + }; + + wantedBy = [ "multi-user.target" ]; + requires = ["${dbService}"]; + after = ["network.target" "${dbService}"]; + }; + }; +} + diff --git a/nixos/modules/services/web-servers/phpfpm.nix b/nixos/modules/services/web-servers/phpfpm/default.nix similarity index 67% rename from nixos/modules/services/web-servers/phpfpm.nix rename to nixos/modules/services/web-servers/phpfpm/default.nix index 2658d7117e3..6befddf9f52 100644 --- a/nixos/modules/services/web-servers/phpfpm.nix +++ b/nixos/modules/services/web-servers/phpfpm/default.nix @@ -9,6 +9,12 @@ let pidFile = "${stateDir}/phpfpm.pid"; + mkPool = n: p: '' + [${n}] + listen = ${p.listen} + ${p.extraConfig} + ''; + cfgFile = pkgs.writeText "phpfpm.conf" '' [global] pid = ${pidFile} @@ -16,7 +22,7 @@ let daemonize = yes ${cfg.extraConfig} - ${concatStringsSep "\n" (mapAttrsToList (n: v: "[${n}]\n${v}") cfg.poolConfigs)} + ${concatStringsSep "\n" (mapAttrsToList mkPool cfg.pools)} ''; phpIni = pkgs.writeText "php.ini" '' @@ -61,33 +67,19 @@ in { "Options appended to the PHP configuration file php.ini."; }; - poolConfigs = mkOption { - type = types.attrsOf types.lines; + pools = mkOption { + type = types.attrsOf (types.submodule (import ./pool-options.nix { + inherit lib; + })); default = {}; - example = literalExample '' - { mypool = ''' - listen = /run/phpfpm/mypool - user = nobody - pm = dynamic - pm.max_children = 75 - pm.start_servers = 10 - pm.min_spare_servers = 5 - pm.max_spare_servers = 20 - pm.max_requests = 500 - '''; - } - ''; description = '' - A mapping between PHP FPM pool names and their configurations. - See the documentation on php-fpm.conf for - details on configuration directives. If no pools are defined, - the phpfpm service is disabled. + If no pools are defined, the phpfpm service is disabled. ''; }; }; }; - config = mkIf (cfg.poolConfigs != {}) { + config = mkIf (cfg.pools != {}) { systemd.services.phpfpm = { wantedBy = [ "multi-user.target" ]; diff --git a/nixos/modules/services/web-servers/phpfpm/pool-options.nix b/nixos/modules/services/web-servers/phpfpm/pool-options.nix new file mode 100644 index 00000000000..cc688c2c48a --- /dev/null +++ b/nixos/modules/services/web-servers/phpfpm/pool-options.nix @@ -0,0 +1,35 @@ +{ lib }: + +with lib; { + + options = { + + listen = mkOption { + type = types.str; + example = "/path/to/unix/socket"; + description = '' + The address on which to accept FastCGI requests. + ''; + }; + + extraConfig = mkOption { + type = types.lines; + example = '' + user = nobody + pm = dynamic + pm.max_children = 75 + pm.start_servers = 10 + pm.min_spare_servers = 5 + pm.max_spare_servers = 20 + pm.max_requests = 500 + ''; + + description = '' + Extra lines that go into the pool configuration. + See the documentation on php-fpm.conf for + details on configuration directives. + ''; + }; + }; +} + diff --git a/pkgs/servers/tt-rss/default.nix b/pkgs/servers/tt-rss/default.nix new file mode 100644 index 00000000000..d42656cf0f6 --- /dev/null +++ b/pkgs/servers/tt-rss/default.nix @@ -0,0 +1,28 @@ +{ stdenv, fetchgit }: + +stdenv.mkDerivation rec { + name = "tt-rss-${version}"; + version = "16.3"; + + src = fetchgit { + url = "https://tt-rss.org/gitlab/fox/tt-rss.git"; + rev = "refs/tags/${version}"; + sha256 = "1584lcq6kcy9f8ik5djb9apck9hxvfpl54sn6yhl3pdfrfdj3nw5"; + }; + + buildPhases = ["unpackPhase" "installPhase"]; + + installPhase = '' + mkdir $out + cp -ra * $out/ + ''; + + meta = with stdenv.lib; { + description = "Web-based news feed (RSS/Atom) aggregator"; + license = licenses.gpl2Plus; + homepage = http://tt-rss.org; + maintainers = with maintainers; [ zohl ]; + platforms = platforms.all; + }; +} + diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index ce31a6e902c..14765e67959 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -10556,6 +10556,8 @@ in torque = callPackage ../servers/computing/torque { }; + tt-rss = callPackage ../servers/tt-rss { }; + axis2 = callPackage ../servers/http/tomcat/axis2 { }; unifi = callPackage ../servers/unifi { };