Change:
<del> { config, lib, pkgs, ... }: with lib; # TODO: are these php-packages needed? #imagick #php-geoip -> php.ini: extension = geoip.so #expat let cfg = config.services.restya-board; fpm = config.services.phpfpm.pools.${poolName}; runDir = "/run/restya-board"; poolName = "restya-board"; in { ###### interface options = { services.restya-board = { enable = mkEnableOption (lib.mdDoc "restya-board"); dataDir = mkOption { type = types.path; default = "/var/lib/restya-board"; description = lib.mdDoc '' Data of the application. ''; }; user = mkOption { type = types.str; default = "restya-board"; description = lib.mdDoc '' User account under which the web-application runs. ''; }; group = mkOption { type = types.str; default = "nginx"; description = lib.mdDoc '' Group account under which the web-application runs. ''; }; virtualHost = { serverName = mkOption { type = types.str; default = "restya.board"; description = lib.mdDoc '' Name of the nginx virtualhost to use. ''; }; listenHost = mkOption { type = types.str; default = "localhost"; description = lib.mdDoc '' Listen address for the virtualhost to use. ''; }; listenPort = mkOption { type = types.port; default = 3000; description = lib.mdDoc '' Listen port for the virtualhost to use. ''; }; }; database = { host = mkOption { type = types.nullOr types.str; default = null; description = lib.mdDoc '' Host of the database. Leave 'null' to use a local PostgreSQL database. A local PostgreSQL database is initialized automatically. ''; }; port = mkOption { type = types.nullOr types.int; default = 5432; description = lib.mdDoc '' The database's port. ''; }; name = mkOption { type = types.str; default = "restya_board"; description = lib.mdDoc '' Name of the database. The database must exist. ''; }; user = mkOption { type = types.str; default = "restya_board"; description = lib.mdDoc '' The database user. The user must exist and have access to the specified database. ''; }; passwordFile = mkOption { type = types.nullOr types.path; default = null; description = lib.mdDoc '' The database user's password. 'null' if no password is set. ''; }; }; email = { server = mkOption { type = types.nullOr types.str; default = null; example = "localhost"; description = lib.mdDoc '' Hostname to send outgoing mail. Null to use the system MTA. ''; }; port = mkOption { type = types.port; default = 25; description = lib.mdDoc '' Port used to connect to SMTP server. ''; }; login = mkOption { type = types.str; default = ""; description = lib.mdDoc '' SMTP authentication login used when sending outgoing mail. ''; }; password = mkOption { type = types.str; default = ""; description = lib.mdDoc '' SMTP authentication password used when sending outgoing mail. ATTENTION: The password is stored world-readable in the nix-store! ''; }; }; timezone = mkOption { type = types.lines; default = "GMT"; description = lib.mdDoc '' Timezone the web-app runs in. ''; }; }; }; ###### implementation config = mkIf cfg.enable { services.phpfpm.pools = { ${poolName} = { inherit (cfg) user group; phpOptions = '' date.timezone = "CET" ${optionalString (cfg.email.server != null) '' SMTP = ${cfg.email.server} smtp_port = ${toString cfg.email.port} auth_username = ${cfg.email.login} auth_password = ${cfg.email.password} ''} ''; settings = mapAttrs (name: mkDefault) { "listen.owner" = "nginx"; "listen.group" = "nginx"; "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; }; }; }; services.nginx.enable = true; services.nginx.virtualHosts.${cfg.virtualHost.serverName} = { listen = [ { addr = cfg.virtualHost.listenHost; port = cfg.virtualHost.listenPort; } ]; serverName = cfg.virtualHost.serverName; root = runDir; extraConfig = '' index index.html index.php; gzip on; gzip_comp_level 6; gzip_min_length  1100; gzip_buffers 16 8k; gzip_proxied any; gzip_types text/plain application/xml text/css text/js text/xml application/x-javascript text/javascript application/json application/xml+rss; client_max_body_size 300M; rewrite ^/oauth/authorize$ /server/php/authorize.php last; rewrite ^/oauth_callback/([a-zA-Z0-9_.]*)/([a-zA-Z0-9_.]*)$ /server/php/oauth_callback.php?plugin=$1&code=$2 last; rewrite ^/download/([0-9]*)/([a-zA-Z0-9_.]*)$ /server/php/download.php?id=$1&hash=$2 last; rewrite ^/ical/([0-9]*)/([0-9]*)/([a-z0-9]*).ics$ /server/php/ical.php?board_id=$1&user_id=$2&hash=$3 last; rewrite ^/api/(.*)$ /server/php/R/r.php?_url=$1&$args last; rewrite ^/api_explorer/api-docs/$ /client/api_explorer/api-docs/index.php last; ''; locations."/".root = "${runDir}/client"; locations."~ .php$" = { tryFiles = "$uri =404"; extraConfig = '' include ${config.services.nginx.package}/conf/fastcgi_params; fastcgi_pass    unix:${fpm.socket}; fastcgi_index   index.php; fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param   PHP_VALUE "upload_max_filesize=9G n post_max_size=9G n max_execution_time=200 n max_input_time=200 n memory_limit=256M"; ''; }; locations."~* .(css|js|less|html|ttf|woff|jpg|jpeg|gif|png|bmp|ico)" = { root = "${runDir}/client"; extraConfig = '' if (-f $request_filename) { break; } rewrite ^/img/([a-zA-Z_]*)/([a-zA-Z_]*)/([a-zA-Z0-9_.]*)$ /server/php/image.php?size=$1&model=$2&filename=$3 last; add_header        Cache-Control public; add_header        Cache-Control must-revalidate; expires           7d; ''; }; }; systemd.services.restya-board-init = { description = "Restya board initialization"; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; wantedBy = [ "multi-user.target" ]; requires = lib.optional (cfg.database.host != null) "postgresql.service"; after = [ "network.target" ] ++ (lib.optional (cfg.database.host != null) "postgresql.service"); script = '' rm -rf "${runDir}" mkdir -m 750 -p "${runDir}" cp -r "${pkgs.restya-board}/"* "${runDir}" sed -i "s/@restya.com/@${cfg.virtualHost.serverName}/g" "${runDir}/sql/restyaboard_with_empty_data.sql" rm -rf "${runDir}/media" rm -rf "${runDir}/client/img" chmod -R 0750 "${runDir}" sed -i "s@^php@${config.services.phpfpm.phpPackage}/bin/php@" "${runDir}/server/php/shell/"*.sh ${if (cfg.database.host == null) then '' sed -i "s/^.*'R_DB_HOST'.*$/define('R_DB_HOST', 'localhost');/g" "${runDir}/server/php/config.inc.php" sed -i "s/^.*'R_DB_PASSWORD'.*$/define('R_DB_PASSWORD', 'restya');/g" "${runDir}/server/php/config.inc.php" '' else '' sed -i "s/^.*'R_DB_HOST'.*$/define('R_DB_HOST', '${cfg.database.host}');/g" "${runDir}/server/php/config.inc.php" sed -i "s/^.*'R_DB_PASSWORD'.*$/define('R_DB_PASSWORD', ${if cfg.database.passwordFile == null then "''" else "'$(cat ${cfg.database.passwordFile})');/g"}" "${runDir}/server/php/config.inc.php" ''} sed -i "s/^.*'R_DB_PORT'.*$/define('R_DB_PORT', '${toString cfg.database.port}');/g" "${runDir}/server/php/config.inc.php" sed -i "s/^.*'R_DB_NAME'.*$/define('R_DB_NAME', '${cfg.database.name}');/g" "${runDir}/server/php/config.inc.php" sed -i "s/^.*'R_DB_USER'.*$/define('R_DB_USER', '${cfg.database.user}');/g" "${runDir}/server/php/config.inc.php" chmod 0400 "${runDir}/server/php/config.inc.php" ln -sf "${cfg.dataDir}/media" "${runDir}/media" ln -sf "${cfg.dataDir}/client/img" "${runDir}/client/img" chmod g+w "${runDir}/tmp/cache" chown -R "${cfg.user}":"${cfg.group}" "${runDir}" mkdir -m 0750 -p "${cfg.dataDir}" mkdir -m 0750 -p "${cfg.dataDir}/media" mkdir -m 0750 -p "${cfg.dataDir}/client/img" cp -r "${pkgs.restya-board}/media/"* "${cfg.dataDir}/media" cp -r "${pkgs.restya-board}/client/img/"* "${cfg.dataDir}/client/img" chown "${cfg.user}":"${cfg.group}" "${cfg.dataDir}" chown -R "${cfg.user}":"${cfg.group}" "${cfg.dataDir}/media" chown -R "${cfg.user}":"${cfg.group}" "${cfg.dataDir}/client/img" ${optionalString (cfg.database.host == null) '' if ! [ -e "${cfg.dataDir}/.db-initialized" ]; then ${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser}  ${config.services.postgresql.package}/bin/psql -U ${config.services.postgresql.superUser}  -c "CREATE USER ${cfg.database.user} WITH ENCRYPTED PASSWORD 'restya'" ${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser}  ${config.services.postgresql.package}/bin/psql -U ${config.services.postgresql.superUser}  -c "CREATE DATABASE ${cfg.database.name} OWNER ${cfg.database.user} ENCODING 'UTF8' TEMPLATE template0" ${pkgs.sudo}/bin/sudo -u ${cfg.user}  ${config.services.postgresql.package}/bin/psql -U ${cfg.database.user}  -d ${cfg.database.name} -f "${runDir}/sql/restyaboard_with_empty_data.sql" touch "${cfg.dataDir}/.db-initialized" fi ''} ''; }; systemd.timers.restya-board = { description = "restya-board scripts for e.g. email notification"; wantedBy = [ "timers.target" ]; after = [ "restya-board-init.service" ]; requires = [ "restya-board-init.service" ]; timerConfig = { OnUnitInactiveSec = "60s"; Unit = "restya-board-timers.service"; }; }; systemd.services.restya-board-timers = { description = "restya-board scripts for e.g. email notification"; serviceConfig.Type = "oneshot"; serviceConfig.User = cfg.user; after = [ "restya-board-init.service" ]; requires = [ "restya-board-init.service" ]; script = '' /bin/sh ${runDir}/server/php/shell/instant_email_notification.sh 2> /dev/null || true /bin/sh ${runDir}/server/php/shell/periodic_email_notification.sh 2> /dev/null || true /bin/sh ${runDir}/server/php/shell/imap.sh 2> /dev/null || true /bin/sh ${runDir}/server/php/shell/webhook.sh 2> /dev/null || true /bin/sh ${runDir}/server/php/shell/card_due_notification.sh 2> /dev/null || true ''; }; users.users.restya-board = { isSystemUser = true; createHome = false; home = runDir; group  = "restya-board"; }; users.groups.restya-board = {}; services.postgresql.enable = mkIf (cfg.database.host == null) true; services.postgresql.identMap = optionalString (cfg.database.host == null) '' restya-board-users restya-board restya_board ''; services.postgresql.authentication = optionalString (cfg.database.host == null) '' local restya_board all ident map=restya-board-users ''; }; } </del>

