]> git.immae.eu Git - perso/Immae/Config/Nix.git/blobdiff - modules/websites/httpd-service-builder.nix
Squash changes containing private information
[perso/Immae/Config/Nix.git] / modules / websites / httpd-service-builder.nix
diff --git a/modules/websites/httpd-service-builder.nix b/modules/websites/httpd-service-builder.nix
deleted file mode 100644 (file)
index 1f7488d..0000000
+++ /dev/null
@@ -1,735 +0,0 @@
-# to help backporting this builder should stay as close as possible to
-# nixos/modules/services/web-servers/apache-httpd/default.nix
-{ httpdName, withUsers ? true }:
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
-
-  cfg = config.services.httpd."${httpdName}";
-
-  runtimeDir = "/run/httpd_${httpdName}";
-
-  pkg = cfg.package.out;
-
-  httpdConf = cfg.configFile;
-
-  php = cfg.phpPackage.override { apacheHttpd = pkg.dev; /* otherwise it only gets .out */ };
-
-  phpMajorVersion = lib.versions.major (lib.getVersion php);
-
-  mod_perl = pkgs.apacheHttpdPackages.mod_perl.override { apacheHttpd = pkg; };
-
-  vhosts = attrValues cfg.virtualHosts;
-
-  mkListenInfo = hostOpts:
-    if hostOpts.listen != [] then hostOpts.listen
-    else (
-      optional (hostOpts.onlySSL || hostOpts.addSSL || hostOpts.forceSSL) { ip = "*"; port = 443; ssl = true; } ++
-      optional (!hostOpts.onlySSL) { ip = "*"; port = 80; ssl = false; }
-    );
-
-  listenInfo = unique (concatMap mkListenInfo vhosts);
-
-  enableHttp2 = any (vhost: vhost.http2) vhosts;
-  enableSSL = any (listen: listen.ssl) listenInfo;
-  enableUserDir = any (vhost: vhost.enableUserDir) vhosts;
-
-  # NOTE: generally speaking order of modules is very important
-  modules =
-    [ # required apache modules our httpd service cannot run without
-      "authn_core" "authz_core"
-      "log_config"
-      "mime" "autoindex" "negotiation" "dir"
-      "alias" "rewrite"
-      "unixd" "slotmem_shm" "socache_shmcb"
-      "mpm_${cfg.multiProcessingModule}"
-    ]
-    ++ (if cfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ])
-    ++ optional enableHttp2 "http2"
-    ++ optional enableSSL "ssl"
-    ++ optional enableUserDir "userdir"
-    ++ optional cfg.enableMellon { name = "auth_mellon"; path = "${pkgs.apacheHttpdPackages.mod_auth_mellon}/modules/mod_auth_mellon.so"; }
-    ++ optional cfg.enablePHP { name = "php${phpMajorVersion}"; path = "${php}/modules/libphp${phpMajorVersion}.so"; }
-    ++ optional cfg.enablePerl { name = "perl"; path = "${mod_perl}/modules/mod_perl.so"; }
-    ++ cfg.extraModules;
-
-  loggingConf = (if cfg.logFormat != "none" then ''
-    ErrorLog ${cfg.logDir}/error.log
-
-    LogLevel notice
-
-    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
-    LogFormat "%h %l %u %t \"%r\" %>s %b" common
-    LogFormat "%{Referer}i -> %U" referer
-    LogFormat "%{User-agent}i" agent
-
-    CustomLog ${cfg.logDir}/access.log ${cfg.logFormat}
-  '' else ''
-    ErrorLog /dev/null
-  '');
-
-
-  browserHacks = ''
-    <IfModule mod_setenvif.c>
-        BrowserMatch "Mozilla/2" nokeepalive
-        BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
-        BrowserMatch "RealPlayer 4\.0" force-response-1.0
-        BrowserMatch "Java/1\.0" force-response-1.0
-        BrowserMatch "JDK/1\.0" force-response-1.0
-        BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully
-        BrowserMatch "^WebDrive" redirect-carefully
-        BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully
-        BrowserMatch "^gnome-vfs" redirect-carefully
-    </IfModule>
-  '';
-
-
-  sslConf = ''
-    <IfModule mod_ssl.c>
-        SSLSessionCache shmcb:${runtimeDir}/ssl_scache(512000)
-
-        Mutex posixsem
-
-        SSLRandomSeed startup builtin
-        SSLRandomSeed connect builtin
-
-        SSLProtocol ${cfg.sslProtocols}
-        SSLCipherSuite ${cfg.sslCiphers}
-        SSLHonorCipherOrder on
-    </IfModule>
-  '';
-
-
-  mimeConf = ''
-    TypesConfig ${pkg}/conf/mime.types
-
-    AddType application/x-x509-ca-cert .crt
-    AddType application/x-pkcs7-crl    .crl
-    AddType application/x-httpd-php    .php .phtml
-
-    <IfModule mod_mime_magic.c>
-        MIMEMagicFile ${pkg}/conf/magic
-    </IfModule>
-  '';
-
-  mkVHostConf = hostOpts:
-    let
-      adminAddr = if hostOpts.adminAddr != null then hostOpts.adminAddr else cfg.adminAddr;
-      listen = filter (listen: !listen.ssl) (mkListenInfo hostOpts);
-      listenSSL = filter (listen: listen.ssl) (mkListenInfo hostOpts);
-
-      useACME = hostOpts.enableACME || hostOpts.useACMEHost != null;
-      sslCertDir =
-        if hostOpts.enableACME then config.security.acme.certs.${hostOpts.hostName}.directory
-        else if hostOpts.useACMEHost != null then config.security.acme.certs.${hostOpts.useACMEHost}.directory
-        else abort "This case should never happen.";
-
-      sslServerCert = if useACME then "${sslCertDir}/full.pem" else hostOpts.sslServerCert;
-      sslServerKey = if useACME then "${sslCertDir}/key.pem" else hostOpts.sslServerKey;
-      sslServerChain = if useACME then "${sslCertDir}/fullchain.pem" else hostOpts.sslServerChain;
-
-      acmeChallenge = optionalString useACME ''
-        Alias /.well-known/acme-challenge/ "${hostOpts.acmeRoot}/.well-known/acme-challenge/"
-        <Directory "${hostOpts.acmeRoot}">
-            AllowOverride None
-            Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
-            Require method GET POST OPTIONS
-            Require all granted
-        </Directory>
-      '';
-    in
-      optionalString (listen != []) ''
-        <VirtualHost ${concatMapStringsSep " " (listen: "${listen.ip}:${toString listen.port}") listen}>
-            ServerName ${hostOpts.hostName}
-            ${concatMapStrings (alias: "ServerAlias ${alias}\n") hostOpts.serverAliases}
-            ServerAdmin ${adminAddr}
-            <IfModule mod_ssl.c>
-                SSLEngine off
-            </IfModule>
-            ${acmeChallenge}
-            ${if hostOpts.forceSSL then ''
-              <IfModule mod_rewrite.c>
-                  RewriteEngine on
-                  RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge [NC]
-                  RewriteCond %{HTTPS} off
-                  RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
-              </IfModule>
-            '' else mkVHostCommonConf hostOpts}
-        </VirtualHost>
-      '' +
-      optionalString (listenSSL != []) ''
-        <VirtualHost ${concatMapStringsSep " " (listen: "${listen.ip}:${toString listen.port}") listenSSL}>
-            ServerName ${hostOpts.hostName}
-            ${concatMapStrings (alias: "ServerAlias ${alias}\n") hostOpts.serverAliases}
-            ServerAdmin ${adminAddr}
-            SSLEngine on
-            SSLCertificateFile ${sslServerCert}
-            SSLCertificateKeyFile ${sslServerKey}
-            ${optionalString hostOpts.http2 "Protocols h2 h2c http/1.1"}
-            ${acmeChallenge}
-            ${mkVHostCommonConf hostOpts}
-        </VirtualHost>
-      ''
-  ;
-
-  mkVHostCommonConf = hostOpts:
-    let
-      documentRoot = if hostOpts.documentRoot != null
-        then hostOpts.documentRoot
-        else pkgs.runCommand "empty" { preferLocalBuild = true; } "mkdir -p $out"
-      ;
-
-      mkLocations = locations: concatStringsSep "\n" (map (config: ''
-        <Location ${config.location}>
-          ${optionalString (config.proxyPass != null) ''
-            <IfModule mod_proxy.c>
-                ProxyPass ${config.proxyPass}
-                ProxyPassReverse ${config.proxyPass}
-            </IfModule>
-          ''}
-          ${optionalString (config.index != null) ''
-            <IfModule mod_dir.c>
-                DirectoryIndex ${config.index}
-            </IfModule>
-          ''}
-          ${optionalString (config.alias != null) ''
-            <IfModule mod_alias.c>
-                Alias "${config.alias}"
-            </IfModule>
-          ''}
-          ${config.extraConfig}
-        </Location>
-      '') (sortProperties (mapAttrsToList (k: v: v // { location = k; }) locations)));
-    in
-      ''
-        ${optionalString cfg.logPerVirtualHost ''
-          ErrorLog ${cfg.logDir}/error-${hostOpts.hostName}.log
-          CustomLog ${cfg.logDir}/access-${hostOpts.hostName}.log ${hostOpts.logFormat}
-        ''}
-
-        ${optionalString (hostOpts.robotsEntries != "") ''
-          Alias /robots.txt ${pkgs.writeText "robots.txt" hostOpts.robotsEntries}
-        ''}
-
-        DocumentRoot "${documentRoot}"
-
-        <Directory "${documentRoot}">
-            Options Indexes FollowSymLinks
-            AllowOverride None
-            Require all granted
-        </Directory>
-
-        ${optionalString hostOpts.enableUserDir ''
-          UserDir public_html
-          UserDir disabled root
-          <Directory "/home/*/public_html">
-              AllowOverride FileInfo AuthConfig Limit Indexes
-              Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
-              <Limit GET POST OPTIONS>
-                  Require all granted
-              </Limit>
-              <LimitExcept GET POST OPTIONS>
-                  Require all denied
-              </LimitExcept>
-          </Directory>
-        ''}
-
-        ${optionalString (hostOpts.globalRedirect != null && hostOpts.globalRedirect != "") ''
-          RedirectPermanent / ${hostOpts.globalRedirect}
-        ''}
-
-        ${
-          let makeDirConf = elem: ''
-                Alias ${elem.urlPath} ${elem.dir}/
-                <Directory ${elem.dir}>
-                    Options +Indexes
-                    Require all granted
-                    AllowOverride All
-                </Directory>
-              '';
-          in concatMapStrings makeDirConf hostOpts.servedDirs
-        }
-
-        ${mkLocations hostOpts.locations}
-        ${hostOpts.extraConfig}
-      ''
-  ;
-
-
-  confFile = pkgs.writeText "httpd.conf" ''
-
-    ServerRoot ${pkg}
-    ServerName ${config.networking.hostName}
-    DefaultRuntimeDir ${runtimeDir}/runtime
-
-    PidFile ${runtimeDir}/httpd.pid
-
-    ${optionalString (cfg.multiProcessingModule != "prefork") ''
-      # mod_cgid requires this.
-      ScriptSock ${runtimeDir}/cgisock
-    ''}
-
-    <IfModule prefork.c>
-        MaxClients           ${toString cfg.maxClients}
-        MaxRequestsPerChild  ${toString cfg.maxRequestsPerChild}
-    </IfModule>
-
-    ${let
-        toStr = listen: "Listen ${listen.ip}:${toString listen.port} ${if listen.ssl then "https" else "http"}";
-        uniqueListen = uniqList {inputList = map toStr listenInfo;};
-      in concatStringsSep "\n" uniqueListen
-    }
-
-    User ${cfg.user}
-    Group ${cfg.group}
-
-    ${let
-        mkModule = module:
-          if isString module then { name = module; path = "${pkg}/modules/mod_${module}.so"; }
-          else if isAttrs module then { inherit (module) name path; }
-          else throw "Expecting either a string or attribute set including a name and path.";
-      in
-        concatMapStringsSep "\n" (module: "LoadModule ${module.name}_module ${module.path}") (unique (map mkModule modules))
-    }
-
-    AddHandler type-map var
-
-    <Files ~ "^\.ht">
-        Require all denied
-    </Files>
-
-    ${mimeConf}
-    ${loggingConf}
-    ${browserHacks}
-
-    Include ${pkg}/conf/extra/httpd-default.conf
-    Include ${pkg}/conf/extra/httpd-autoindex.conf
-    Include ${pkg}/conf/extra/httpd-multilang-errordoc.conf
-    Include ${pkg}/conf/extra/httpd-languages.conf
-
-    TraceEnable off
-
-    ${sslConf}
-
-    # Fascist default - deny access to everything.
-    <Directory />
-        Options FollowSymLinks
-        AllowOverride None
-        Require all denied
-    </Directory>
-
-    ${cfg.extraConfig}
-
-    ${concatMapStringsSep "\n" mkVHostConf vhosts}
-  '';
-
-  # Generate the PHP configuration file.  Should probably be factored
-  # out into a separate module.
-  phpIni = pkgs.runCommand "php.ini"
-    { options = cfg.phpOptions;
-      preferLocalBuild = true;
-    }
-    ''
-      cat ${php}/etc/php.ini > $out
-      echo "$options" >> $out
-    '';
-
-in
-
-
-{
-
-  imports = [
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "extraSubservices" ] "Most existing subservices have been ported to the NixOS module system. Please update your configuration accordingly.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "stateDir" ] "The httpd module now uses /run/httpd as a runtime directory.")
-
-    # virtualHosts options
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "documentRoot" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "enableSSL" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "enableUserDir" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "globalRedirect" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "hostName" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "listen" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "robotsEntries" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "servedDirs" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "servedFiles" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "serverAliases" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "sslServerCert" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "sslServerChain" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-    (mkRemovedOptionModule [ "services" "httpd" httpdName "sslServerKey" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
-  ];
-
-  # interface
-
-  options = {
-
-    services.httpd."${httpdName}" = {
-
-      enable = mkEnableOption "the Apache HTTP Server";
-
-      package = mkOption {
-        type = types.package;
-        default = pkgs.apacheHttpd;
-        defaultText = "pkgs.apacheHttpd";
-        description = ''
-          Overridable attribute of the Apache HTTP Server package to use.
-        '';
-      };
-
-      configFile = mkOption {
-        type = types.path;
-        default = confFile;
-        defaultText = "confFile";
-        example = literalExample ''pkgs.writeText "httpd.conf" "# my custom config file ..."'';
-        description = ''
-          Override the configuration file used by Apache. By default,
-          NixOS generates one automatically.
-        '';
-      };
-
-      extraConfig = mkOption {
-        type = types.lines;
-        default = "";
-        description = ''
-          Configuration lines appended to the generated Apache
-          configuration file. Note that this mechanism will not work
-          when <option>configFile</option> is overridden.
-        '';
-      };
-
-      extraModules = mkOption {
-        type = types.listOf types.unspecified;
-        default = [];
-        example = literalExample ''
-          [
-            "proxy_connect"
-            { name = "jk"; path = "''${pkgs.tomcat_connectors}/modules/mod_jk.so"; }
-          ]
-        '';
-        description = ''
-          Additional Apache modules to be used. These can be
-          specified as a string in the case of modules distributed
-          with Apache, or as an attribute set specifying the
-          <varname>name</varname> and <varname>path</varname> of the
-          module.
-        '';
-      };
-
-      adminAddr = mkOption {
-        type = types.str;
-        example = "admin@example.org";
-        description = "E-mail address of the server administrator.";
-      };
-
-      logFormat = mkOption {
-        type = types.str;
-        default = "common";
-        example = "combined";
-        description = ''
-          Log format for log files. Possible values are: combined, common, referer, agent.
-          See <link xlink:href="https://httpd.apache.org/docs/2.4/logs.html"/> for more details.
-        '';
-      };
-
-      logPerVirtualHost = mkOption {
-        type = types.bool;
-        default = true;
-        description = ''
-          If enabled, each virtual host gets its own
-          <filename>access.log</filename> and
-          <filename>error.log</filename>, namely suffixed by the
-          <option>hostName</option> of the virtual host.
-        '';
-      };
-
-      user = mkOption {
-        type = types.str;
-        default = "wwwrun";
-        description = ''
-          User account under which httpd runs.
-        '';
-      };
-
-      group = mkOption {
-        type = types.str;
-        default = "wwwrun";
-        description = ''
-          Group under which httpd runs.
-        '';
-      };
-
-      logDir = mkOption {
-        type = types.path;
-        default = "/var/log/httpd";
-        description = ''
-          Directory for Apache's log files. It is created automatically.
-        '';
-      };
-
-      virtualHosts = mkOption {
-        type = with types; attrsOf (submodule (import <nixpkgs/nixos/modules/services/web-servers/apache-httpd/vhost-options.nix>));
-        default = {
-          localhost = {
-            documentRoot = "${pkg}/htdocs";
-          };
-        };
-        example = literalExample ''
-          {
-            "foo.example.com" = {
-              forceSSL = true;
-              documentRoot = "/var/www/foo.example.com"
-            };
-            "bar.example.com" = {
-              addSSL = true;
-              documentRoot = "/var/www/bar.example.com";
-            };
-          }
-        '';
-        description = ''
-          Specification of the virtual hosts served by Apache. Each
-          element should be an attribute set specifying the
-          configuration of the virtual host.
-        '';
-      };
-
-      enableMellon = mkOption {
-        type = types.bool;
-        default = false;
-        description = "Whether to enable the mod_auth_mellon module.";
-      };
-
-      enablePHP = mkOption {
-        type = types.bool;
-        default = false;
-        description = "Whether to enable the PHP module.";
-      };
-
-      phpPackage = mkOption {
-        type = types.package;
-        default = pkgs.php;
-        defaultText = "pkgs.php";
-        description = ''
-          Overridable attribute of the PHP package to use.
-        '';
-      };
-
-      enablePerl = mkOption {
-        type = types.bool;
-        default = false;
-        description = "Whether to enable the Perl module (mod_perl).";
-      };
-
-      phpOptions = mkOption {
-        type = types.lines;
-        default = "";
-        example =
-          ''
-            date.timezone = "CET"
-          '';
-        description = ''
-          Options appended to the PHP configuration file <filename>php.ini</filename>.
-        '';
-      };
-
-      multiProcessingModule = mkOption {
-        type = types.enum [ "event" "prefork" "worker" ];
-        default = "prefork";
-        example = "worker";
-        description =
-          ''
-            Multi-processing module to be used by Apache. Available
-            modules are <literal>prefork</literal> (the default;
-            handles each request in a separate child process),
-            <literal>worker</literal> (hybrid approach that starts a
-            number of child processes each running a number of
-            threads) and <literal>event</literal> (a recent variant of
-            <literal>worker</literal> that handles persistent
-            connections more efficiently).
-          '';
-      };
-
-      maxClients = mkOption {
-        type = types.int;
-        default = 150;
-        example = 8;
-        description = "Maximum number of httpd processes (prefork)";
-      };
-
-      maxRequestsPerChild = mkOption {
-        type = types.int;
-        default = 0;
-        example = 500;
-        description = ''
-          Maximum number of httpd requests answered per httpd child (prefork), 0 means unlimited.
-        '';
-      };
-
-      sslCiphers = mkOption {
-        type = types.str;
-        default = "HIGH:!aNULL:!MD5:!EXP";
-        description = "Cipher Suite available for negotiation in SSL proxy handshake.";
-      };
-
-      sslProtocols = mkOption {
-        type = types.str;
-        default = "All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1";
-        example = "All -SSLv2 -SSLv3";
-        description = "Allowed SSL/TLS protocol versions.";
-      };
-    };
-
-  };
-
-  # implementation
-
-  config = mkIf cfg.enable {
-
-    assertions = [
-      {
-        assertion = all (hostOpts: !hostOpts.enableSSL) vhosts;
-        message = ''
-          The option `services.httpd.virtualHosts.<name>.enableSSL` no longer has any effect; please remove it.
-          Select one of `services.httpd.virtualHosts.<name>.addSSL`, `services.httpd.virtualHosts.<name>.forceSSL`,
-          or `services.httpd.virtualHosts.<name>.onlySSL`.
-        '';
-      }
-      {
-        assertion = all (hostOpts: with hostOpts; !(addSSL && onlySSL) && !(forceSSL && onlySSL) && !(addSSL && forceSSL)) vhosts;
-        message = ''
-          Options `services.httpd.virtualHosts.<name>.addSSL`,
-          `services.httpd.virtualHosts.<name>.onlySSL` and `services.httpd.virtualHosts.<name>.forceSSL`
-          are mutually exclusive.
-        '';
-      }
-      {
-        assertion = all (hostOpts: !(hostOpts.enableACME && hostOpts.useACMEHost != null)) vhosts;
-        message = ''
-          Options `services.httpd.virtualHosts.<name>.enableACME` and
-          `services.httpd.virtualHosts.<name>.useACMEHost` are mutually exclusive.
-        '';
-      }
-    ];
-
-    warnings =
-      mapAttrsToList (name: hostOpts: ''
-        Using config.services.httpd.virtualHosts."${name}".servedFiles is deprecated and will become unsupported in a future release. Your configuration will continue to work as is but please migrate your configuration to config.services.httpd.virtualHosts."${name}".locations before the 20.09 release of NixOS.
-      '') (filterAttrs (name: hostOpts: hostOpts.servedFiles != []) cfg.virtualHosts);
-
-    users.users = optionalAttrs (withUsers && cfg.user == "wwwrun") {
-      wwwrun = {
-        group = cfg.group;
-        description = "Apache httpd user";
-        uid = config.ids.uids.wwwrun;
-      };
-    };
-
-    users.groups = optionalAttrs (withUsers && cfg.group == "wwwrun") {
-      wwwrun.gid = config.ids.gids.wwwrun;
-    };
-
-    security.acme.certs = mapAttrs (name: hostOpts: {
-      user = cfg.user;
-      group = mkDefault cfg.group;
-      email = if hostOpts.adminAddr != null then hostOpts.adminAddr else cfg.adminAddr;
-      webroot = hostOpts.acmeRoot;
-      extraDomains = genAttrs hostOpts.serverAliases (alias: null);
-      postRun = "systemctl reload httpd.service";
-    }) (filterAttrs (name: hostOpts: hostOpts.enableACME) cfg.virtualHosts);
-
-    environment.systemPackages = [ pkg ];
-
-    # required for "apachectl configtest"
-    environment.etc."httpd/httpd_${httpdName}.conf".source = httpdConf;
-
-    services.httpd."${httpdName}" = { phpOptions =
-      ''
-        ; Needed for PHP's mail() function.
-        sendmail_path = sendmail -t -i
-
-        ; Don't advertise PHP
-        expose_php = off
-      '' + optionalString (config.time.timeZone != null) ''
-
-        ; Apparently PHP doesn't use $TZ.
-        date.timezone = "${config.time.timeZone}"
-      '';
-
-    extraModules = mkBefore [
-      # HTTP authentication mechanisms: basic and digest.
-      "auth_basic" "auth_digest"
-
-      # Authentication: is the user who he claims to be?
-      "authn_file" "authn_dbm" "authn_anon"
-
-      # Authorization: is the user allowed access?
-      "authz_user" "authz_groupfile" "authz_host"
-
-      # Other modules.
-      "ext_filter" "include" "env" "mime_magic"
-      "cern_meta" "expires" "headers" "usertrack" "setenvif"
-      "dav" "status" "asis" "info" "dav_fs"
-      "vhost_alias" "imagemap" "actions" "speling"
-      "proxy" "proxy_http"
-      "cache" "cache_disk"
-
-      # For compatibility with old configurations, the new module mod_access_compat is provided.
-      "access_compat"
-    ];
-    };
-
-    systemd.tmpfiles.rules =
-      let
-        svc = config.systemd.services."httpd${httpdName}".serviceConfig;
-      in
-        [
-          "d '${cfg.logDir}' 0700 ${svc.User} ${svc.Group}"
-          "Z '${cfg.logDir}' - ${svc.User} ${svc.Group}"
-        ];
-
-    systemd.services."httpd${httpdName}" =
-      let
-        vhostsACME = filter (hostOpts: hostOpts.enableACME) vhosts;
-      in
-      { description = "Apache HTTPD";
-
-        wantedBy = [ "multi-user.target" ];
-        wants = concatLists (map (hostOpts: [ "acme-${hostOpts.hostName}.service" "acme-selfsigned-${hostOpts.hostName}.service" ]) vhostsACME);
-        after = [ "network.target" "fs.target" ] ++ map (hostOpts: "acme-selfsigned-${hostOpts.hostName}.service") vhostsACME;
-
-        path =
-          [ pkg pkgs.coreutils pkgs.gnugrep ]
-          ++ optional cfg.enablePHP pkgs.system-sendmail; # Needed for PHP's mail() function.
-
-        environment =
-          optionalAttrs cfg.enablePHP { PHPRC = phpIni; }
-          // optionalAttrs cfg.enableMellon { LD_LIBRARY_PATH  = "${pkgs.xmlsec}/lib"; };
-
-        preStart =
-          ''
-            # Get rid of old semaphores.  These tend to accumulate across
-            # server restarts, eventually preventing it from restarting
-            # successfully.
-            for i in $(${pkgs.utillinux}/bin/ipcs -s | grep ' ${cfg.user} ' | cut -f2 -d ' '); do
-                ${pkgs.utillinux}/bin/ipcrm -s $i
-            done
-          '';
-
-        serviceConfig = {
-          ExecStart = "@${pkg}/bin/httpd httpd -f ${httpdConf}";
-          ExecStop = "${pkg}/bin/httpd -f ${httpdConf} -k graceful-stop";
-          ExecReload = "${pkg}/bin/httpd -f ${httpdConf} -k graceful";
-          User = "root";
-          Group = cfg.group;
-          Type = "forking";
-          PIDFile = "${runtimeDir}/httpd.pid";
-          Restart = "always";
-          RestartSec = "5s";
-          RuntimeDirectory = "httpd_${httpdName} httpd_${httpdName}/runtime";
-          RuntimeDirectoryMode = "0750";
-        };
-      };
-
-  };
-}