mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-05 21:03:40 +00:00
nixos/speedtest-tracker: init module
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
This commit is contained in:
@@ -1755,6 +1755,7 @@
|
||||
./services/web-apps/snipe-it.nix
|
||||
./services/web-apps/snips-sh.nix
|
||||
./services/web-apps/sogo.nix
|
||||
./services/web-apps/speedtest-tracker.nix
|
||||
./services/web-apps/sshwifty.nix
|
||||
./services/web-apps/stash.nix
|
||||
./services/web-apps/stirling-pdf.nix
|
||||
|
||||
429
nixos/modules/services/web-apps/speedtest-tracker.nix
Normal file
429
nixos/modules/services/web-apps/speedtest-tracker.nix
Normal file
@@ -0,0 +1,429 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.services.speedtest-tracker;
|
||||
|
||||
user = cfg.user;
|
||||
group = cfg.group;
|
||||
|
||||
defaultUser = "speedtest-tracker";
|
||||
defaultGroup = "speedtest-tracker";
|
||||
|
||||
artisan = "${cfg.package}/artisan";
|
||||
|
||||
env-file-values = lib.mapAttrs' (n: v: {
|
||||
name = lib.removeSuffix "_FILE" n;
|
||||
value = v;
|
||||
}) (lib.filterAttrs (n: v: v != null && lib.match ".+_FILE" n != null) cfg.settings);
|
||||
|
||||
env-nonfile-values = lib.filterAttrs (n: v: lib.match ".+_FILE" n == null) cfg.settings;
|
||||
|
||||
speedtest-tracker-maintenance = pkgs.writeShellScript "speedtest-tracker-maintenance.sh" ''
|
||||
set -a
|
||||
${lib.toShellVars env-nonfile-values}
|
||||
${lib.concatLines (lib.mapAttrsToList (n: v: "${n}=\"$(< ${v})\"") env-file-values)}
|
||||
set +a
|
||||
${lib.optionalString (
|
||||
cfg.settings.DB_CONNECTION == "sqlite"
|
||||
) "touch ${cfg.dataDir}/storage/database/database.sqlite"}
|
||||
rm -f ${cfg.dataDir}/cache/*.php
|
||||
${artisan} package:discover
|
||||
${artisan} migrate --force
|
||||
${artisan} optimize:clear
|
||||
${artisan} view:cache
|
||||
${artisan} config:cache
|
||||
'';
|
||||
|
||||
speedtest-tracker-env-script =
|
||||
command:
|
||||
pkgs.writeShellScript "speedtest-tracker-${builtins.replaceStrings [ ":" " " ] [ "-" "-" ] command}.sh" ''
|
||||
set -a
|
||||
${lib.toShellVars env-nonfile-values}
|
||||
${lib.concatLines (lib.mapAttrsToList (n: v: "${n}=\"$(< ${v})\"") env-file-values)}
|
||||
set +a
|
||||
exec ${artisan} ${command}
|
||||
'';
|
||||
|
||||
commonServiceConfig = {
|
||||
Type = "oneshot";
|
||||
User = user;
|
||||
Group = group;
|
||||
StateDirectory = "speedtest-tracker";
|
||||
ReadWritePaths = [ cfg.dataDir ];
|
||||
WorkingDirectory = cfg.package;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
CapabilityBoundingSet = "";
|
||||
AmbientCapabilities = "";
|
||||
ProtectSystem = "strict";
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectClock = true;
|
||||
ProtectHostname = true;
|
||||
ProtectHome = "tmpfs";
|
||||
ProtectKernelLogs = true;
|
||||
ProtectProc = "invisible";
|
||||
ProcSubset = "pid";
|
||||
PrivateNetwork = false;
|
||||
RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX";
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service @resources"
|
||||
"~@obsolete @privileged"
|
||||
];
|
||||
RestrictSUIDSGID = true;
|
||||
RemoveIPC = true;
|
||||
NoNewPrivileges = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictNamespaces = true;
|
||||
LockPersonality = true;
|
||||
PrivateUsers = true;
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
options.services.speedtest-tracker = {
|
||||
|
||||
enable = lib.mkEnableOption "Speedtest Tracker: A self-hosted internet performance tracking application";
|
||||
|
||||
package =
|
||||
lib.mkPackageOption pkgs "speedtest-tracker" { }
|
||||
// lib.mkOption {
|
||||
apply =
|
||||
speedtest-tracker:
|
||||
speedtest-tracker.override (prev: {
|
||||
dataDir = cfg.dataDir;
|
||||
});
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = defaultUser;
|
||||
description = "User account under which Speedtest Tracker runs.";
|
||||
};
|
||||
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = if cfg.enableNginx then "nginx" else defaultGroup;
|
||||
defaultText = "If `services.speedtest-tracker.enableNginx` is true then `nginx` else ${defaultGroup}";
|
||||
description = ''
|
||||
Group under which Speedtest Tracker runs. It is best to set this to the group
|
||||
of whatever webserver is being used as the frontend.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/speedtest-tracker";
|
||||
description = ''
|
||||
The place where Speedtest Tracker stores its state.
|
||||
'';
|
||||
};
|
||||
|
||||
enableNginx = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable nginx or not. If enabled, an nginx virtual host will
|
||||
be created for access to Speedtest Tracker. If not enabled, then you may use
|
||||
`''${config.services.speedtest-tracker.package}` as your document root in
|
||||
whichever webserver you wish to setup.
|
||||
'';
|
||||
};
|
||||
|
||||
virtualHost = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "localhost";
|
||||
description = ''
|
||||
The hostname at which you wish Speedtest Tracker to be served. If you have
|
||||
enabled nginx using `services.speedtest-tracker.enableNginx` then this will
|
||||
be used.
|
||||
'';
|
||||
};
|
||||
|
||||
poolConfig = lib.mkOption {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.oneOf [
|
||||
lib.types.str
|
||||
lib.types.int
|
||||
lib.types.bool
|
||||
]
|
||||
);
|
||||
default = { };
|
||||
defaultText = ''
|
||||
{
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 32;
|
||||
"pm.start_servers" = 2;
|
||||
"pm.min_spare_servers" = 2;
|
||||
"pm.max_spare_servers" = 4;
|
||||
"pm.max_requests" = 500;
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Options for the Speedtest Tracker PHP pool. See the documentation on `php-fpm.conf`
|
||||
for details on configuration directives.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
default = { };
|
||||
description = ''
|
||||
Options for Speedtest Tracker configuration. Refer to
|
||||
<https://github.com/alexjustesen/speedtest-tracker> for
|
||||
details on supported values. All `_FILE` values are supported:
|
||||
append `_FILE` to the setting name to provide a path to a file
|
||||
containing the secret value.
|
||||
'';
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
APP_KEY_FILE = "/var/secrets/speedtest-tracker-app-key.txt";
|
||||
DB_CONNECTION = "mysql";
|
||||
DB_HOST = "db";
|
||||
DB_PORT = 3306;
|
||||
DB_DATABASE = "speedtest-tracker";
|
||||
DB_USERNAME = "speedtest-tracker";
|
||||
DB_PASSWORD_FILE = "/var/secrets/speedtest-tracker-mysql-password.txt";
|
||||
}
|
||||
'';
|
||||
type = lib.types.submodule {
|
||||
freeformType = lib.types.attrsOf (
|
||||
lib.types.oneOf [
|
||||
lib.types.str
|
||||
lib.types.int
|
||||
lib.types.bool
|
||||
]
|
||||
);
|
||||
options = {
|
||||
APP_KEY_FILE = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = ''
|
||||
The path to your appkey. The file should contain a 32 character
|
||||
random app key. This may be set using `echo "base64:$(head -c 32
|
||||
/dev/urandom | base64)" > /path/to/key-file`.
|
||||
'';
|
||||
};
|
||||
APP_URL = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default =
|
||||
if cfg.virtualHost == "localhost" then
|
||||
"http://${cfg.virtualHost}"
|
||||
else
|
||||
"https://${cfg.virtualHost}";
|
||||
defaultText = ''
|
||||
http(s)://''${config.services.speedtest-tracker.virtualHost}
|
||||
'';
|
||||
description = ''
|
||||
The APP_URL used by Speedtest Tracker internally. Please make sure this
|
||||
URL matches the external URL of your installation. It is used to
|
||||
validate specific requests and to generate URLs in notifications.
|
||||
'';
|
||||
};
|
||||
DB_CONNECTION = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"sqlite"
|
||||
"mysql"
|
||||
"mariadb"
|
||||
"pgsql"
|
||||
];
|
||||
default = "sqlite";
|
||||
example = "pgsql";
|
||||
description = ''
|
||||
The type of database you wish to use. Can be one of "sqlite",
|
||||
"mysql", "mariadb" or "pgsql".
|
||||
'';
|
||||
};
|
||||
DB_HOST = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "localhost";
|
||||
description = ''
|
||||
The IP or hostname which hosts your database.
|
||||
'';
|
||||
};
|
||||
DB_PORT = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
default =
|
||||
if cfg.settings.DB_CONNECTION == "pgsql" then
|
||||
5432
|
||||
else if cfg.settings.DB_CONNECTION == "mysql" || cfg.settings.DB_CONNECTION == "mariadb" then
|
||||
3306
|
||||
else
|
||||
null;
|
||||
defaultText = ''
|
||||
`null` if DB_CONNECTION is "sqlite", `3306` if "mysql" or "mariadb", `5432` if "pgsql"
|
||||
'';
|
||||
description = ''
|
||||
The port your database is listening at. sqlite does not require
|
||||
this value to be filled.
|
||||
'';
|
||||
};
|
||||
DB_DATABASE = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default =
|
||||
if cfg.settings.DB_CONNECTION == "sqlite" then
|
||||
"${cfg.dataDir}/storage/database/database.sqlite"
|
||||
else
|
||||
"speedtest-tracker";
|
||||
defaultText = ''
|
||||
"''${config.services.speedtest-tracker.dataDir}/storage/database/database.sqlite" if DB_CONNECTION is "sqlite", "speedtest-tracker" otherwise
|
||||
'';
|
||||
description = ''
|
||||
The name of the database, or path to the sqlite file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
services.phpfpm.pools.speedtest-tracker = {
|
||||
inherit user group;
|
||||
phpPackage = cfg.package.phpPackage;
|
||||
phpOptions = ''
|
||||
log_errors = on
|
||||
'';
|
||||
settings = {
|
||||
"listen.mode" = lib.mkDefault "0660";
|
||||
"listen.owner" = lib.mkDefault user;
|
||||
"listen.group" = lib.mkDefault group;
|
||||
"pm" = lib.mkDefault "dynamic";
|
||||
"pm.max_children" = lib.mkDefault 32;
|
||||
"pm.start_servers" = lib.mkDefault 2;
|
||||
"pm.min_spare_servers" = lib.mkDefault 2;
|
||||
"pm.max_spare_servers" = lib.mkDefault 4;
|
||||
"pm.max_requests" = lib.mkDefault 500;
|
||||
}
|
||||
// cfg.poolConfig;
|
||||
};
|
||||
|
||||
systemd.services.speedtest-tracker-setup = {
|
||||
after = [
|
||||
"postgresql.target"
|
||||
"mysql.service"
|
||||
];
|
||||
requiredBy = [ "phpfpm-speedtest-tracker.service" ];
|
||||
before = [ "phpfpm-speedtest-tracker.service" ];
|
||||
serviceConfig = {
|
||||
ExecStart = speedtest-tracker-maintenance;
|
||||
RemainAfterExit = true;
|
||||
}
|
||||
// commonServiceConfig;
|
||||
unitConfig.JoinsNamespaceOf = "phpfpm-speedtest-tracker.service";
|
||||
restartTriggers = [ cfg.package ];
|
||||
partOf = [ "phpfpm-speedtest-tracker.service" ];
|
||||
};
|
||||
|
||||
systemd.services.speedtest-tracker-scheduler = {
|
||||
after = [ "speedtest-tracker-setup.service" ];
|
||||
wants = [ "speedtest-tracker-setup.service" ];
|
||||
description = "Speedtest Tracker scheduler";
|
||||
path = [ pkgs.ookla-speedtest ];
|
||||
serviceConfig = {
|
||||
ExecStart = speedtest-tracker-env-script "schedule:run";
|
||||
}
|
||||
// commonServiceConfig;
|
||||
};
|
||||
|
||||
systemd.timers.speedtest-tracker-scheduler = {
|
||||
description = "Speedtest Tracker scheduler timer";
|
||||
timerConfig = {
|
||||
OnCalendar = "minutely";
|
||||
Persistent = true;
|
||||
};
|
||||
wantedBy = [ "timers.target" ];
|
||||
restartTriggers = [ cfg.package ];
|
||||
};
|
||||
|
||||
systemd.services.speedtest-tracker-queue-worker = {
|
||||
after = [ "speedtest-tracker-setup.service" ];
|
||||
wants = [ "speedtest-tracker-setup.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
description = "Speedtest Tracker queue worker";
|
||||
path = [ pkgs.ookla-speedtest ];
|
||||
serviceConfig = commonServiceConfig // {
|
||||
Type = "simple";
|
||||
Restart = "always";
|
||||
ExecStart = speedtest-tracker-env-script "queue:work --sleep=3 --tries=3";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = lib.mkIf cfg.enableNginx {
|
||||
enable = true;
|
||||
recommendedTlsSettings = lib.mkDefault true;
|
||||
recommendedOptimisation = lib.mkDefault true;
|
||||
recommendedGzipSettings = lib.mkDefault true;
|
||||
virtualHosts.${cfg.virtualHost} = {
|
||||
root = "${cfg.package}/public";
|
||||
locations = {
|
||||
"/" = {
|
||||
tryFiles = "$uri $uri/ /index.php?$query_string";
|
||||
index = "index.php";
|
||||
extraConfig = ''
|
||||
sendfile off;
|
||||
'';
|
||||
};
|
||||
"~ \\.php$" = {
|
||||
extraConfig = ''
|
||||
include ${config.services.nginx.package}/conf/fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $request_filename;
|
||||
fastcgi_param modHeadersAvailable true;
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools.speedtest-tracker.socket};
|
||||
'';
|
||||
};
|
||||
"~ \\.(js|css|gif|png|ico|jpg|jpeg)$" = {
|
||||
extraConfig = "expires 365d;";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.settings."10-speedtest-tracker" =
|
||||
lib.genAttrs
|
||||
[
|
||||
"${cfg.dataDir}/storage"
|
||||
"${cfg.dataDir}/storage/app"
|
||||
"${cfg.dataDir}/storage/database"
|
||||
"${cfg.dataDir}/storage/framework"
|
||||
"${cfg.dataDir}/storage/framework/cache"
|
||||
"${cfg.dataDir}/storage/framework/sessions"
|
||||
"${cfg.dataDir}/storage/framework/views"
|
||||
"${cfg.dataDir}/storage/logs"
|
||||
"${cfg.dataDir}/cache"
|
||||
]
|
||||
(n: {
|
||||
d = {
|
||||
inherit group;
|
||||
mode = "0700";
|
||||
inherit user;
|
||||
};
|
||||
})
|
||||
// {
|
||||
"${cfg.dataDir}".d = {
|
||||
inherit group;
|
||||
mode = "0710";
|
||||
inherit user;
|
||||
};
|
||||
};
|
||||
|
||||
users = {
|
||||
users = lib.mkIf (user == defaultUser) {
|
||||
${defaultUser} = {
|
||||
inherit group;
|
||||
isSystemUser = true;
|
||||
home = cfg.dataDir;
|
||||
};
|
||||
};
|
||||
groups = lib.mkIf (group == defaultGroup) { ${defaultGroup} = { }; };
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = pkgs.speedtest-tracker.meta.maintainers;
|
||||
}
|
||||
@@ -1484,6 +1484,7 @@ in
|
||||
sonic-server = runTest ./sonic-server.nix;
|
||||
spacecookie = runTest ./spacecookie.nix;
|
||||
spark = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./spark { };
|
||||
speedtest-tracker = runTest ./speedtest-tracker.nix;
|
||||
spiped = runTest ./spiped.nix;
|
||||
sqlite3-to-mysql = runTest ./sqlite3-to-mysql.nix;
|
||||
squid = runTest ./squid.nix;
|
||||
|
||||
33
nixos/tests/speedtest-tracker.nix
Normal file
33
nixos/tests/speedtest-tracker.nix
Normal file
@@ -0,0 +1,33 @@
|
||||
{ lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
app-key = "base64:VGVzdFRlc3RUZXN0VGVzdFRlc3RUZXN0VGVzdFRlc3Q=";
|
||||
in
|
||||
{
|
||||
name = "speedtest-tracker";
|
||||
meta = {
|
||||
maintainers = pkgs.speedtest-tracker.meta.maintainers;
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
|
||||
nodes.sqlite = {
|
||||
environment.etc."speedtest-tracker-appkey".text = app-key;
|
||||
services.speedtest-tracker = {
|
||||
enable = true;
|
||||
enableNginx = true;
|
||||
settings = {
|
||||
APP_KEY_FILE = "/etc/speedtest-tracker-appkey";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
sqlite.wait_for_unit("phpfpm-speedtest-tracker.service")
|
||||
sqlite.wait_for_unit("nginx.service")
|
||||
sqlite.wait_for_unit("speedtest-tracker-queue-worker.service")
|
||||
|
||||
sqlite.succeed("curl -Ls -o /dev/null -w '%{http_code}' http://localhost/admin/login | grep '200'")
|
||||
sqlite.succeed("curl -Ls http://localhost/admin/login | grep -i 'login'")
|
||||
sqlite.succeed("systemctl start speedtest-tracker-scheduler.service")
|
||||
'';
|
||||
}
|
||||
Reference in New Issue
Block a user