at 23.11-pre 6.0 kB view raw
1{ config, lib, pkgs, utils, ... }: 2 3let 4 inherit (lib) mkDefault mkEnableOption mkIf mkOption types literalExpression; 5 cfg = config.services.engelsystem; 6in { 7 options = { 8 services.engelsystem = { 9 enable = mkOption { 10 default = false; 11 example = true; 12 description = lib.mdDoc '' 13 Whether to enable engelsystem, an online tool for coordinating volunteers 14 and shifts on large events. 15 ''; 16 type = lib.types.bool; 17 }; 18 19 domain = mkOption { 20 type = types.str; 21 example = "engelsystem.example.com"; 22 description = lib.mdDoc "Domain to serve on."; 23 }; 24 25 package = mkOption { 26 type = types.package; 27 description = lib.mdDoc "Engelsystem package used for the service."; 28 default = pkgs.engelsystem; 29 defaultText = literalExpression "pkgs.engelsystem"; 30 }; 31 32 createDatabase = mkOption { 33 type = types.bool; 34 default = true; 35 description = lib.mdDoc '' 36 Whether to create a local database automatically. 37 This will override every database setting in {option}`services.engelsystem.config`. 38 ''; 39 }; 40 }; 41 42 services.engelsystem.config = mkOption { 43 type = types.attrs; 44 default = { 45 database = { 46 host = "localhost"; 47 database = "engelsystem"; 48 username = "engelsystem"; 49 }; 50 }; 51 example = { 52 maintenance = false; 53 database = { 54 host = "database.example.com"; 55 database = "engelsystem"; 56 username = "engelsystem"; 57 password._secret = "/var/keys/engelsystem/database"; 58 }; 59 email = { 60 driver = "smtp"; 61 host = "smtp.example.com"; 62 port = 587; 63 from.address = "engelsystem@example.com"; 64 from.name = "example engelsystem"; 65 encryption = "tls"; 66 username = "engelsystem@example.com"; 67 password._secret = "/var/keys/engelsystem/mail"; 68 }; 69 autoarrive = true; 70 min_password_length = 6; 71 default_locale = "de_DE"; 72 }; 73 description = lib.mdDoc '' 74 Options to be added to config.php, as a nix attribute set. Options containing secret data 75 should be set to an attribute set containing the attribute _secret - a string pointing to a 76 file containing the value the option should be set to. See the example to get a better 77 picture of this: in the resulting config.php file, the email.password key will be set to 78 the contents of the /var/keys/engelsystem/mail file. 79 80 See https://engelsystem.de/doc/admin/configuration/ for available options. 81 82 Note that the admin user login credentials cannot be set here - they always default to 83 admin:asdfasdf. Log in and change them immediately. 84 ''; 85 }; 86 }; 87 88 config = mkIf cfg.enable { 89 # create database 90 services.mysql = mkIf cfg.createDatabase { 91 enable = true; 92 package = mkDefault pkgs.mariadb; 93 ensureUsers = [{ 94 name = "engelsystem"; 95 ensurePermissions = { "engelsystem.*" = "ALL PRIVILEGES"; }; 96 }]; 97 ensureDatabases = [ "engelsystem" ]; 98 }; 99 100 environment.etc."engelsystem/config.php".source = 101 pkgs.writeText "config.php" '' 102 <?php 103 return json_decode(file_get_contents("/var/lib/engelsystem/config.json"), true); 104 ''; 105 106 services.phpfpm.pools.engelsystem = { 107 user = "engelsystem"; 108 settings = { 109 "listen.owner" = config.services.nginx.user; 110 "pm" = "dynamic"; 111 "pm.max_children" = 32; 112 "pm.max_requests" = 500; 113 "pm.start_servers" = 2; 114 "pm.min_spare_servers" = 2; 115 "pm.max_spare_servers" = 5; 116 "php_admin_value[error_log]" = "stderr"; 117 "php_admin_flag[log_errors]" = true; 118 "catch_workers_output" = true; 119 }; 120 }; 121 122 services.nginx = { 123 enable = true; 124 virtualHosts."${cfg.domain}".locations = { 125 "/" = { 126 root = "${cfg.package}/share/engelsystem/public"; 127 extraConfig = '' 128 index index.php; 129 try_files $uri $uri/ /index.php?$args; 130 autoindex off; 131 ''; 132 }; 133 "~ \\.php$" = { 134 root = "${cfg.package}/share/engelsystem/public"; 135 extraConfig = '' 136 fastcgi_pass unix:${config.services.phpfpm.pools.engelsystem.socket}; 137 fastcgi_index index.php; 138 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 139 include ${config.services.nginx.package}/conf/fastcgi_params; 140 include ${config.services.nginx.package}/conf/fastcgi.conf; 141 ''; 142 }; 143 }; 144 }; 145 146 systemd.services."engelsystem-init" = { 147 wantedBy = [ "multi-user.target" ]; 148 serviceConfig = { Type = "oneshot"; }; 149 script = 150 let 151 genConfigScript = pkgs.writeScript "engelsystem-gen-config.sh" 152 (utils.genJqSecretsReplacementSnippet cfg.config "config.json"); 153 in '' 154 umask 077 155 mkdir -p /var/lib/engelsystem/storage/app 156 mkdir -p /var/lib/engelsystem/storage/cache/views 157 cd /var/lib/engelsystem 158 ${genConfigScript} 159 chmod 400 config.json 160 chown -R engelsystem . 161 ''; 162 }; 163 systemd.services."engelsystem-migrate" = { 164 wantedBy = [ "multi-user.target" ]; 165 serviceConfig = { 166 Type = "oneshot"; 167 User = "engelsystem"; 168 Group = "engelsystem"; 169 }; 170 script = '' 171 ${cfg.package}/bin/migrate 172 ''; 173 after = [ "engelsystem-init.service" "mysql.service" ]; 174 }; 175 systemd.services."phpfpm-engelsystem".after = 176 [ "engelsystem-migrate.service" ]; 177 178 users.users.engelsystem = { 179 isSystemUser = true; 180 createHome = true; 181 home = "/var/lib/engelsystem/storage"; 182 group = "engelsystem"; 183 }; 184 users.groups.engelsystem = { }; 185 }; 186}