Discussion:
fails when installing using a custom option; this is the service status: The issue is caused by the hardcoded database name in : the database name should be . I have not tested it directly but looking at the module source code I'm almost sure this also applies to and options. Use this service declaration:
thanks for reporting this. I've never used this service, but I would be willing to take a look and fix this if you were willing to test it for me. Sound good?
Hello Aaron, Aaron Andersen <: yes! thank you for your offer In the next couple of weeks I'll be pretty busy, but I should be able to test later on I'd also like to learn how to test local defined (i.e. in a git branch) changes to the packages/services: do you have a pointer to the relevant documentation please, just a pointer: I'll do my homework :-) Thanks! Gio' [...]
I've found a few issues. The package in nixpkgs hasn't been updated in over 2 years. It also looks like the module author has likely moved on, so the module hasn't seen any support or maintenance in the last 2 years either. Generally at this point if no one is willing to take over maintenance of at least the package we would want to remove this from nixpkgs because this is a web application and we shouldn't have users thinking they are using something up to date and secure when it is actually lagging 7 releases (2 years) behind upstream. That being said I really don't enjoy removing software from nixpkgs that people are using, or want to use... If you're really keen on using this software on NixOS I suggest we look for a new package/module maintainer. Please let me know if you want to pursue this.
Thank you for your contributions. This has been automatically marked as stale because it has had no activity for 180 days. If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity. Here are suggestions that might help resolve this more quickly: for maintainers and people that previously touched the related code and @ mention them in a comment. on the . 3. Ask on the on .