infrastructure/modules/nixos/dgn-web.nix
Tom Hubrecht 88d9b8c3e3
chore: Add license and copyright information
Signed-off-by: Tom Hubrecht <tom.hubrecht@dgnum.eu>
Acked-by: Ryan Lahfa <ryan.lahfa@dgnum.eu>
Acked-by: Maurice Debray <maurice.debray@dgnum.eu>
Acked-by: Lubin Bailly <lubin.bailly@dgnum.eu>
Acked-by: Jean-Marc Gailis <jean-marc.gailis@dgnum.eu> as the legal authority, at the time of writing, in DGNum.
Acked-by: Elias Coppens <elias.coppens@dgnum.eu> as a member, at the time of writing, of the DGNum executive counsel.
2024-12-13 12:41:38 +01:00

157 lines
3.5 KiB
Nix

# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
#
# SPDX-License-Identifier: EUPL-1.2
{ config, lib, ... }:
let
inherit (lib)
attrsToList
concatStringsSep
filterAttrs
getAttr
mapAttrs
mapAttrs'
mkEnableOption
mkIf
mkOption
nameValuePair
recursiveUpdate
;
inherit (lib.types)
attrs
attrsOf
bool
port
str
submodule
;
cfg = config.dgn-web;
in
{
options.dgn-web = {
enable = mkEnableOption "sane defaults for web services.";
internalPorts = mkOption {
type = attrsOf port;
default = { };
description = ''
Map from the web services to their internal ports, it should avoid port clashes.
'';
};
simpleProxies = mkOption {
type = attrsOf (submodule {
options = {
port = mkOption {
type = port;
description = ''
Port where the service will listen.
'';
};
host = mkOption {
type = str;
description = ''
Hostname of the service.
'';
};
proxyWebsockets = mkOption {
type = bool;
default = false;
description = ''
Whether to support proxying websocket connections with HTTP/1.1.
'';
};
vhostConfig = mkOption {
type = attrs;
default = { };
description = ''
Additional virtualHost settings.
'';
};
};
});
default = { };
description = ''
A set of simple localhost redirections.
'';
};
};
config = mkIf cfg.enable {
assertions = [
(
let
duplicates = builtins.attrValues (
builtins.mapAttrs (p: serv: "${p}: ${concatStringsSep ", " serv}") (
filterAttrs (_: ls: builtins.length ls != 1) (
builtins.foldl' (
rev:
{ name, value }:
let
str = builtins.toString value;
in
rev // { ${str} = (rev.${str} or [ ]) ++ [ name ]; }
) { } (attrsToList cfg.internalPorts)
)
)
);
in
{
assertion = duplicates == [ ];
message = ''
Internal ports cannot be used for multiple services, the clashes are:
${concatStringsSep "\n " duplicates}
'';
}
)
];
dgn-web.internalPorts = mapAttrs (_: getAttr "port") cfg.simpleProxies;
# Keep logs during 1 year (53 weeks)
services.logrotate.settings.nginx.rotate = 53;
services.nginx = {
enable = true;
virtualHosts = mapAttrs' (
_:
{
host,
port,
proxyWebsockets,
vhostConfig,
}:
nameValuePair host (
recursiveUpdate {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
inherit proxyWebsockets;
};
} vhostConfig
)
) cfg.simpleProxies;
recommendedBrotliSettings = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
recommendedZstdSettings = true;
};
networking.firewall.allowedTCPPorts = [
80
443
];
};
}