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