{ config, lib, pkgs, self, ... }: let pubsolarDomain = import ./pubsolar-domain.nix; # Machine user for CI pipelines in { networking.firewall.allowedTCPPorts = [80 443]; networking.networkmanager.unmanaged = ["interface-name:ve-caddy"]; networking.nat = { enable = true; internalInterfaces = ["ve-caddy"]; externalInterface = "enp0s31f6"; # Lazy IPv6 connectivity for the container enableIPv6 = true; }; systemd.tmpfiles.rules = [ "d '/data/www' 0750 root www - -" "d '/data/caddy' 0750 root caddy - -" ]; users.groups.caddy = {}; users.groups.www = {}; users.users.hakkonaut.extraGroups = ["www"]; ids.uids.www = 996; ids.gids.www = 996; fileSystems."/var/lib/caddy" = { device = "/data/caddy"; options = ["bind"]; }; fileSystems."/srv/www" = { device = "/data/www"; options = ["bind"]; }; containers.caddy = { autoStart = true; privateNetwork = true; hostAddress = "192.168.101.0"; localAddress = "192.168.103.0"; hostAddress6 = "fc00::1"; localAddress6 = "fc00::3"; forwardPorts = [ { containerPort = 443; hostPort = 443; protocol = "tcp"; } { containerPort = 80; hostPort = 80; protocol = "tcp"; } ]; bindMounts = { "/srv/www/" = { hostPath = "/data/www"; isReadOnly = false; }; "/var/lib/caddy/" = { hostPath = "/data/caddy"; isReadOnly = false; }; "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory" = { hostPath = "/data/acme"; isReadOnly = false; }; }; config = { users.groups.caddy = {}; users.groups.www = {}; users.groups.acme = {}; users.users.caddy.extraGroups = ["www" "acme"]; networking.firewall.allowedTCPPorts = [80 443]; environment.etc."resolv.conf".text = "nameserver 1.1.1.0"; services.caddy = { enable = lib.mkForce true; email = "acme@benjaminbaedorf.eu"; globalConfig = lib.mkForce ""; virtualHosts = { "dashboard.nougat-2.b12f.io" = { extraConfig = '' reverse_proxy :2019 ''; }; "www.b12f.io" = { extraConfig = '' redir https://pub.solar{uri} ''; }; "mail.b12f.io" = { extraConfig = '' redir / /realms/pub.solar/account temporary reverse_proxy :8080 ''; }; "${pubsolarDomain}" = { logFormat = lib.mkForce '' output discard ''; extraConfig = '' # PubSolarOS images handle /os/download/* { root * /srv/www file_server /os/download/* browse } # serve base domain pub.solar for mastodon.pub.solar # https://masto.host/mastodon-usernames-different-from-the-domain-used-for-installation/ handle /.well-known/host-meta { redir https://mastodon.${pubsolarDomain}{uri} } # pub.solar website handle { root * /srv/www/pub.solar try_files {path}.html {path} file_server } # minimal error handling, respond with status code and text handle_errors { respond "{http.error.status_code} {http.error.status_text}" } ''; }; "www.${pubsolarDomain}" = { logFormat = lib.mkForce '' output discard ''; extraConfig = '' redir https://${pubsolarDomain}{uri} ''; }; "auth.${pubsolarDomain}" = { logFormat = lib.mkForce '' output discard ''; extraConfig = '' redir / /realms/${pubsolarDomain}/account temporary reverse_proxy 192.168.104.0:8080 ''; }; "git.${pubsolarDomain}" = { logFormat = lib.mkForce '' output discard ''; extraConfig = '' redir /user/login /user/oauth2/keycloak temporary reverse_proxy 192.168.105.0:3000 ''; }; "ci.${pubsolarDomain}" = { logFormat = lib.mkForce '' output discard ''; extraConfig = '' reverse_proxy 192.168.101.0:8080 ''; }; }; }; }; }; }