{ specialArgs, hostAddress, localAddress, httpPort ? 80, httpsPort ? 443, autoStart ? false, }: let domain = "www.stefanjunker.de"; in { inherit specialArgs; config = { config, pkgs, lib, repoFlake, ... }: { system.stateVersion = "22.05"; # Did you read the comment? disabledModules = [ "services/misc/forgejo.nix" ]; imports = [ "${repoFlake.inputs.nixpkgs_forgejo}/nixos/modules/services/misc/forgejo.nix" ../profiles/containers/configuration.nix repoFlake.inputs.sops-nix.nixosModules.sops ]; sops.defaultSopsFile = ./webserver_secrets.yaml; networking.firewall.enable = true; networking.firewall.allowedTCPPorts = [ httpPort httpsPort ]; sops.age.sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"]; sops.secrets.hedgedoc_environment_file = { sopsFile = ./webserver_secrets.yaml; owner = config.users.users.hedgedoc.name; }; services.caddy = { enable = true; virtualHosts."${domain}" = { extraConfig = let port = "${builtins.toString config.services.authelia.instances.default.settings.server.port}"; path = "${config.services.authelia.instances.default.settings.server.path}"; in '' redir /hedgedoc* https://hedgedoc.${domain} file_server /*/* { browse root /var/www/stefanjunker.de/htdocs/caddy pass_thru } # respond "Hi" # respond (not /*/*) "Hi" ''; }; virtualHosts."hedgedoc.${domain}" = { extraConfig = '' reverse_proxy http://[::1]:3000 ''; }; virtualHosts."authelia.${domain}" = { extraConfig = '' reverse_proxy http://127.0.0.1:${builtins.toString config.services.authelia.instances.default.settings.server.port} ''; }; virtualHosts."lldap.${domain}" = { extraConfig = '' reverse_proxy http://127.0.0.1:${builtins.toString config.services.lldap.settings.http_port} ''; }; virtualHosts."forgejo.${domain}" = { extraConfig = '' reverse_proxy http://127.0.0.1:${builtins.toString config.services.forgejo.settings.server.HTTP_PORT} ''; }; }; services.hedgedoc = { enable = true; settings = { domain = "hedgedoc.${domain}"; urlPath = ""; protocolUseSSL = true; db = { dialect = "sqlite"; storage = "/var/lib/hedgedoc/db.hedgedoc.sqlite"; }; allowAnonymous = false; allowAnonymousEdits = false; allowGravatar = false; allowFreeURL = false; defaultPermission = "private"; allowEmailRegister = false; email = false; ldap = { url = "ldap://127.0.0.1:${builtins.toString config.services.lldap.settings.ldap_port}"; bindDn = "uid=admin,ou=people,dc=stefanjunker,dc=de"; # these are set via the `environmentFile` bindCredentials = "$LDAP_ADMIN_PASSWORD"; searchBase = "ou=people,dc=stefanjunker,dc=de"; searchFilter = "(&(memberOf=cn=hedgedoc,ou=groups,dc=stefanjunker,dc=de)(uid={{username}}))"; useridField = "uid"; }; uploadsPath = "/var/lib/hedgedoc/uploads"; }; environmentFile = config.sops.secrets.hedgedoc_environment_file.path; }; services.jitsi-meet = { enable = false; hostName = "meet.${domain}"; config = { prejoinPageEnabled = true; }; caddy.enable = true; nginx.enable = false; }; sops.secrets.authelia_storageEncryptionKey = { sopsFile = ./webserver_secrets.yaml; owner = config.users.users.authelia-default.name; }; sops.secrets.authelia_jwtSecret = { sopsFile = ./webserver_secrets.yaml; owner = config.users.users.authelia-default.name; }; services.authelia.instances.default = let baseDir = "/var/lib/authelia-default"; in { enable = true; secrets.storageEncryptionKeyFile = config.sops.secrets.authelia_storageEncryptionKey.path; secrets.jwtSecretFile = config.sops.secrets.authelia_jwtSecret.path; settings = { theme = "auto"; default_2fa_method = "totp"; log.level = "debug"; server = { disable_healthcheck = true; host = "127.0.0.1"; port = 9091; # path = "authelia"; }; storage = { local.path = "${baseDir}/authelia.sqlite"; }; authentication_backend = { file.path = "${baseDir}/first_factor.yaml"; file.search.email = true; file.search.case_insensitive = false; }; access_control = { default_policy = "one_factor"; }; session.domain = "stefanjunker.de"; notifier = { disable_startup_check = true; filesystem.filename = "${baseDir}/notification.txt"; }; }; }; users.groups.lldap = {}; users.users.lldap = { isSystemUser = true; group = "lldap"; }; sops.secrets.lldap_jwtSecret = { sopsFile = ./webserver_secrets.yaml; owner = config.users.users.lldap.name; }; sops.secrets.lldap_adminPassword = { sopsFile = ./webserver_secrets.yaml; owner = config.users.users.lldap.name; }; sops.secrets.lldap_environmentFile = { sopsFile = ./webserver_secrets.yaml; owner = config.users.users.lldap.name; }; services.lldap = { enable = true; environment = { LLDAP_JWT_SECRET_FILE = config.sops.secrets.lldap_jwtSecret.path; LLDAP_LDAP_USER_PASS_FILE = config.sops.secrets.lldap_adminPassword.path; }; environmentFile = config.sops.secrets.lldap_environmentFile.path; settings = { verbose = true; ldap_base_dn = "dc=stefanjunker,dc=de"; http_url = "https://lldap.${domain}"; ## Options to configure SMTP parameters, to send password reset emails. ## To set these options from environment variables, use the following format ## (example with "password"): LLDAP_SMTP_OPTIONS__PASSWORD smtp_options = { ## Whether to enabled password reset via email, from LLDAP. enable_password_reset = true; # port = 465; ## How the connection is encrypted, either "NONE" (no encryption), "TLS" or "STARTTLS". # smtp_encryption = "TLS"; }; # database_url = "sqlite:///var/lib/lldap/users.db?mode=rwc"; }; }; sops.secrets.FORGEJO_JWT_SECRET = {}; sops.secrets.FORGEJO_INTERNAL_TOKEN = {}; sops.secrets.FORGEJO_SECRET_KEY = {}; services.forgejo = { enable = true; package = repoFlake.inputs.nixpkgs_forgejo.legacyPackages.${pkgs.system}.forgejo; settings = { service.DISABLE_REGISTRATION = true; server.HTTP_ADDR = "127.0.0.1"; server.DISABLE_SSH = true; server.ROOT_URL = "https://forgejo.${domain}"; server.HTTP_PORT = 3001; }; secrets = { oauth2.JWT_SECRET = lib.mkForce config.sops.secrets.FORGEJO_JWT_SECRET.path; security.INTERNAL_TOKEN = lib.mkForce config.sops.secrets.FORGEJO_INTERNAL_TOKEN.path; security.SECRET_KEY = lib.mkForce config.sops.secrets.FORGEJO_SECRET_KEY.path; }; }; systemd.services.lldap.serviceConfig.User = config.users.users.lldap.name; systemd.services.lldap.serviceConfig.Group = config.users.groups.lldap.name; systemd.services.lldap.serviceConfig.DynamicUser = lib.mkForce false; }; inherit autoStart; bindMounts = { # FIXME/REMINDER: this is used so that the container can decrypt the secrets that are deployed to the host "/etc/ssh/ssh_host_ed25519_key".isReadOnly = true; "/etc/ssh/ssh_host_ed25519_key.pub".isReadOnly = true; "/var/www" = { hostPath = "/var/lib/container-volumes/webserver/var-www"; isReadOnly = false; }; "/var/lib/mysql" = { hostPath = "/var/lib/container-volumes/webserver/var-lib-mysql"; isReadOnly = false; }; "/var/lib/hedgedoc" = { hostPath = "/var/lib/container-volumes/webserver/var-lib-hedgedoc"; isReadOnly = false; }; "/var/lib/authelia-default" = { hostPath = "/var/lib/container-volumes/webserver/var-lib-authelia-default"; isReadOnly = false; }; "/var/lib/lldap" = { hostPath = "/var/lib/container-volumes/webserver/var-lib-lldap"; isReadOnly = false; }; "/var/lib/forgejo" = { hostPath = "/var/lib/container-volumes/webserver/var-lib-forgejo"; isReadOnly = false; }; }; # extraFlags = ["--resolv-conf=bind-host"]; # networking.useHostResolvConf = true; privateNetwork = true; forwardPorts = [ { # http containerPort = 80; hostPort = httpPort; protocol = "tcp"; } { # https containerPort = 443; hostPort = httpsPort; protocol = "tcp"; } ]; inherit hostAddress localAddress; }