Skip to content

Instantly share code, notes, and snippets.

@3noch
Created October 7, 2017 18:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 3noch/6120e99c2bfb6849eb615f3d9471f9c2 to your computer and use it in GitHub Desktop.
Save 3noch/6120e99c2bfb6849eb615f3d9471f9c2 to your computer and use it in GitHub Desktop.
{ config
, pkgs
, lib
, ...
}:
let
cfg = config.simpleWebServer;
in with lib; {
options.simpleWebServer = {
enable = mkOption {
type = types.bool;
default = false;
#example = literalExample true;
description = ''
When enabled, provides a simple interface for a fully functioning web server.
'';
};
domain = mkOption {
type = types.string;
default = "domain.com";
#example = literalExample "my.site.com";
description = ''Primary domain of the web server (usually without any subdomains)'';
};
host = mkOption {
type = types.string;
default = cfg.domain;
#example = literalExample "www.\${config.simpleWebServer.domain}";
description = ''
Primary host where the server (this may be the same as the domain, or it may include a subdomain).
'';
};
hostRedirects = mkOption {
type = types.listOf types.string;
default = [];
#example = literalExample [ "www.mysite.com" "oldhost.com" ];
description = ''
Hosts that should redirect to the primary host. Note that if HTTPS is enabled,
TLS certificates will be obtained for all hosts in this list.
'';
};
adminEmail = mkOption {
type = types.string;
default = "admin@${cfg.domain}";
#example = literalExample "admin@mysite.com";
description = ''Email address of web server administrator (used for HTTPS certificates).'';
};
enableHttps = mkOption {
type = types.bool;
default = true;
#example = literalExample false;
description = ''
If enabled, the server will obtain TLS certificates and redirect all traffic to HTTPS.
'';
};
localAppUrl = mkOption {
type = types.string;
#example = literalExample "127.0.0.1:8000";
description = ''
URL to a [locally hosted] web server that will handle the traffic.
'';
};
maxUploadMb = mkOption {
type = types.int;
default = 50;
#example = literalExample 100;
description = ''Maximum size up uploaded files in MB.'';
};
siteUrl = mkOption {
type = types.string;
default = "${if cfg.enableHttps then "https" else "http"}://${cfg.host}";
description = ''
Fully qualified URL of the web server. NOTE: You probably don't want to set this directly.
'';
};
hostName = mkOption {
type = types.string;
default = cfg.host;
#example = literalExample "myserver";
description = ''
Host name for the network.
'';
};
};
config = mkIf cfg.enable (
let
acmeChallengesDir = "/var/www/challenges";
nginxConfig = import ./nginx-config.nix {
inherit config pkgs acmeChallengesDir;
inherit (cfg) enableHttps host hostRedirects maxUploadMb;
dhParams =
if appConfig.enableHttps
then "${config.security.dhparams.path}/nginx.pem"
else null;
upstream = cfg.localAppUrl;
};
httpsModule = {
security.acme.certs.${cfg.host} = {
webroot = acmeChallengesDir;
email = cfg.adminEmail;
extraDomains = pkgs.lib.genAttrs cfg.hostRedirects (x: null);
postRun = "systemctl reload nginx.service";
};
# Depending on hardware, first-time deploy could take a good 5-15 minutes for this to generate.
security.dhparams.params = { nginx = 3072; };
};
in {
imports = [ (if cfg.enableHttps then httpsModule else {}) ];
networking.hostName = cfg.hostName;
networking.firewall.allowedTCPPorts = [80] ++ lib.optional cfg.enableHttps 443;
environment.systemPackages = with pkgs; [
gzip htop unzip nix-repl vim zip
];
time.timeZone = "UTC";
services.nginx.enable = true;
services.nginx.httpConfig = nginxConfig;
services.postfix.enable = true;
}
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment