diff --git a/system/options.nix b/system/options.nix
index 7c452d02435b..3e802253d07d 100644
--- a/system/options.nix
+++ b/system/options.nix
@@ -1194,13 +1194,6 @@
";
};
- adminAddr = mkOption {
- example = "admin@example.org";
- description = "
- E-mail address of the server administrator.
- ";
- };
-
logDir = mkOption {
default = "/var/log/httpd";
description = "
@@ -1225,54 +1218,6 @@
";
};
- documentRoot = mkOption {
- default = null;
- example = "/data/webserver/docs";
- description = "
- The path of Apache's document root directory. If left undefined,
- an empty directory in the Nix store will be used as root.
- ";
- };
-
- servedDirs = mkOption {
- default = [];
- example = [
- { urlPath = "/nix";
- dir = "/home/eelco/Dev/nix-homepage";
- }
- ];
- description = "
- This option provides a simple way to serve static directories.
- ";
- };
-
- servedFiles = mkOption {
- default = [];
- example = [
- { urlPath = "/foo/bar.png";
- dir = "/home/eelco/some-file.png";
- }
- ];
- description = "
- This option provides a simple way to serve individual, static files.
- ";
- };
-
- # !!! this is a mis-nomer, should be "extraConfig" or something.
- extraDirectories = mkOption {
- default = "";
- example = "
-
- Options FollowSymlinks
- AllowOverride All
-
- ";
- description = "
- These lines go to httpd.conf verbatim. They will go after
- directories and directory aliases defined by default.
- ";
- };
-
mod_php = mkOption {
default = false;
description = "Whether to enable the PHP module.";
@@ -1367,14 +1312,11 @@
};
- extraSubservices = mkOption {
- default = [];
- description = "
- Extra subservices to enable in the webserver.
- ";
- };
-
- };
+ } // # Include the options shared between the main server and virtual hosts.
+ (import ../upstart-jobs/apache-httpd/per-server-options.nix {
+ inherit mkOption;
+ forMainServer = true;
+ });
vsftpd = {
enable = mkOption {
diff --git a/upstart-jobs/apache-httpd/default.nix b/upstart-jobs/apache-httpd/default.nix
index 69d50757bf14..aff915e4a2b0 100644
--- a/upstart-jobs/apache-httpd/default.nix
+++ b/upstart-jobs/apache-httpd/default.nix
@@ -9,23 +9,25 @@ let
httpd = pkgs.apacheHttpd;
- serverInfo = {
+ makeServerInfo = cfg: {
# Canonical name must not include a trailing slash.
canonicalName =
- "http://" +
- cfg.hostName +
+ "http://${cfg.hostName}" +
(if cfg.httpPort != 80 then ":${toString cfg.httpPort}" else "");
serverConfig = cfg;
fullConfig = config; # machine config
};
- subservices =
+ callSubservices = serverInfo: defs:
let f = svc:
let config = pkgs.lib.addDefaultOptionValues res.options svc.config;
res = svc.function {inherit config pkgs serverInfo;};
in res;
- in map f cfg.extraSubservices;
+ in map f defs;
+
+
+ allSubservices = callSubservices (makeServerInfo cfg) cfg.extraSubservices;
# !!! should be in lib
@@ -33,10 +35,6 @@ let
pkgs.runCommand name {inherit text;} "ensureDir $out; echo -n \"$text\" > $out/$name";
- documentRoot = if cfg.documentRoot != null then cfg.documentRoot else
- pkgs.runCommand "empty" {} "ensureDir $out";
-
-
# Names of modules from ${httpd}/modules that we want to load.
apacheModules =
[ # HTTP authentication mechanisms: basic and digest.
@@ -84,6 +82,7 @@ let
'';
+ # !!! integrate with virtual hosting below
sslConf = ''
Listen ${toString cfg.httpsPort}
@@ -128,24 +127,65 @@ let
'';
- documentRootConf = ''
- DocumentRoot "${documentRoot}"
+ perServerConf = isMainServer: cfg: let
-
- Options Indexes FollowSymLinks
- AllowOverride None
- Order allow,deny
- Allow from all
-
- '';
+ serverInfo = makeServerInfo cfg;
+ subservices = callSubservices serverInfo cfg.extraSubservices;
- robotsTxt = pkgs.writeText "robots.txt" ''
- ${pkgs.lib.concatStrings (map (svc: svc.robotsEntries) subservices)}
- '';
-
- robotsConf = ''
- Alias /robots.txt ${robotsTxt}
+ documentRoot = if cfg.documentRoot != null then cfg.documentRoot else
+ pkgs.runCommand "empty" {} "ensureDir $out";
+
+ documentRootConf = ''
+ DocumentRoot "${documentRoot}"
+
+
+ Options Indexes FollowSymLinks
+ AllowOverride None
+ Order allow,deny
+ Allow from all
+
+ '';
+
+ robotsTxt = pkgs.writeText "robots.txt" ''
+ ${concatMapStrings (svc: svc.robotsEntries) subservices}
+ '';
+
+ robotsConf = ''
+ Alias /robots.txt ${robotsTxt}
+ '';
+
+ in ''
+ ServerName ${serverInfo.canonicalName}
+
+ ${if isMainServer || cfg.adminAddr != "" then ''
+ ServerAdmin ${cfg.adminAddr}
+ '' else ""}
+
+ ${robotsConf}
+
+ ${if isMainServer || cfg.documentRoot != null then documentRootConf else ""}
+
+ ${
+ let makeDirConf = elem: ''
+ Alias ${elem.urlPath} ${elem.dir}/
+
+ Order allow,deny
+ Allow from all
+ AllowOverride None
+
+ '';
+ in concatMapStrings makeDirConf cfg.servedDirs
+ }
+
+ ${
+ let makeFileConf = elem: ''
+ Alias ${elem.urlPath} ${elem.file}
+ '';
+ in concatMapStrings makeFileConf cfg.servedFiles
+ }
+
+ ${concatMapStrings (svc: svc.extraConfig) subservices}
'';
@@ -153,10 +193,6 @@ let
ServerRoot ${httpd}
- ServerAdmin ${cfg.adminAddr}
-
- ServerName ${serverInfo.canonicalName}
-
PidFile ${cfg.stateDir}/httpd.pid
@@ -172,10 +208,10 @@ let
${let
load = {name, path}: "LoadModule ${name}_module ${path}\n";
allModules =
- pkgs.lib.concatMap (svc: svc.extraModulesPre) subservices ++
+ pkgs.lib.concatMap (svc: svc.extraModulesPre) allSubservices ++
map (name: {inherit name; path = "${httpd}/modules/mod_${name}.so";}) apacheModules ++
- pkgs.lib.concatMap (svc: svc.extraModules) subservices;
- in pkgs.lib.concatStrings (map load allModules)
+ pkgs.lib.concatMap (svc: svc.extraModules) allSubservices;
+ in concatMapStrings load allModules
}
${if cfg.enableUserDir then ''
@@ -232,30 +268,32 @@ let
Allow from all
- ${robotsConf}
+ # Generate directives for the main server.
+ ${perServerConf true cfg}
- ${documentRootConf}
+ # Always enable virtual hosts; it doesn't seem to hurt.
+ NameVirtualHost *:*
- ${
- let makeDirConf = elem: ''
- Alias ${elem.urlPath} ${elem.dir}/
-
- Order allow,deny
- Allow from all
- AllowOverride None
-
+ # Catch-all: since this is the first virtual host, any
+ # non-matching requests will use the main server configuration.
+
+
+
+ ${let
+ perServerOptions = import ./per-server-options.nix {
+ inherit (pkgs.lib) mkOption;
+ forMainServer = false;
+ };
+ makeVirtualHost = vhostIn:
+ let
+ # Fill in defaults for missing options.
+ vhost = pkgs.lib.addDefaultOptionValues perServerOptions vhostIn;
+ in ''
+
+ ${perServerConf false vhost}
+
'';
- in pkgs.lib.concatStrings (map makeDirConf cfg.servedDirs)
- }
-
- ${
- let makeFileConf = elem: ''
- Alias ${elem.urlPath} ${elem.file}
- '';
- in pkgs.lib.concatStrings (map makeFileConf cfg.servedFiles)
- }
-
- ${pkgs.lib.concatStrings (map (svc: svc.extraConfig) subservices)}
+ in concatMapStrings makeVirtualHost cfg.virtualHosts}
'';
@@ -276,7 +314,7 @@ in
}
];
- extraPath = [httpd] ++ pkgs.lib.concatMap (svc: svc.extraPath) subservices;
+ extraPath = [httpd] ++ pkgs.lib.concatMap (svc: svc.extraPath) allSubservices;
# Statically verify the syntactic correctness of the generated
# httpd.conf.
@@ -306,10 +344,10 @@ in
${
let f = {name, value}: "env ${name}=${value}\n";
- in pkgs.lib.concatStrings (map f (pkgs.lib.concatMap (svc: svc.globalEnvVars) subservices))
+ in pkgs.lib.concatStrings (map f (pkgs.lib.concatMap (svc: svc.globalEnvVars) allSubservices))
}
- env PATH=${pkgs.coreutils}/bin:${pkgs.gnugrep}/bin:${pkgs.lib.concatStringsSep ":" (pkgs.lib.concatMap (svc: svc.extraServerPath) subservices)}
+ env PATH=${pkgs.coreutils}/bin:${pkgs.gnugrep}/bin:${pkgs.lib.concatStringsSep ":" (pkgs.lib.concatMap (svc: svc.extraServerPath) allSubservices)}
${pkgs.diffutils}/bin:${pkgs.gnused}/bin
diff --git a/upstart-jobs/apache-httpd/per-server-options.nix b/upstart-jobs/apache-httpd/per-server-options.nix
new file mode 100644
index 000000000000..08f60b2cc6d1
--- /dev/null
+++ b/upstart-jobs/apache-httpd/per-server-options.nix
@@ -0,0 +1,86 @@
+# This file defines the options that can be used both for the Apache
+# main server configuration, and for the virtual hosts. (The latter
+# has additional options that affect the web server as a whole, like
+# the user/group to run under.)
+
+{forMainServer, mkOption}:
+
+{
+
+ hostName = mkOption {
+ default = "localhost";
+ description = "
+ Canonical hostname for the server.
+ ";
+ };
+
+ httpPort = mkOption {
+ default = 80;
+ description = "
+ Port for unencrypted HTTP requests.
+ ";
+ };
+
+ adminAddr = mkOption ({
+ example = "admin@example.org";
+ description = "
+ E-mail address of the server administrator.
+ ";
+ } // (if forMainServer then {} else {default = "";}));
+
+ documentRoot = mkOption {
+ default = null;
+ example = "/data/webserver/docs";
+ description = "
+ The path of Apache's document root directory. If left undefined,
+ an empty directory in the Nix store will be used as root.
+ ";
+ };
+
+ servedDirs = mkOption {
+ default = [];
+ example = [
+ { urlPath = "/nix";
+ dir = "/home/eelco/Dev/nix-homepage";
+ }
+ ];
+ description = "
+ This option provides a simple way to serve static directories.
+ ";
+ };
+
+ servedFiles = mkOption {
+ default = [];
+ example = [
+ { urlPath = "/foo/bar.png";
+ dir = "/home/eelco/some-file.png";
+ }
+ ];
+ description = "
+ This option provides a simple way to serve individual, static files.
+ ";
+ };
+
+ # !!! this is a mis-nomer, should be "extraConfig" or something.
+ extraDirectories = mkOption {
+ default = "";
+ example = "
+
+ Options FollowSymlinks
+ AllowOverride All
+
+ ";
+ description = "
+ These lines go to httpd.conf verbatim. They will go after
+ directories and directory aliases defined by default.
+ ";
+ };
+
+ extraSubservices = mkOption {
+ default = [];
+ description = "
+ Extra subservices to enable in the webserver.
+ ";
+ };
+
+}
diff --git a/upstart-jobs/apache-httpd/subversion.nix b/upstart-jobs/apache-httpd/subversion.nix
index ae78f90e22c5..60c3d71c62dd 100644
--- a/upstart-jobs/apache-httpd/subversion.nix
+++ b/upstart-jobs/apache-httpd/subversion.nix
@@ -404,6 +404,6 @@ in {
};
- };
+ };
}