diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index e7b7ad1194c..522a7992919 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -865,6 +865,7 @@
./services/web-apps/moinmoin.nix
./services/web-apps/restya-board.nix
./services/web-apps/sogo.nix
+ ./services/web-apps/rss-bridge.nix
./services/web-apps/tt-rss.nix
./services/web-apps/trac.nix
./services/web-apps/trilium.nix
diff --git a/nixos/modules/services/web-apps/rss-bridge.nix b/nixos/modules/services/web-apps/rss-bridge.nix
new file mode 100644
index 00000000000..f1d5b7660f3
--- /dev/null
+++ b/nixos/modules/services/web-apps/rss-bridge.nix
@@ -0,0 +1,127 @@
+{ config, lib, pkgs, ... }:
+with lib;
+let
+ cfg = config.services.rss-bridge;
+
+ poolName = "rss-bridge";
+
+ whitelist = pkgs.writeText "rss-bridge_whitelist.txt"
+ (concatStringsSep "\n" cfg.whitelist);
+in
+{
+ options = {
+ services.rss-bridge = {
+ enable = mkEnableOption "rss-bridge";
+
+ user = mkOption {
+ type = types.str;
+ default = "nginx";
+ example = "nginx";
+ description = ''
+ User account under which both the service and the web-application run.
+ '';
+ };
+
+ group = mkOption {
+ type = types.str;
+ default = "nginx";
+ example = "nginx";
+ description = ''
+ Group under which the web-application run.
+ '';
+ };
+
+ pool = mkOption {
+ type = types.str;
+ default = poolName;
+ description = ''
+ Name of existing phpfpm pool that is used to run web-application.
+ If not specified a pool will be created automatically with
+ default values.
+ '';
+ };
+
+ dataDir = mkOption {
+ type = types.str;
+ default = "/var/lib/rss-bridge";
+ description = ''
+ Location in which cache directory will be created.
+ You can put config.ini.php in here.
+ '';
+ };
+
+ virtualHost = mkOption {
+ type = types.nullOr types.str;
+ default = "rss-bridge";
+ description = ''
+ Name of the nginx virtualhost to use and setup. If null, do not setup any virtualhost.
+ '';
+ };
+
+ whitelist = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = options.literalExample ''
+ [
+ "Facebook"
+ "Instagram"
+ "Twitter"
+ ]
+ '';
+ description = ''
+ List of bridges to be whitelisted.
+ If the list is empty, rss-bridge will use whitelist.default.txt.
+ Use [ "*" ] to whitelist all.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ services.phpfpm.pools = mkIf (cfg.pool == poolName) {
+ ${poolName} = {
+ user = cfg.user;
+ settings = mapAttrs (name: mkDefault) {
+ "listen.owner" = cfg.user;
+ "listen.group" = cfg.user;
+ "listen.mode" = "0600";
+ "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;
+ };
+ };
+ };
+ systemd.tmpfiles.rules = [
+ "d '${cfg.dataDir}/cache' 0750 ${cfg.user} ${cfg.group} - -"
+ (mkIf (cfg.whitelist != []) "L+ ${cfg.dataDir}/whitelist.txt - - - - ${whitelist}")
+ "z '${cfg.dataDir}/config.ini.php' 0750 ${cfg.user} ${cfg.group} - -"
+ ];
+
+ services.nginx = mkIf (cfg.virtualHost != null) {
+ enable = true;
+ virtualHosts = {
+ ${cfg.virtualHost} = {
+ root = "${pkgs.rss-bridge}";
+
+ locations."/" = {
+ tryFiles = "$uri /index.php$is_args$args";
+ };
+
+ locations."~ ^/index.php(/|$)" = {
+ extraConfig = ''
+ include ${pkgs.nginx}/conf/fastcgi_params;
+ fastcgi_split_path_info ^(.+\.php)(/.+)$;
+ fastcgi_pass unix:${config.services.phpfpm.pools.${cfg.pool}.socket};
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param RSSBRIDGE_DATA ${cfg.dataDir};
+ '';
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/pkgs/servers/web-apps/rss-bridge/default.nix b/pkgs/servers/web-apps/rss-bridge/default.nix
new file mode 100644
index 00000000000..432f5956406
--- /dev/null
+++ b/pkgs/servers/web-apps/rss-bridge/default.nix
@@ -0,0 +1,33 @@
+{ config, lib, pkgs, fetchFromGitHub, stdenv, ... }:
+
+stdenv.mkDerivation rec {
+ pname = "rss-bridge";
+ version = "2020-02-26";
+
+ src = fetchFromGitHub {
+ owner = "RSS-Bridge";
+ repo = "rss-bridge";
+ rev = "${version}";
+ sha256 = "075k4bylx9308d083ry5a9q4629ccnrnndqqdqp1g42rzlqrw79q";
+ };
+
+ patchPhase = ''
+ substituteInPlace lib/rssbridge.php \
+ --replace "define('PATH_CACHE', PATH_ROOT . 'cache/');" "define('PATH_CACHE', getenv('RSSBRIDGE_DATA') . '/cache/');" \
+ --replace "define('FILE_CONFIG', PATH_ROOT . 'config.ini.php');" "define('FILE_CONFIG', getenv('RSSBRIDGE_DATA') . '/config.ini.php');" \
+ --replace "define('WHITELIST', PATH_ROOT . 'whitelist.txt');" "define('WHITELIST', getenv('RSSBRIDGE_DATA') . '/whitelist.txt');"
+ '';
+
+ installPhase = ''
+ mkdir $out/
+ cp -R ./* $out
+ '';
+
+ meta = with lib; {
+ description = "The RSS feed for websites missing it";
+ homepage = "https://github.com/RSS-Bridge/rss-bridge";
+ license = licenses.unlicense;
+ maintainers = with maintainers; [ dawidsowa ];
+ platforms = platforms.all;
+ };
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 9d2ad844aa6..b0b78427448 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -16822,6 +16822,8 @@ in
tt-rss-plugin-auth-ldap = callPackage ../servers/tt-rss/plugin-auth-ldap { };
tt-rss-theme-feedly = callPackage ../servers/tt-rss/theme-feedly { };
+ rss-bridge = callPackage ../servers/web-apps/rss-bridge { };
+
searx = callPackage ../servers/web-apps/searx { };
selfoss = callPackage ../servers/web-apps/selfoss { };