Files
k8scd/nix-infra-machine/app_modules/nginx/default.nix
T
2026-03-15 18:31:53 +01:00

187 lines
5.5 KiB
Nix

{ config, pkgs, lib, ... }:
let
appName = "nginx";
cfg = config.infrastructure.${appName};
in
{
options.infrastructure.${appName} = {
enable = lib.mkEnableOption "infrastructure.nginx";
package = lib.mkOption {
type = lib.types.package;
description = "Nginx package to use.";
default = pkgs.nginx;
example = "pkgs.nginxMainline";
};
openFirewall = lib.mkOption {
type = lib.types.bool;
description = "Whether to open firewall ports for HTTP (80) and HTTPS (443).";
default = true;
};
recommendedSettings = lib.mkOption {
type = lib.types.bool;
description = ''
Enable recommended nginx settings for optimization and security.
This enables recommendedGzipSettings, recommendedOptimisation,
recommendedProxySettings, and recommendedTlsSettings.
'';
default = true;
};
# ==========================================================================
# Let's Encrypt / ACME Configuration
# ==========================================================================
acme = {
enable = lib.mkOption {
type = lib.types.bool;
description = "Enable ACME (Let's Encrypt) certificate management.";
default = false;
};
acceptTerms = lib.mkOption {
type = lib.types.bool;
description = ''
Accept the ACME provider's terms of service.
For Let's Encrypt: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
'';
default = false;
};
email = lib.mkOption {
type = lib.types.nullOr lib.types.str;
description = "Default email address for ACME certificate registration and renewal notifications.";
default = null;
example = "admin@example.com";
};
staging = lib.mkOption {
type = lib.types.bool;
description = ''
Use Let's Encrypt staging server for testing.
Certificates won't be trusted but you won't hit rate limits.
'';
default = false;
};
extraConfig = lib.mkOption {
type = lib.types.attrsOf lib.types.anything;
description = ''
Extra configuration options passed to security.acme.defaults.
See https://nixos.org/manual/nixos/stable/#module-security-acme for options.
'';
default = {};
example = {
webroot = "/var/lib/acme/acme-challenge";
renewInterval = "daily";
};
};
};
# ==========================================================================
# Pass-through Configuration
# ==========================================================================
virtualHosts = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule {
# Use freeformType to allow any nginx virtualHost options
freeformType = lib.types.attrsOf lib.types.anything;
});
description = ''
Virtual host configurations passed directly to services.nginx.virtualHosts.
See https://nixos.org/manual/nixos/stable/options.html#opt-services.nginx.virtualHosts
Example with Let's Encrypt:
{
"example.com" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:8080";
};
};
}
'';
default = {};
example = lib.literalExpression ''
{
"example.com" = {
enableACME = true;
forceSSL = true;
root = "/var/www/example.com";
};
"api.example.com" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:3000";
proxyWebsockets = true;
};
};
}
'';
};
appendHttpConfig = lib.mkOption {
type = lib.types.lines;
description = "Additional nginx http block configuration.";
default = "";
example = ''
proxy_buffer_size 128k;
proxy_buffers 4 256k;
'';
};
extraConfig = lib.mkOption {
type = lib.types.attrsOf lib.types.anything;
description = ''
Extra configuration options passed directly to services.nginx.
Use this for any nginx options not explicitly exposed by this module.
'';
default = {};
example = {
clientMaxBodySize = "100m";
resolver = { addresses = [ "1.1.1.1" ]; };
};
};
};
config = lib.mkIf cfg.enable {
# ACME configuration
security.acme = lib.mkIf cfg.acme.enable {
acceptTerms = cfg.acme.acceptTerms;
defaults = {
email = cfg.acme.email;
server = lib.mkIf cfg.acme.staging "https://acme-staging-v02.api.letsencrypt.org/directory";
} // cfg.acme.extraConfig;
};
# Nginx configuration
services.nginx = {
enable = true;
package = cfg.package;
# Recommended settings
recommendedGzipSettings = cfg.recommendedSettings;
recommendedOptimisation = cfg.recommendedSettings;
recommendedProxySettings = cfg.recommendedSettings;
recommendedTlsSettings = cfg.recommendedSettings;
# Virtual hosts (pass-through)
virtualHosts = cfg.virtualHosts;
# Additional http config
appendHttpConfig = cfg.appendHttpConfig;
} // cfg.extraConfig;
# Open firewall for HTTP/HTTPS
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ 80 443 ];
# Install useful utilities
environment.systemPackages = [ pkgs.curl pkgs.openssl ];
};
}