diff --git a/machines/terra/modules.nix b/machines/terra/modules.nix index 52cae86..5746d0b 100644 --- a/machines/terra/modules.nix +++ b/machines/terra/modules.nix @@ -8,6 +8,11 @@ users.default.enable = true; + containers = { + nginx.enable = true; + forgejo.enable = true; + }; + base = { nix.enable = true; locale.enable = true; diff --git a/modules/containers/default.nix b/modules/containers/default.nix new file mode 100644 index 0000000..9e61d5b --- /dev/null +++ b/modules/containers/default.nix @@ -0,0 +1,17 @@ +{...}: { + imports = [ + ./nginx.nix + ./forgejo.nix + ]; + + config = { + networking.nat = { + enable = true; + # Use "ve-*" when using nftables instead of iptables + internalInterfaces = ["ve-+"]; + externalInterface = "eno1"; + # Lazy IPv6 connectivity for the container + enableIPv6 = true; + }; + }; +} diff --git a/modules/containers/forgejo.nix b/modules/containers/forgejo.nix new file mode 100644 index 0000000..a54522f --- /dev/null +++ b/modules/containers/forgejo.nix @@ -0,0 +1,153 @@ +{ + inputs, + outputs, + lib, + config, + pkgs, + ... +}: let + inherit (lib) mkEnableOption mkIf; + cfg = config.horseman.containers.forgejo; + username = config.horseman.username; + + HTTP_PORT = 3000; + SSH_PORT = 34916; + INSTANCE_URL = "http://local.git.server:3000"; + SECRET = "7c31591e8b67225a116d4a4519ea8e507e08f71f"; # TODO REMOVE + DATA_DIR = "/home/${username}/backups/volumes/forgejo"; + BACKUP_FILE = "/home/${username}/backups/forgejo.tar"; + +in { + options = { + horseman.containers.forgejo = { + enable = mkEnableOption "forgejo containers"; + }; + }; + + config = mkIf cfg.enable { + networking.extraHosts = "192.168.100.3 local.git.server"; + + + systemd.timers."backup-forgejo" = { + wantedBy = ["timers.target"]; + timerConfig = { + OnCalendar = "daily"; + Persistent = true; + }; + }; + + environment.systemPackages = [ pkgs.gnutar ]; + systemd.services."backup-forgejo" = { + script = '' + ${pkgs.gnutar} -cf ${BACKUP_FILE} ${DATA_DIR} + ''; + serviceConfig = { + User = "root"; + }; + }; + + containers.forgejoRunner = { + autoStart = true; + privateNetwork = true; + hostAddress = "172.16.0.2"; + localAddress = "192.168.100.2"; + + config = { + config, + pkgs, + ... + }: let + configFile = pkgs.writeText "runner.yml" '' + runner: + labels: + - "self-hosted:host" + ''; + in { + environment.systemPackages = with pkgs; [ + forgejo-runner + ]; + + users.groups.runner = {}; + users.users.runner = { + isNormalUser = true; + group = "runner"; + }; + + systemd.services.startup = { + script = '' + cd ${config.users.users.runner.home} + ${pkgs.forgejo-runner}/bin/forgejo-runner create-runner-file --instance http://192.168.100.3:3000 --secret ${SECRET} --name runner + sleep 10 + ${pkgs.forgejo-runner}/bin/forgejo-runner daemon --config ${configFile} + ''; + serviceConfig.User = "runner"; + wantedBy = ["multi-user.target"]; + }; + + system.stateVersion = "23.11"; + }; + }; + + containers.forgejo = { + autoStart = true; + privateNetwork = true; + hostAddress = "172.16.0.3"; + localAddress = "192.168.100.3"; + + bindMounts = { + "/var/lib/forgejo" = { + hostPath = DATA_DIR; + isReadOnly = false; + }; + }; + + config = { + config, + pkgs, + ... + }: { + environment.systemPackages = [pkgs.forgejo]; + services.forgejo = { + enable = true; + + stateDir = "/var/lib/forgejo"; + + settings = { + server = { + HTTP_PORT = HTTP_PORT; + SSH_PORT = SSH_PORT; + ROOT_URL = INSTANCE_URL; + }; + session = { + COOKIE_SECURE = false; # TODO Set to true + }; + service = { + DISABLE_REGISTRATION = true; + }; + }; + }; + + systemd.services.startup = { + script = '' + cd ${config.users.users.forgejo.home} + ${pkgs.forgejo}/bin/forgejo forgejo-cli actions register --name runner --secret ${SECRET} --config ${config.services.forgejo.stateDir}/custom/conf/app.ini + ''; + serviceConfig.User = "forgejo"; + wantedBy = ["multi-user.target"]; + }; + + networking = { + firewall = { + enable = true; + allowedTCPPorts = [HTTP_PORT SSH_PORT]; + }; + # Use systemd-resolved inside the container + # Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686 + useHostResolvConf = lib.mkForce false; + }; + + system.stateVersion = "23.11"; + }; + }; + }; +} diff --git a/modules/containers/nginx.nix b/modules/containers/nginx.nix new file mode 100644 index 0000000..87be28c --- /dev/null +++ b/modules/containers/nginx.nix @@ -0,0 +1,70 @@ +{ + inputs, + outputs, + lib, + config, + pkgs, + ... +}: let + inherit (lib) mkEnableOption mkIf mkOption types; + cfg = config.horseman.containers.nginx; +in { + options = { + horseman.containers.nginx = { + enable = mkEnableOption "nginx container"; + }; + }; + + config = mkIf cfg.enable { + networking.extraHosts = "192.168.100.1 koendev.nl *.koendev.nl"; + + containers.nginx = { + autoStart = true; + privateNetwork = true; + hostAddress = "172.16.0.1"; + localAddress = "192.168.100.1"; + + bindMounts = { + "/var/www/portfolio" = { + hostPath = "/home/horseman/Programming/portfolio/_site"; + isReadOnly = true; + }; + }; + + config = { + config, + pkgs, + lib, + ... + }: { + services.nginx = { + enable = true; + + virtualHosts = { + "koendev.nl" = { + # addSSL = false; + # enableACME = false; + root = "/var/www/portfolio"; + }; + + "vault.koendev.nl" = { + locations."/" = { + proxyPass = "http://172.16.0.2"; + }; + }; + }; + }; + + networking = { + firewall = { + enable = true; + allowedTCPPorts = [80]; + }; + useHostResolvConf = lib.mkForce false; + }; + services.resolved.enable = true; + system.stateVersion = "23.11"; + }; + }; + }; +} diff --git a/modules/default.nix b/modules/default.nix index 7b85bd5..2c57013 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -12,6 +12,7 @@ in { ./base ./boot ./catppuccin + ./containers ./hardware ./network ./timers