freshrss: init at 1.20.0, tests and module
This commit is contained in:
parent
12f1449d2b
commit
0b204f0c28
@ -270,6 +270,13 @@
|
||||
<link linkend="opt-services.dolibarr.enable">services.dolibarr</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://freshrss.org/">FreshRSS</link>, a
|
||||
free, self-hostable RSS feed aggregator. Available as
|
||||
<link linkend="opt-services.freshrss.enable">services.freshrss</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://www.expressvpn.com">expressvpn</link>,
|
||||
|
@ -96,6 +96,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [Dolibarr](https://www.dolibarr.org/), an enterprise resource planning and customer relationship manager. Enable using [services.dolibarr](#opt-services.dolibarr.enable).
|
||||
|
||||
- [FreshRSS](https://freshrss.org/), a free, self-hostable RSS feed aggregator. Available as [services.freshrss](#opt-services.freshrss.enable).
|
||||
|
||||
- [expressvpn](https://www.expressvpn.com), the CLI client for ExpressVPN. Available as [services.expressvpn](#opt-services.expressvpn.enable).
|
||||
|
||||
- [go-autoconfig](https://github.com/L11R/go-autoconfig), IMAP/SMTP autodiscover server. Available as [services.go-autoconfig](#opt-services.go-autoconfig.enable).
|
||||
|
@ -1072,6 +1072,7 @@
|
||||
./services/web-apps/engelsystem.nix
|
||||
./services/web-apps/ethercalc.nix
|
||||
./services/web-apps/fluidd.nix
|
||||
./services/web-apps/freshrss.nix
|
||||
./services/web-apps/galene.nix
|
||||
./services/web-apps/gerrit.nix
|
||||
./services/web-apps/gotify-server.nix
|
||||
|
274
nixos/modules/services/web-apps/freshrss.nix
Normal file
274
nixos/modules/services/web-apps/freshrss.nix
Normal file
@ -0,0 +1,274 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.freshrss;
|
||||
|
||||
poolName = "freshrss";
|
||||
in
|
||||
{
|
||||
meta.maintainers = with maintainers; [ etu stunkymonkey ];
|
||||
|
||||
options.services.freshrss = {
|
||||
enable = mkEnableOption (mdDoc "FreshRSS feed reader");
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.freshrss;
|
||||
defaultText = lib.literalExpression "pkgs.freshrss";
|
||||
description = mdDoc "Which FreshRSS package to use.";
|
||||
};
|
||||
|
||||
defaultUser = mkOption {
|
||||
type = types.str;
|
||||
default = "admin";
|
||||
description = mdDoc "Default username for FreshRSS.";
|
||||
example = "eva";
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = types.path;
|
||||
description = mdDoc "Password for the defaultUser for FreshRSS.";
|
||||
example = "/run/secrets/freshrss";
|
||||
};
|
||||
|
||||
baseUrl = mkOption {
|
||||
type = types.str;
|
||||
description = mdDoc "Default URL for FreshRSS.";
|
||||
example = "https://freshrss.example.com";
|
||||
};
|
||||
|
||||
language = mkOption {
|
||||
type = types.str;
|
||||
default = "en";
|
||||
description = mdDoc "Default language for FreshRSS.";
|
||||
example = "de";
|
||||
};
|
||||
|
||||
database = {
|
||||
type = mkOption {
|
||||
type = types.enum [ "sqlite" "pgsql" "mysql" ];
|
||||
default = "sqlite";
|
||||
description = mdDoc "Database type.";
|
||||
example = "pgsql";
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "localhost";
|
||||
description = mdDoc "Database host for FreshRSS.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = with types; nullOr port;
|
||||
default = null;
|
||||
description = mdDoc "Database port for FreshRSS.";
|
||||
example = 3306;
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "freshrss";
|
||||
description = mdDoc "Database user for FreshRSS.";
|
||||
};
|
||||
|
||||
passFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = mdDoc "Database password file for FreshRSS.";
|
||||
example = "/run/secrets/freshrss";
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "freshrss";
|
||||
description = mdDoc "Database name for FreshRSS.";
|
||||
};
|
||||
|
||||
tableprefix = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = mdDoc "Database table prefix for FreshRSS.";
|
||||
example = "freshrss";
|
||||
};
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/freshrss";
|
||||
description = mdDoc "Default data folder for FreshRSS.";
|
||||
example = "/mnt/freshrss";
|
||||
};
|
||||
|
||||
virtualHost = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "freshrss";
|
||||
description = mdDoc ''
|
||||
Name of the nginx virtualhost to use and setup. If null, do not setup any virtualhost.
|
||||
'';
|
||||
};
|
||||
|
||||
pool = mkOption {
|
||||
type = types.str;
|
||||
default = poolName;
|
||||
description = mdDoc ''
|
||||
Name of the phpfpm pool to use and setup. If not specified, a pool will be created
|
||||
with default values.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
config =
|
||||
let
|
||||
systemd-hardening = {
|
||||
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
|
||||
DeviceAllow = "";
|
||||
LockPersonality = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "strict";
|
||||
RemoveIPC = true;
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [ "@system-service" "~@resources" "~@privileged" ];
|
||||
UMask = "0007";
|
||||
};
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
# Set up a Nginx virtual host.
|
||||
services.nginx = mkIf (cfg.virtualHost != null) {
|
||||
enable = true;
|
||||
virtualHosts.${cfg.virtualHost} = {
|
||||
root = "${cfg.package}/p";
|
||||
|
||||
locations."~ ^.+?\.php(/.*)?$".extraConfig = ''
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools.${cfg.pool}.socket};
|
||||
fastcgi_split_path_info ^(.+\.php)(/.*)$;
|
||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||
'';
|
||||
|
||||
locations."/" = {
|
||||
tryFiles = "$uri $uri/ index.php";
|
||||
index = "index.php index.html index.htm";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Set up phpfpm pool
|
||||
services.phpfpm.pools = mkIf (cfg.pool == poolName) {
|
||||
${poolName} = {
|
||||
user = "freshrss";
|
||||
settings = {
|
||||
"listen.owner" = "nginx";
|
||||
"listen.group" = "nginx";
|
||||
"listen.mode" = "0600";
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 32;
|
||||
"pm.max_requests" = 500;
|
||||
"pm.start_servers" = 2;
|
||||
"pm.min_spare_servers" = 2;
|
||||
"pm.max_spare_servers" = 5;
|
||||
"catch_workers_output" = true;
|
||||
};
|
||||
phpEnv = {
|
||||
FRESHRSS_DATA_PATH = "${cfg.dataDir}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users.users.freshrss = {
|
||||
description = "FreshRSS service user";
|
||||
isSystemUser = true;
|
||||
group = "freshrss";
|
||||
};
|
||||
users.groups.freshrss = { };
|
||||
|
||||
systemd.services.freshrss-config =
|
||||
let
|
||||
settingsFlags = concatStringsSep " \\\n "
|
||||
(mapAttrsToList (k: v: "${k} ${toString v}") {
|
||||
"--default_user" = ''"${cfg.defaultUser}"'';
|
||||
"--auth_type" = ''"form"'';
|
||||
"--base_url" = ''"${cfg.baseUrl}"'';
|
||||
"--language" = ''"${cfg.language}"'';
|
||||
"--db-type" = ''"${cfg.database.type}"'';
|
||||
# The following attributes are optional depending on the type of
|
||||
# database. Those that evaluate to null on the left hand side
|
||||
# will be omitted.
|
||||
${if cfg.database.name != null then "--db-base" else null} = ''"${cfg.database.name}"'';
|
||||
${if cfg.database.passFile != null then "--db-password" else null} = ''"$(cat ${cfg.database.passFile})"'';
|
||||
${if cfg.database.user != null then "--db-user" else null} = ''"${cfg.database.user}"'';
|
||||
${if cfg.database.tableprefix != null then "--db-prefix" else null} = ''"${cfg.database.tableprefix}"'';
|
||||
${if cfg.database.host != null && cfg.database.port != null then "--db-host" else null} = ''"${cfg.database.host}:${toString cfg.database.port}"'';
|
||||
});
|
||||
in
|
||||
{
|
||||
description = "Set up the state directory for FreshRSS before use";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "freshrss";
|
||||
Group = "freshrss";
|
||||
StateDirectory = "freshrss";
|
||||
WorkingDirectory = cfg.package;
|
||||
} // systemd-hardening;
|
||||
environment = {
|
||||
FRESHRSS_DATA_PATH = cfg.dataDir;
|
||||
};
|
||||
|
||||
script = ''
|
||||
# create files with correct permissions
|
||||
mkdir -m 755 -p ${cfg.dataDir}
|
||||
|
||||
# do installation or reconfigure
|
||||
if test -f ${cfg.dataDir}/config.php; then
|
||||
# reconfigure with settings
|
||||
${pkgs.php}/bin/php ./cli/reconfigure.php ${settingsFlags}
|
||||
${pkgs.php}/bin/php ./cli/update-user.php --user ${cfg.defaultUser} --password "$(cat ${cfg.passwordFile})"
|
||||
else
|
||||
# Copy the user data template directory
|
||||
cp -r ./data ${cfg.dataDir}
|
||||
|
||||
# check correct folders in data folder
|
||||
${pkgs.php}/bin/php ./cli/prepare.php
|
||||
# install with settings
|
||||
${pkgs.php}/bin/php ./cli/do-install.php ${settingsFlags}
|
||||
${pkgs.php}/bin/php ./cli/create-user.php --user ${cfg.defaultUser} --password "$(cat ${cfg.passwordFile})"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.freshrss-updater = {
|
||||
description = "FreshRSS feed updater";
|
||||
after = [ "freshrss-config.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
startAt = "*:0/5";
|
||||
environment = {
|
||||
FRESHRSS_DATA_PATH = cfg.dataDir;
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "freshrss";
|
||||
Group = "freshrss";
|
||||
StateDirectory = "freshrss";
|
||||
WorkingDirectory = cfg.package;
|
||||
ExecStart = "${pkgs.php}/bin/php ./app/actualize_script.php";
|
||||
} // systemd-hardening;
|
||||
};
|
||||
};
|
||||
}
|
@ -170,6 +170,7 @@ in {
|
||||
fluidd = handleTest ./fluidd.nix {};
|
||||
fontconfig-default-fonts = handleTest ./fontconfig-default-fonts.nix {};
|
||||
freeswitch = handleTest ./freeswitch.nix {};
|
||||
freshrss = handleTest ./freshrss.nix {};
|
||||
frr = handleTest ./frr.nix {};
|
||||
fsck = handleTest ./fsck.nix {};
|
||||
ft2-clone = handleTest ./ft2-clone.nix {};
|
||||
|
19
nixos/tests/freshrss.nix
Normal file
19
nixos/tests/freshrss.nix
Normal file
@ -0,0 +1,19 @@
|
||||
import ./make-test-python.nix ({ lib, pkgs, ... }: {
|
||||
name = "freshrss";
|
||||
meta.maintainers = with lib.maintainers; [ etu stunkymonkey ];
|
||||
|
||||
nodes.machine = { pkgs, ... }: {
|
||||
services.freshrss = {
|
||||
enable = true;
|
||||
baseUrl = "http://localhost";
|
||||
passwordFile = pkgs.writeText "password" "secret";
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.wait_for_open_port(80)
|
||||
response = machine.succeed("curl -vvv -s -H 'Host: freshrss' http://127.0.0.1:80/i/")
|
||||
assert '<title>Login · FreshRSS</title>' in response, "Login page didn't load successfully"
|
||||
'';
|
||||
})
|
38
pkgs/servers/web-apps/freshrss/default.nix
Normal file
38
pkgs/servers/web-apps/freshrss/default.nix
Normal file
@ -0,0 +1,38 @@
|
||||
{ stdenvNoCC, lib, fetchFromGitHub, nixosTests, pkgs }:
|
||||
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
pname = "FreshRSS";
|
||||
version = "1.20.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "FreshRSS";
|
||||
repo = "FreshRSS";
|
||||
rev = version;
|
||||
hash = "sha256-mzhEw2kFv77SmeuEx66n9ujWMscZO3+03tHimk1/vk4=";
|
||||
};
|
||||
|
||||
passthru.tests = nixosTests.freshrss;
|
||||
|
||||
# There's nothing to build.
|
||||
dontBuild = true;
|
||||
|
||||
# the data folder is no in this package and thereby declared by an env-var
|
||||
overrideConfig = pkgs.writeText "constants.local.php" ''
|
||||
<?php
|
||||
define('DATA_PATH', getenv('FRESHRSS_DATA_PATH'));
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp -vr * $out/
|
||||
|
||||
cp $overrideConfig $out/constants.local.php
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "FreshRSS is a free, self-hostable RSS aggregator";
|
||||
homepage = "https://www.freshrss.org/";
|
||||
license = licenses.agpl3Plus;
|
||||
maintainers = with maintainers; [ etu stunkymonkey ];
|
||||
};
|
||||
}
|
@ -23045,6 +23045,8 @@ with pkgs;
|
||||
openssl = openssl_1_1;
|
||||
};
|
||||
|
||||
freshrss = callPackage ../servers/web-apps/freshrss { };
|
||||
|
||||
freeswitch = callPackage ../servers/sip/freeswitch {
|
||||
inherit (darwin.apple_sdk.frameworks) SystemConfiguration;
|
||||
openssl = openssl_1_1;
|
||||
|
Loading…
Reference in New Issue
Block a user