diff --git a/hosts/profiles/ulogger-server/default.nix b/hosts/profiles/ulogger-server/default.nix new file mode 100644 index 00000000..84ed3fa0 --- /dev/null +++ b/hosts/profiles/ulogger-server/default.nix @@ -0,0 +1,117 @@ +{ self, pkgs, config, lib, ... }: + +{ + services.postgresql = { + ensureDatabases = [ "ulogger" ]; + ensureUsers = [{ + name = "ulogger"; + ensurePermissions = { + "DATABASE ulogger" = "ALL PRIVILEGES"; + }; + }]; + }; + + services.ulogger = { + enable = true; + hostName = "tracks.mossnet.lan"; + conf = '' + . + */ + + // This is default configuration file. + // Copy it to config.php and customize + + // default map drawing framework + // (gmaps = google maps, openlayers = openlayers/osm) + //$mapapi = "gmaps"; + $mapapi = "openlayers"; + + // openlayers additional map layers + // OpenCycleMap (0 = no, 1 = yes) + $layer_ocm = 1; + // MapQuest-OSM (0 = no, 1 = yes) + $layer_mq = 1; + // osmapa.pl (0 = no, 1 = yes) + $layer_osmapa = 1; + // UMP (0 = no, 1 = yes) + $layer_ump = 1; + + // default coordinates for initial map + $init_latitude = 52.23; + $init_longitude = 21.01; + + // you may set your google maps api key + // this is not obligatory by now + //$gkey = ""; + + // MySQL config + $dbhost = "localhost"; // mysql host, eg. localhost + $dbuser = "ulogger"; // database user + $dbpass = ""; // database pass + $dbname = "ulogger"; // database name + $dbprefix = ""; // optional table names prefix, eg. "ulogger_" + + // other + // require login/password authentication + // (0 = no, 1 = yes) + $require_authentication = 0; + + // all users tracks are visible to authenticated user + // (0 = no, 1 = yes) + $public_tracks = 0; + + // admin user, who + // - can add new users + // - can edit all tracks, users + // - has access to all users locations + // none if empty + $admin_user = "admin"; + + // miniumum required length of user password + $pass_lenmin = 12; + + // required strength of user password + // 0 = no requirements, + // 1 = require mixed case letters (lower and upper), + // 2 = require mixed case and numbers, + // 3 = require mixed case, numbers and non-alphanumeric characters + $pass_strength = 0; + + // Default interval in seconds for live auto reload + $interval = 10; + + // Default language + // (en, pl, de, hu) + $lang = "en"; + //$lang = "pl"; + //$lang = "de"; + //$lang = "hu"; + //$lang = "fr"; + //$lang = "it"; + + // units + // (metric, imperial) + $units = "metric"; + //$units = "imperial"; + + ?> + + ''; + }; +} diff --git a/modules/nixos/ulogger.nix b/modules/nixos/ulogger.nix new file mode 100644 index 00000000..1f1b0352 --- /dev/null +++ b/modules/nixos/ulogger.nix @@ -0,0 +1,282 @@ +{ config, options, lib, pkgs, ... }: + +with lib; +let + cfg = config.services.ulogger; + + poolName = "ulogger"; + + configFile = pkgs.writeTextFile { + name = "ulogger-config"; + text = cfg.conf; + destination = "config.php"; + }; + + appDir = pkgs.buildEnv { + name = "ulogger-app-dir"; + ignoreCollisions = true; + checkCollisionContents = false; + paths = [ configFile "${cfg.package}/app" ]; + }; + +in +{ + options = { + services.ulogger = { + enable = mkEnableOption "ulogger"; + user = mkOption { + type = types.str; + default = "nginx"; + description = '' + User account under which both the update daemon and the web-application run. + ''; + }; + dataDir = mkOption { + type = types.path; + default = "/var/lib/ulogger"; + description = '' + Data directory. + ''; + }; + + package = mkOption { + type = types.package; + default = pkgs.ulogger-server; + description = '' + ulogger-server package to use. + ''; + }; + + hostName = mkOption { + type = types.str; + description = '' + Name of the nginx virtualhost to use and setup. + ''; + }; + + poolConfig = mkOption { + type = types.lines; + default = '' + pm = dynamic + pm.max_children = 75 + pm.start_servers = 1 + pm.min_spare_servers = 1 + pm.max_spare_servers = 20 + pm.max_requests = 500 + catch_workers_output = 1 + ''; + description = '' + Options for uloggers's PHP pool. See the documentation on php-fpm.conf for details on configuration directives. + ''; + }; + + conf = mkOption { + type = types.str; + default = '' + . + */ + + // This is default configuration file. + // Copy it to config.php and customize + + // default map drawing framework + // (gmaps = google maps, openlayers = openlayers/osm) + //$mapapi = "gmaps"; + $mapapi = "openlayers"; + + // openlayers additional map layers + // OpenCycleMap (0 = no, 1 = yes) + $layer_ocm = 1; + // MapQuest-OSM (0 = no, 1 = yes) + $layer_mq = 1; + // osmapa.pl (0 = no, 1 = yes) + $layer_osmapa = 1; + // UMP (0 = no, 1 = yes) + $layer_ump = 1; + + // default coordinates for initial map + $init_latitude = 52.23; + $init_longitude = 21.01; + + // you may set your google maps api key + // this is not obligatory by now + //$gkey = ""; + + // MySQL config + $dbhost = ""; // mysql host, eg. localhost + $dbuser = ""; // database user + $dbpass = ""; // database pass + $dbname = ""; // database name + $dbprefix = ""; // optional table names prefix, eg. "ulogger_" + + // other + // require login/password authentication + // (0 = no, 1 = yes) + $require_authentication = 1; + + // all users tracks are visible to authenticated user + // (0 = no, 1 = yes) + $public_tracks = 0; + + // admin user, who + // - can add new users + // - can edit all tracks, users + // - has access to all users locations + // none if empty + $admin_user = ""; + + // miniumum required length of user password + $pass_lenmin = 12; + + // required strength of user password + // 0 = no requirements, + // 1 = require mixed case letters (lower and upper), + // 2 = require mixed case and numbers, + // 3 = require mixed case, numbers and non-alphanumeric characters + $pass_strength = 2; + + // Default interval in seconds for live auto reload + $interval = 10; + + // Default language + // (en, pl, de, hu) + $lang = "en"; + //$lang = "pl"; + //$lang = "de"; + //$lang = "hu"; + //$lang = "fr"; + //$lang = "it"; + + // units + // (metric, imperial) + $units = "metric"; + //$units = "imperial"; + + ?> + ''; + description = '' + Contents of the ulogger configuration file (config.php) + ''; + }; + }; + }; + + + config = mkIf cfg.enable { + services.phpfpm.pools."${poolName}" = { + user = "${cfg.user}"; + group = "nginx"; + phpPackage = pkgs.php; + settings = { + "listen.owner" = "nginx"; + "listen.group" = "nginx"; + "listen.mode" = "0600"; + "user" = "${cfg.user}"; + "group" = "nginx"; + "pm" = "dynamic"; + "pm.max_children" = "75"; + "pm.min_spare_servers" = "5"; + "pm.max_spare_servers" = "20"; + "pm.max_requests" = "10"; + "catch_workers_output" = "1"; + "php_admin_value[error_log]" = "/var/log/nginx/${poolName}-phpfpm-error.log"; + }; + }; + services.phpfpm.phpOptions = '' + max_execution_time = 120 + ''; + + services.nginx.enable = mkDefault true; + + services.nginx.virtualHosts."${cfg.hostName}" = { + enableACME = false; + forceSSL = false; + root = "${cfg.package}"; + + extraConfig = '' + add_header X-Frame-Options SAMEORIGIN; + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + ''; + + locations."/" = { + extraConfig = '' + ''; + }; + + locations."~ ^/app\\.php(/|$)" = { + extraConfig = '' + fastcgi_pass unix:${config.services.phpfpm.pools."${poolName}".socket}; + include ${pkgs.nginx}/conf/fastcgi_params; + include ${pkgs.nginx}/conf/fastcgi.conf; + fastcgi_index ${conf.pkg}/index.php; + ''; + }; + + systemd.services.ulogger-install = { + description = "ulogger install service"; + wantedBy = [ "multi-user.target" ]; + before = [ "phpfpm-ulogger.service" ]; + after = [ "mysql.service" "postgresql.service" ]; + path = with pkgs; [ coreutils php phpPackages.composer ]; + + serviceConfig = { + User = cfg.user; + Type = "oneshot"; + RemainAfterExit = "yes"; + PermissionsStartOnly = true; + }; + + preStart = '' + mkdir -p "${cfg.dataDir}" + mkdir -p "${cfg.dataDir}/uploads" + chown ${cfg.user}:nginx "${cfg.dataDir}" + ''; + + environment = { + ULOGGER_ADMIN_USER = "admin"; + ULOGGER_ADMIN_PASSWORD = "admin"; + }; + + script = '' + echo "Setting up wallabag files in ${cfg.dataDir} ..." + cd "${cfg.dataDir}" + + rm -rf var/cache/* + rm -f app + ln -sf ${appDir} app + ln -sf ${cfg.package}/composer.{json,lock} . + + if [ ! -f installed ]; then + echo "Install file not found, installing ..." + # TODO, taken from https://github.com/bfabiszewski/ulogger-server/blob/master/.docker/init.sh + su postgres -c "psql -U ulogger < ${appDir}/scripts/ulogger.pgsql" + su postgres -c "psql -d ulogger -c \"INSERT INTO users (login, password, admin) VALUES ('$ULOGGER_ADMIN_USER', '$ULOGGER_ADMIN_PASSWORD', TRUE)\"" + touch installed + fi + ''; + }; + }; + + meta = with stdenv.lib; { + maintainers = with maintainers; [ nadrieril ]; + }; + + }; +} diff --git a/pkgs/ulogger.nix b/pkgs/ulogger.nix new file mode 100644 index 00000000..7ad5dc3f --- /dev/null +++ b/pkgs/ulogger.nix @@ -0,0 +1,26 @@ +{ lib, stdenv, fetchurl, fetchpatch }: + +let + pname = "ulogger-server"; + version = "1.1"; +in +stdenv.mkDerivation { + inherit pname version; + + # Release tarball includes vendored files + src = fetchurl { + url = "https://github.com/bfabiszewski/ulogger-server/archive/refs/tags/v${version}.tar.gz"; + hash = ""; + }; + + dontBuild = true; + + installPhase = '' + runHook preInstall + rm -R .docker + rm -R .tests + mkdir $out + cp -R * $out/ + runHook postInstall + ''; +}