nginx: added serverName option for virtualHosts

This allows overriding the `server_name` attribute of virtual
hosts. By doing so it is possible to have multiple virtualHost
definitions that share the same `server_name`. This is useful in
particular when you need a HTTP as well as a HTTPS virtualhost: same
server_name, different port.
This commit is contained in:
Bob van der Linden 2017-01-16 16:46:43 +01:00 committed by Robin Gloster
parent b9b95aa4d4
commit d9987f360a
2 changed files with 33 additions and 16 deletions

View file

@ -5,7 +5,11 @@ with lib;
let let
cfg = config.services.nginx; cfg = config.services.nginx;
virtualHosts = mapAttrs (vhostName: vhostConfig: virtualHosts = mapAttrs (vhostName: vhostConfig:
vhostConfig // (optionalAttrs vhostConfig.enableACME { vhostConfig // {
serverName = if vhostConfig.serverName != null
then vhostConfig.serverName
else vhostName;
} // (optionalAttrs vhostConfig.enableACME {
sslCertificate = "/var/lib/acme/${vhostName}/fullchain.pem"; sslCertificate = "/var/lib/acme/${vhostName}/fullchain.pem";
sslCertificateKey = "/var/lib/acme/${vhostName}/key.pem"; sslCertificateKey = "/var/lib/acme/${vhostName}/key.pem";
}) })
@ -112,8 +116,9 @@ let
${cfg.appendConfig} ${cfg.appendConfig}
''; '';
vhosts = concatStringsSep "\n" (mapAttrsToList (serverName: vhost: vhosts = concatStringsSep "\n" (mapAttrsToList (vhostName: vhost:
let let
serverName = vhost.serverName;
ssl = vhost.enableSSL || vhost.forceSSL; ssl = vhost.enableSSL || vhost.forceSSL;
port = if vhost.port != null then vhost.port else (if ssl then 443 else 80); port = if vhost.port != null then vhost.port else (if ssl then 443 else 80);
listenString = toString port + optionalString ssl " ssl http2" listenString = toString port + optionalString ssl " ssl http2"
@ -161,7 +166,7 @@ let
ssl_certificate_key ${vhost.sslCertificateKey}; ssl_certificate_key ${vhost.sslCertificateKey};
''} ''}
${optionalString (vhost.basicAuth != {}) (mkBasicAuth serverName vhost.basicAuth)} ${optionalString (vhost.basicAuth != {}) (mkBasicAuth vhostName vhost.basicAuth)}
${mkLocations vhost.locations} ${mkLocations vhost.locations}
@ -178,8 +183,8 @@ let
${config.extraConfig} ${config.extraConfig}
} }
'') locations); '') locations);
mkBasicAuth = serverName: authDef: let mkBasicAuth = vhostName: authDef: let
htpasswdFile = pkgs.writeText "${serverName}.htpasswd" ( htpasswdFile = pkgs.writeText "${vhostName}.htpasswd" (
concatStringsSep "\n" (mapAttrsToList (user: password: '' concatStringsSep "\n" (mapAttrsToList (user: password: ''
${user}:{PLAIN}${password} ${user}:{PLAIN}${password}
'') authDef) '') authDef)
@ -393,8 +398,10 @@ in
}; };
security.acme.certs = filterAttrs (n: v: v != {}) ( security.acme.certs = filterAttrs (n: v: v != {}) (
mapAttrs (vhostName: vhostConfig: let
optionalAttrs vhostConfig.enableACME { vhostsConfigs = mapAttrsToList (vhostName: vhostConfig: vhostConfig) virtualHosts;
acmeEnabledVhosts = filter (vhostConfig: vhostConfig.enableACME) vhostsConfigs;
acmePairs = map (vhostConfig: { name = vhostConfig.serverName; value = {
user = cfg.user; user = cfg.user;
group = cfg.group; group = cfg.group;
webroot = vhostConfig.acmeRoot; webroot = vhostConfig.acmeRoot;
@ -402,8 +409,9 @@ in
postRun = '' postRun = ''
systemctl reload nginx systemctl reload nginx
''; '';
} }; }) acmeEnabledVhosts;
) virtualHosts in
listToAttrs acmePairs
); );
users.extraUsers = optionalAttrs (cfg.user == "nginx") (singleton users.extraUsers = optionalAttrs (cfg.user == "nginx") (singleton

View file

@ -8,6 +8,15 @@
with lib; with lib;
{ {
options = { options = {
serverName = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Name of this virtual host. Defaults to attribute name in virtualHosts.
'';
example = "example.org";
};
serverAliases = mkOption { serverAliases = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [];