summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/darwin/default.nix4
-rw-r--r--modules/darwin/still-awake/default.nix50
-rw-r--r--modules/default.nix11
-rw-r--r--modules/graphics/default.nix36
-rw-r--r--modules/linus.onl/default.nix98
-rw-r--r--modules/nixos/cloudflare-proxy/default.nix (renamed from modules/cloudflare-proxy/default.nix)0
-rw-r--r--modules/nixos/default.nix10
-rw-r--r--modules/nixos/duksebot/default.nix71
-rw-r--r--modules/nixos/on-demand-minecraft/default.nix359
-rw-r--r--modules/notifications.linus.onl/default.nix42
10 files changed, 494 insertions, 187 deletions
diff --git a/modules/darwin/default.nix b/modules/darwin/default.nix
new file mode 100644
index 0000000..2419e48
--- /dev/null
+++ b/modules/darwin/default.nix
@@ -0,0 +1,4 @@
+
+{
+ still-awake = import ./still-awake;
+}
diff --git a/modules/darwin/still-awake/default.nix b/modules/darwin/still-awake/default.nix
new file mode 100644
index 0000000..9221359
--- /dev/null
+++ b/modules/darwin/still-awake/default.nix
@@ -0,0 +1,50 @@
+{ pkgs, lib, config, ... }:
+
+let
+ inherit (lib) mkIf mkEnableOption;
+
+ cfg = config.my.services.still-awake;
+in
+{
+ options.my.services.still-awake.enable = mkEnableOption "still-awake launchd job";
+
+ config = mkIf cfg.enable {
+ launchd.agents."still-awake" =
+ let
+ # https://macperformanceguide.com/blog/2022/20221125_2044-launch_daemon-launchctl-posix-spawn-permission-denied.html
+ log-file = "/tmp/still-awake.log";
+ in
+ {
+ enable = true;
+ config = {
+ ProgramArguments = [ "${pkgs.still-awake}/bin/still-awake" ];
+ ProcessType = "Interactive";
+
+ # WARNING: These times must match the ones specified in ${source}!
+ StartCalendarInterval = [
+ { Hour = 21; Minute = 30; }
+ { Hour = 22; }
+ { Hour = 22; Minute = 30; }
+ { Hour = 23; }
+ { Hour = 23; Minute = 30; }
+ { Hour = 23; }
+ { Hour = 23; Minute = 30; }
+ { Hour = 00; }
+ { Hour = 00; Minute = 30; }
+ { Hour = 01; }
+ { Hour = 01; Minute = 30; }
+ { Hour = 02; }
+ { Hour = 02; Minute = 30; }
+ { Hour = 03; }
+ { Hour = 03; Minute = 30; }
+ { Hour = 04; }
+ { Hour = 04; Minute = 30; }
+ { Hour = 05; }
+ ];
+
+ StandardOutPath = log-file;
+ StandardErrorPath = log-file;
+ };
+ };
+ };
+}
diff --git a/modules/default.nix b/modules/default.nix
deleted file mode 100644
index 3015d59..0000000
--- a/modules/default.nix
+++ /dev/null
@@ -1,11 +0,0 @@
-{ ... }:
-
-{
- imports =
- [
- ./linus.onl
- ./notifications.linus.onl
- ./cloudflare-proxy
- ./graphics
- ];
-}
diff --git a/modules/graphics/default.nix b/modules/graphics/default.nix
deleted file mode 100644
index e2b7a86..0000000
--- a/modules/graphics/default.nix
+++ /dev/null
@@ -1,36 +0,0 @@
-# This module configures a basic graphical environment. I use this sometimes for
-# ahmed when muhammed is being repaired.
-
-{ config, lib, pkgs, ... }:
-
-let
- inherit (lib) mkEnableOption mkIf;
-
- cfg = config.my.modules.graphics;
-in
-{
- options.my.modules.graphics.enable = mkEnableOption "basic graphical environment";
-
- config = mkIf cfg.enable {
- services.xserver.enable = true;
-
- # Match console keyboard layout but swap capslock and escape.
- # TODO: Create a custom keymap with esc/capslock swap so console can use it.
- services.xserver.layout = config.console.keyMap;
- services.xserver.xkbOptions = "caps:swapescape";
-
- # Enable touchpad support.
- services.xserver.libinput.enable = true;
-
- services.xserver.windowManager.dwm.enable = true;
-
- # Enable sound.
- sound.enable = true;
- hardware.pulseaudio.enable = true;
-
- environment.systemPackages = with pkgs; [
- st # suckless terminal - dwm is pretty sucky without this
- dmenu # application launcher
- ];
- };
-}
diff --git a/modules/linus.onl/default.nix b/modules/linus.onl/default.nix
deleted file mode 100644
index 617865c..0000000
--- a/modules/linus.onl/default.nix
+++ /dev/null
@@ -1,98 +0,0 @@
-{ pkgs, lib, config, ... }:
-
-let
- inherit (lib) mkEnableOption mkOption types mkIf optional;
-
- domain = "linus.onl";
-
- cfg = config.my.modules."${domain}";
-in
-{
- options.my.modules."${domain}" = {
- enable = mkEnableOption "${domain} static site";
-
- useACME = mkEnableOption "built-in HTTPS stuff";
- };
-
- config = mkIf cfg.enable {
- # Create a user to run the build script under.
- users.users."${domain}-builder" = {
- description = "builds ${domain}";
- group = "${domain}-builder";
- isSystemUser = true;
- };
- users.groups."${domain}-builder" = { };
-
- # Create the output directory.
- system.activationScripts."${domain}-create-www" = lib.stringAfter [ "var" ] ''
- mkdir -p /var/www/${domain}
- chown ${domain}-builder /var/www/${domain}
- chgrp ${domain}-builder /var/www/${domain}
- chmod 0755 /var/www/${domain}
- '';
-
- # Create a systemd service which rebuild the site regularly.
- #
- # This can't be done using Nix because the site relies on the git build and
- # there are some inherent difficulties with including .git/ in the
- # inputSource for derivations.
- #
- # See: https://github.com/NixOS/nix/issues/6900
- # See: https://github.com/NixOS/nixpkgs/issues/8567
- #
- # TODO: Integrate rebuilding with GitHub webhooks to rebuild on push.
- systemd.services."${domain}-source" = {
- description = "generate https://${domain} source";
-
- serviceConfig = {
- Type = "oneshot";
- User = "${domain}-builder";
- Group = "${domain}-builder";
- };
- startAt = "*-*-* *:00/5:00";
-
- path = with pkgs; [
- git
- rsync
- coreutils-full
- tcl-8_5
- gnumake
- ];
- environment.TCLLIBPATH = "$TCLLIBPATH ${pkgs.tcl-cmark}/lib/tclcmark1.0";
- script = ''
- set -ex
- tmpdir="$(mktemp -d -t linus.onl-source.XXXXXXXXXXXX)"
- cd "$tmpdir"
- trap 'rm -rf $tmpdir' EXIT
- # TODO: Only do minimal possible cloning
- git clone https://github.com/linnnus/${domain} .
- make _build
- rsync --archive --delete _build/ /var/www/${domain}
- '';
-
- # TODO: Harden service
-
- # Network must be online for us to check.
- after = [ "network-online.target" ];
- requires = [ "network-online.target" ];
-
- # We must generate some files for NGINX to serve, so this should be run
- # before NGINX.
- before = [ "nginx.service" ];
- wantedBy = [ "nginx.service" ];
- };
-
- # Register domain name with ddns.
- services.cloudflare-dyndns.domains = [ domain ];
-
- # Register virtual host.
- services.nginx = {
- virtualHosts."${domain}" = {
- # NOTE: 'forceSSL' will cause an infite loop, if the cloudflare proxy does NOT connect over HTTPS.
- enableACME = cfg.useACME;
- forceSSL = cfg.useACME;
- root = "/var/www/${domain}";
- };
- };
- };
-}
diff --git a/modules/cloudflare-proxy/default.nix b/modules/nixos/cloudflare-proxy/default.nix
index 73d8893..73d8893 100644
--- a/modules/cloudflare-proxy/default.nix
+++ b/modules/nixos/cloudflare-proxy/default.nix
diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix
new file mode 100644
index 0000000..9ad08e5
--- /dev/null
+++ b/modules/nixos/default.nix
@@ -0,0 +1,10 @@
+{
+ ## Reusable services.
+
+ on-demand-minecraft = import ./on-demand-minecraft;
+ duksebot = import ./duksebot;
+
+ ## Other miscellaneous configuration bits. These may be useful to other you.
+
+ cloudflare-proxy = import ./cloudflare-proxy;
+}
diff --git a/modules/nixos/duksebot/default.nix b/modules/nixos/duksebot/default.nix
new file mode 100644
index 0000000..c1dc5cf
--- /dev/null
+++ b/modules/nixos/duksebot/default.nix
@@ -0,0 +1,71 @@
+# This module defines an on-demand minecraft server service which turns off the
+# server when it's not being used.
+
+{ config, lib, pkgs, modulesPath, ... }:
+
+let
+ inherit (lib) mkIf mkOption mkEnableOption types;
+
+ cfg = config.my.services.duksebot;
+in
+{
+ options.my.services.duksebot = {
+ enable = mkEnableOption "duksebot daily reminder";
+
+ package = mkOption {
+ description = "What package to use";
+ default = pkgs.duksebot;
+ type = types.package;
+ };
+ };
+
+ config = mkIf cfg.enable {
+ # Create a user to run the server under.
+ users.users.duksebot = {
+ description = "Runs daily dukse reminder";
+ group = "duksebot";
+ isSystemUser = true;
+ home = "/srv/duksebot";
+ createHome = true;
+ };
+ users.groups.duksebot = { };
+
+ age.secrets.duksebot-env = {
+ file = ../../../secrets/duksebot.env.age;
+ owner = config.users.users.duksebot.name;
+ group = config.users.users.duksebot.group;
+ mode = "0440";
+ };
+
+ # Create a service which simply runs script. This will be invoked by our timer.
+ systemd.services.duksebot = {
+ serviceConfig = {
+ # We only want to run this once every time the timer triggers it.
+ Type = "oneshot";
+ # Run as the user we created above.
+ User = "duksebot";
+ Group = "duksebot";
+ WorkingDirectory = config.users.users.duksebot.home;
+ };
+ script = ''
+ # Load the secret environment variables.
+ export $(grep -v '^#' ${config.age.secrets.duksebot-env.path} | xargs)
+ # Kick off.
+ exec "${cfg.package}"/bin/duksebot
+ '';
+ };
+
+ # Create a timer to activate our oneshot service.
+ systemd.timers.duksebot = {
+ wantedBy = [ "timers.target" ];
+ partOf = [ "duksebot.service" ];
+ after = [ "network-online.target" ];
+ wants = [ "network-online.target" ]; # FIXME: redundant?
+ timerConfig = {
+ # OnCalendar = "*-*-* 7:00:00";
+ OnCalendar = "*:0/1";
+ Unit = "duksebot.service";
+ };
+ };
+ };
+}
diff --git a/modules/nixos/on-demand-minecraft/default.nix b/modules/nixos/on-demand-minecraft/default.nix
new file mode 100644
index 0000000..541a624
--- /dev/null
+++ b/modules/nixos/on-demand-minecraft/default.nix
@@ -0,0 +1,359 @@
+# This module defines an on-demand minecraft server service which turns off the
+# server when it's not being used.
+
+{ config, lib, pkgs, modulesPath, ... }:
+
+let
+ inherit (lib) mkIf mkOption mkEnableOption types;
+
+ cfg = config.my.services.on-demand-minecraft;
+in
+{
+ options.my.services.on-demand-minecraft = {
+ enable = mkEnableOption "local minecraft server";
+
+ eula = mkOption {
+ description = ''
+ Whether you agree to [Mojangs EULA](https://account.mojang.com/documents/minecraft_eula).
+ This option must be set to `true` to run a Minecraft™️ server (??).
+ '';
+ type = types.bool;
+ default = false;
+ };
+
+ frequency-check-players = mkOption {
+ description = ''
+ How often to check the number of players using the server. If
+ no players are using the server, it is shut down.
+
+ This should be a valid value for systemd's `onCalendar`
+ property.
+ '';
+ type = types.nonEmptyStr;
+ default = "*-*-* *:*:0/20";
+ };
+
+ minimum-server-lifetime = mkOption {
+ description = ''
+ Minimum required time to pass from the server is started
+ before it is allowed to be killed. This should ensure the
+ server has time to start up before it is killed.
+
+ The option is specified as a number of seconds.
+ '';
+ type = types.ints.positive;
+ default = 300;
+ };
+
+ internal-port = mkOption {
+ description = ''
+ The internal port which the minecraft server will listen to.
+ This port does not need to be exposed to the network.
+ '';
+ type = types.port;
+ default = cfg.external-port + 1;
+ };
+
+ external-port = mkOption {
+ description = ''
+ The external port of the socket which is forwarded to the
+ Minecraft server. This is the one users will connect to. You
+ will need to add it to `networking.firewall.allowedTCPPorts`
+ to open it in the firewall.
+
+ You may also have to set up port forwarding if you want to
+ play with friends who are not on the same LAN.
+ '';
+ type = types.port;
+ default = 25565;
+ };
+
+ rcon-password = mkOption {
+ description = ''
+ The RCON password used for remote control.
+
+ Local systemd units use this password to execute commands
+ that fetch the current number of players. This number is used
+ to shut down the server, when there are no active players.
+ '';
+ type = types.nonEmptyStr;
+ default = "260a368f55f4fb4fa"; # XXX: Is this a bad idea?
+ };
+
+ openFirewall = mkOption {
+ description = ''
+ Open holes in the firewall so clients on LAN can connect. You must
+ set up port forwarding if you want to play over WAN.
+ '';
+ type = types.bool;
+ default = true;
+ };
+
+ package = mkOption {
+ description = "What Minecraft server to run.";
+ default = pkgs.minecraft-server;
+ type = types.package;
+ };
+
+ server-properties = mkOption {
+ description = ''
+ Minecraft server properties for the server.properties file. See
+ <https://minecraft.gamepedia.com/Server.properties#Java_Edition_3>
+ for documentation on these values. Note that some options like
+ `enable-rcon` will be forced on because the're required for the
+ server to work.
+ '';
+ type = with types; attrsOf (oneOf [ bool int str ]);
+ default = { };
+ example = lib.literalExpression ''
+ {
+ difficulty = 3;
+ gamemode = 1;
+ motd = "My NixOS server!";
+ }
+ '';
+ };
+
+ jvm-options = mkOption {
+ description = "JVM options for the Minecraft server. List of command line arguments.";
+ type = types.listOf lib.types.str;
+ default = [ "-Xmx2048M" "-Xms2048M" ];
+ };
+ };
+
+ config = mkIf cfg.enable {
+ # Create a user to run the server under.
+ users.users.minecrafter = {
+ description = "On-demand minecraft server service user";
+ home = "/srv/minecrafter";
+ createHome = true;
+ group = "minecrafter";
+ isSystemUser = true;
+ };
+ users.groups.minecrafter = { };
+
+ # Create an internal socket and hook it up to minecraft-server process as
+ # stdin. That way we can send commands to it.
+ systemd.sockets.minecraft-server = {
+ bindsTo = [ "minecraft-server.service" ];
+ socketConfig = {
+ ListenFIFO = "/run/minecraft-server.stdin";
+ SocketMode = "0660";
+ SocketUser = "minecrafter";
+ SocketGroup = "minecrafter";
+ RemoveOnStop = true;
+ FlushPending = true;
+ };
+ };
+
+ # Create a service which runs the server.
+ systemd.services.minecraft-server =
+ let
+ server-properties = cfg.server-properties // {
+ server-port = cfg.internal-port;
+ enable-rcon = true;
+ "rcon.password" = cfg.rcon-password;
+ };
+ cfg-to-str = v:
+ if builtins.isBool v
+ then (if v then "true" else "false")
+ else toString v;
+ server-properties-file = pkgs.writeText "server.properties" (''
+ # server.properties managed by NixOS configuration.
+ '' + lib.concatStringsSep "\n" (lib.mapAttrsToList
+ (n: v: "${n}=${cfg-to-str v}")
+ server-properties));
+
+ # We don't allow eula=false anyways
+ eula-file = builtins.toFile "eula.txt" ''
+ # eula.txt managed by NixOS Configuration
+ eula=true
+ '';
+
+ # HACK: Each server is given its own subdirectory so
+ # incompatabilities between servers don't cause complaints.
+ start-server = pkgs.writeShellScript "minecraft-server-start" ''
+ # Switch to runtime directory.
+ export RUNTIME_DIR="${config.users.users.minecrafter.home}/${cfg.package.name}/"
+ ${pkgs.busybox}/bin/mkdir -p "$RUNTIME_DIR"
+ ${pkgs.busybox}/bin/chown minecrafter:minecrafter "$RUNTIME_DIR"
+ cd "$RUNTIME_DIR"
+
+ # Set up/update environment for server
+ ln -sf ${eula-file} eula.txt
+ cp -f ${server-properties-file} server.properties
+ chmod u+w server.properties # Must be writable because server regenerates it.
+
+ exec ${cfg.package}/bin/minecraft-server "$@"
+ '';
+
+ stop-server = pkgs.writeShellScript "minecraft-server-stop" ''
+ # Send the 'stop' command to the server. It listens for commands on stdin.
+ echo stop > ${config.systemd.sockets.minecraft-server.socketConfig.ListenFIFO}
+ # Wait for the PID of the minecraft server to disappear before
+ # returning, so systemd doesn't attempt to SIGKILL it.
+ while kill -0 "$1" 2> /dev/null; do
+ sleep 1s
+ done
+ '';
+ in
+ {
+ description = "Actually runs the Minecraft server";
+ requires = [ "minecraft-server.socket" ];
+ after = [ "networking.target" "minecraft-server.socket" ];
+ wantedBy = [ ]; # TEMP: Does this do anything?
+
+ serviceConfig = {
+ ExecStart = "${start-server} ${lib.escapeShellArgs cfg.jvm-options}";
+ ExecStop = "${stop-server} $MAINPID";
+ Restart = "always";
+
+ User = "minecrafter";
+ Group = "minecrafter";
+
+ StandardInput = "socket";
+ StandardOutput = "journal";
+ StandardError = "journal";
+
+ # Hardening
+ CapabilityBoundingSet = [ "" ];
+ DeviceAllow = [ "" ];
+ LockPersonality = true;
+ PrivateDevices = true;
+ PrivateTmp = true;
+ PrivateUsers = true;
+ ProtectClock = true;
+ ProtectControlGroups = true;
+ ProtectHome = true;
+ ProtectHostname = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ ProtectProc = "invisible";
+ RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ RestrictSUIDSGID = true;
+ SystemCallArchitectures = "native";
+ UMask = "0077";
+ };
+ };
+
+ # This socket listens for connections on the public port and
+ # triggers `listen-minecraft.service` when a connection is made.
+ systemd.sockets.listen-minecraft = {
+ enable = true;
+ wantedBy = [ "sockets.target" ];
+ requires = [ "network.target" ];
+ listenStreams = [ (toString cfg.external-port) ];
+ };
+
+ # This service is triggerd by a TCP connection on the public
+ # port. It starts hook-minecraft.service if it is not running
+ # already and waits for it to return (using `after`). Then it proxifies the TCP
+ # connection to the real (local) Minecraft port.
+ systemd.services.listen-minecraft = {
+ enable = true;
+ path = with pkgs; [ systemd ];
+ requires = [ "hook-minecraft.service" "listen-minecraft.socket" ];
+ after = [ "hook-minecraft.service" "listen-minecraft.socket" ];
+ serviceConfig.ExecStart = ''
+ ${pkgs.systemd.out}/lib/systemd/systemd-socket-proxyd 127.0.0.1:${toString cfg.internal-port}
+ '';
+ };
+
+ # This starts Minecraft if required and waits for it to be
+ # available over TCP to unlock the `listen-minecraft.service`
+ # proxy.
+ systemd.services.hook-minecraft = {
+ enable = true;
+ # Add tools used by scripts to path.
+ path = with pkgs; [ systemd libressl busybox ];
+ serviceConfig =
+ let
+ # Start the Minecraft server and the timer regularly
+ # checking whether it should stop.
+ start-mc = pkgs.writeShellScriptBin "start-mc" ''
+ echo "Starting server and stop-timer..."
+ systemctl start minecraft-server.service
+ systemctl start stop-minecraft.timer
+ '';
+ # Wait for the internal port to be accessible for max.
+ # 60 seconds before complaining.
+ wait-tcp = pkgs.writeShellScriptBin "wait-tcp" ''
+ echo "Waiting for server to start listening on port ${toString cfg.internal-port}..."
+ for i in `seq 60`; do
+ if nc -z 127.0.0.1 ${toString cfg.internal-port} >/dev/null; then
+ echo "Yay! ${toString cfg.internal-port} is not available. hook-minecraft is finished."
+ exit 0
+ fi
+ sleep 1
+ done
+ echo "${toString cfg.internal-port} did not become available in time."
+ exit 1
+ '';
+ in
+ {
+ # First we start the server, then we wait for it to become available.
+ ExecStart = "${start-mc}/bin/start-mc";
+ ExecStartPost = "${wait-tcp}/bin/wait-tcp";
+ };
+ };
+
+ # This timer runs the service of the same name, that checks if
+ # the server needs to be stopped.
+ systemd.timers.stop-minecraft = {
+ enable = true;
+ timerConfig = {
+ OnCalendar = cfg.frequency-check-players;
+ #Unit = "stop-minecraft.service";
+ };
+ };
+
+ systemd.services.stop-minecraft =
+ let
+ # Script that returns true (exit code 1) if the server can be shut
+ # down. It uses RCON to get the player list. It does not continue if
+ # the server was started less than `minimum-server-lifetime` seconds
+ # ago.
+ no-player-connected = pkgs.writeShellScriptBin "no-player-connected" ''
+ servicestartsec="$(date -d "$(systemctl show --property=ActiveEnterTimestamp minecraft-server.service | cut -d= -f2)" +%s)"
+ serviceelapsedsec="$(( $(date +%s) - servicestartsec))"
+
+ if [ $serviceelapsedsec -lt ${toString cfg.minimum-server-lifetime} ]; then
+ echo "Server is too young to be stopped (minimum lifetime is ${toString cfg.minimum-server-lifetime}s)"
+ exit 1
+ fi
+
+ PLAYERS="$(printf "list\n" | ${pkgs.rcon.out}/bin/rcon -m -H 127.0.0.1 -p 25575 -P ${cfg.rcon-password})"
+ if echo "$PLAYERS" | grep "are 0 of a"; then
+ exit 0
+ else
+ exit 1
+ fi
+ '';
+ in
+ {
+ enable = true;
+ serviceConfig.Type = "oneshot";
+ script = ''
+ if ${no-player-connected}/bin/no-player-connected; then
+ echo "Stopping minecraft server..."
+ systemctl stop minecraft-server.service
+ systemctl stop hook-minecraft.service
+ systemctl stop stop-minecraft.timer
+ fi
+ '';
+ };
+
+ networking.firewall = mkIf cfg.openFirewall {
+ allowedUDPPorts = [ cfg.external-port ];
+ allowedTCPPorts = [ cfg.external-port ];
+ };
+
+ assertions = [{
+ assertion = cfg.eula;
+ message = "You must agree to Mojangs EULA to run minecraft-server. Read https://account.mojang.com/documents/minecraft_eula and set `services.minecraft-server.eula` to `true` if you agree.";
+ }];
+ };
+}
diff --git a/modules/notifications.linus.onl/default.nix b/modules/notifications.linus.onl/default.nix
deleted file mode 100644
index 443853f..0000000
--- a/modules/notifications.linus.onl/default.nix
+++ /dev/null
@@ -1,42 +0,0 @@
-{ pkgs, lib, config, ... }:
-
-let
- inherit (lib) mkEnableOption mkOption types mkIf optional;
-
- domain = "notifications.linus.onl";
-
- # TODO: Make option internal-port.
- internal-port = 13082;
-
- cfg = config.my.modules."notifications.linus.onl";
-in
-{
- options.my.modules."notifications.linus.onl" = {
- enable = mkEnableOption "notifications.linus.onl static site";
-
- useACME = mkEnableOption "built-in HTTPS stuff";
- };
-
- config = mkIf cfg.enable {
- my.services.push-notification-api = {
- enable = true;
- # host = "notifications.linus.onl";
- host = "0.0.0.0";
- port = internal-port;
- openFirewall = false; # We're using NGINX reverse proxy.
- };
-
- # Register domain name.
- services.cloudflare-dyndns.domains = [ "notifications.linus.onl" ];
-
- # Serve the generated page using NGINX.
- services.nginx.virtualHosts."notifications.linus.onl" = {
- enableACME = cfg.useACME;
- forceSSL = cfg.useACME;
- locations."/" = {
- recommendedProxySettings = true;
- proxyPass = "http://127.0.0.1:${toString internal-port}";
- };
- };
- };
-}