diff --git a/README.md b/README.md index aee8da9..e3c1b4a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,3 @@ nixos-rebuild switch --flake .#nixos \ --sudo --ask-sudo-password ``` -The main public services under `yisroelbaum.com` are provided by the -`yisroelbaum-web` flake input. Rabbi Gerzi is imported directly from its own -flake so its application module remains independently owned. This repository -owns the machine configuration and provisions runtime secrets for both. diff --git a/configuration.nix b/configuration.nix index 070cce9..29870b7 100644 --- a/configuration.nix +++ b/configuration.nix @@ -1,5 +1,8 @@ { + config, pkgs, + domainName, + resume, ... }: { @@ -7,6 +10,7 @@ [ # Include the results of the hardware scan. ./hardware-configuration.nix ./borgbackup.nix + ./forgejo.nix ./boot.nix ]; @@ -95,6 +99,46 @@ # Install firefox. programs.firefox.enable = true; + users.users.nginx.extraGroups = [ "acme" ]; + services.nginx = { + enable = true; + virtualHosts = { + "${domainName}" = { + forceSSL = true; + enableACME = true; + locations = { + "/" = { + root = "${resume.packages.x86_64-linux.default}"; + }; + }; + }; + "jellyfin.${domainName}" = { + forceSSL = true; + enableACME = true; + locations = { + "/" = { + proxyPass = "http://localhost:8096"; + }; + }; + }; + }; + }; + security.acme = { + defaults.webroot = "/var/lib/acme/acme-challenge/"; + acceptTerms = true; + defaults.email = "yisroel.d.baum@gmail.com"; + certs = { + "${domainName}" = { + domain = "*.${domainName}"; + webroot = "/var/lib/acme/acme-challenge/"; + group = config.services.nginx.group; + reloadServices = [ + "nginx" + ]; + }; + }; + }; + # Allow unfree packages nixpkgs.config.allowUnfree = true; @@ -115,6 +159,10 @@ # enableSSHSupport = true; # }; + services.jellyfin = { + enable = true; + }; + # List services that you want to enable: services.dnsmasq = { enable = true; diff --git a/flake.lock b/flake.lock index 2e9db57..bdd385d 100644 --- a/flake.lock +++ b/flake.lock @@ -44,11 +44,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1785613642, - "narHash": "sha256-WFG0BXn6XHhdf5O2EC0KOvCpzkknx5pPwTME1NNPLhw=", + "lastModified": 1783365146, + "narHash": "sha256-glQYGvVU2renata14CZqKmAINrbZqVud/BBqimr4QHM=", "ref": "refs/heads/master", - "rev": "1cf3de423a932da611c715df7a6196d969b25e80", - "revCount": 388, + "rev": "04aad89124c4d4c6347fd741f76ca163941292b9", + "revCount": 375, "type": "git", "url": "https://git.yisroelbaum.com/yisroelbaum/Rabbi_Gerzi" }, @@ -60,7 +60,6 @@ "resume": { "inputs": { "nixpkgs": [ - "yisroelbaum-web", "nixpkgs" ] }, @@ -83,9 +82,9 @@ "home-manager": "home-manager", "nixpkgs": "nixpkgs", "rabbi-gerzi": "rabbi-gerzi", + "resume": "resume", "sops-nix": "sops-nix", - "tide": "tide", - "yisroelbaum-web": "yisroelbaum-web" + "tide": "tide" } }, "sops-nix": { @@ -160,27 +159,6 @@ "repo": "flake-utils", "type": "github" } - }, - "yisroelbaum-web": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ], - "resume": "resume" - }, - "locked": { - "lastModified": 1785611752, - "narHash": "sha256-AC7EilGHueXmYK9gu+/EOw8wfL+Hv0bbjgKuBMvbPvA=", - "ref": "refs/heads/master", - "rev": "4a489e90f3af8d6eeb0ab0658c6e932253eaedc3", - "revCount": 3, - "type": "git", - "url": "https://git.yisroelbaum.com/yisroelbaum/yisroelbaum-web" - }, - "original": { - "type": "git", - "url": "https://git.yisroelbaum.com/yisroelbaum/yisroelbaum-web" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 1c9a84d..08739f7 100644 --- a/flake.nix +++ b/flake.nix @@ -16,8 +16,8 @@ url = "git+https://git.yisroelbaum.com/yisroelbaum/TIDE"; inputs.nixpkgs.follows = "nixpkgs"; }; - yisroelbaum-web = { - url = "git+https://git.yisroelbaum.com/yisroelbaum/yisroelbaum-web"; + resume = { + url = "git+https://git.yisroelbaum.com/yisroelbaum/MyResume"; inputs.nixpkgs.follows = "nixpkgs"; }; rabbi-gerzi = { @@ -33,24 +33,23 @@ home-manager, sops-nix, tide, - yisroelbaum-web, + resume, rabbi-gerzi, ... }: let system = "x86_64-linux"; + domainName = "yisroelbaum.com"; in { nixosConfigurations.nixos = nixpkgs.lib.nixosSystem { modules = [ ./configuration.nix ./tide.nix - ./yisroelbaum-web.nix ./rabbi-gerzi.nix home-manager.nixosModules.home-manager sops-nix.nixosModules.sops tide.nixosModules.tide - yisroelbaum-web.nixosModules.default rabbi-gerzi.nixosModules.default { home-manager.useGlobalPkgs = true; @@ -58,6 +57,7 @@ home-manager.users.yisroel = ./home-manager/home.nix; } ]; + specialArgs = { inherit domainName resume; }; }; devShells."${system}".default = let diff --git a/forgejo.nix b/forgejo.nix new file mode 100644 index 0000000..942bb83 --- /dev/null +++ b/forgejo.nix @@ -0,0 +1,107 @@ +{ + domainName, + config, + pkgs, + ... +}: +{ + services = { + forgejo = { + enable = true; + settings = { + server = { + ROOT_URL = "https://git.${domainName}/"; + PROTOCOL = "http"; + HTTP_ADDR = "127.0.0.1"; + HTTP_PORT = 3000; + DOMAIN = "git.${domainName}"; + SSH_PORT = 2222; + START_SSH_SERVER = true; + }; + session.COOKIE_SECURE = true; + service.DISABLE_REGISTRATION = true; + mailer = { + ENABLED = true; + SMTP_ADDR = "in-v3.mailjet.com"; + SMTP_PORT = 587; + FROM = "me@${domainName}"; + # USER and PASSWD come from secrets below + }; + }; + secrets.mailer.USER = config.sops.secrets."forgejo-mailer-user".path; + secrets.mailer.PASSWD = config.sops.secrets."forgejo-mailer-passwd".path; + }; + nginx.virtualHosts."git.${domainName}" = { + forceSSL = true; + enableACME = true; + extraConfig = '' + client_max_body_size 512M; + ''; + locations = { + "/" = { + proxyPass = "http://127.0.0.1:3000"; + recommendedProxySettings = false; + extraConfig = '' + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + ''; + }; + }; + }; + borgbackup.jobs.forgejo = { + paths = [ config.services.forgejo.stateDir ]; + repo = "ssh://n5lniyfd@n5lniyfd.repo.borgbase.com/./repo"; + user = "root"; + group = "root"; + encryption = { + mode = "repokey-blake2"; + passCommand = "${pkgs.coreutils}/bin/cat ${config.sops.secrets."borg-passphrase".path}"; + }; + doInit = true; + compression = "auto,zstd"; + startAt = "*-*-* 03:15:00"; + persistentTimer = true; + prune.keep = { + daily = 7; + weekly = 4; + monthly = 6; + }; + environment.BORG_RSH = "ssh -i ${config.sops.secrets."borg-private-key".path} -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/root/.config/borg/known_hosts"; + preHook = '' + forgejoWasActive=/root/.cache/borg/forgejo-was-active + if ${pkgs.systemd}/bin/systemctl is-active --quiet forgejo.service; then + touch "$forgejoWasActive" + ${pkgs.systemd}/bin/systemctl stop forgejo.service + else + rm -f "$forgejoWasActive" + fi + ''; + postHook = '' + forgejoWasActive=/root/.cache/borg/forgejo-was-active + if [ -e "$forgejoWasActive" ]; then + ${pkgs.systemd}/bin/systemctl start forgejo.service + rm -f "$forgejoWasActive" + fi + ''; + }; + }; + + systemd.services.borgbackup-job-forgejo = { + after = [ + "sops-install-secrets.service" + "network-online.target" + ]; + wants = [ "network-online.target" ]; + }; + + sops.secrets."forgejo-mailer-user" = { + sopsFile = ./secrets/forgejo.yaml; + mode = "0400"; + }; + sops.secrets."forgejo-mailer-passwd" = { + sopsFile = ./secrets/forgejo.yaml; + mode = "0400"; + }; +} diff --git a/rabbi-gerzi.nix b/rabbi-gerzi.nix index 36905fb..ad5f676 100644 --- a/rabbi-gerzi.nix +++ b/rabbi-gerzi.nix @@ -1,19 +1,20 @@ { config, + domainName, ... }: { services.rabbi-gerzi = { enable = true; frontend = { - hostName = "rabbigerzi.yisroelbaum.com"; + hostName = "rabbigerzi.${domainName}"; nginx = { forceSSL = true; enableACME = true; }; }; backend = { - hostName = "rabbigerziapi.yisroelbaum.com"; + hostName = "rabbigerziapi.${domainName}"; environmentFile = config.sops.secrets."rabbi-gerzi-env".path; nginx = { forceSSL = true; diff --git a/secrets/README.md b/secrets/README.md index 705acc7..b4eb134 100644 --- a/secrets/README.md +++ b/secrets/README.md @@ -18,17 +18,6 @@ host's age key. 3. On a workstation, put that public key into `.sops.yaml` at the repository root and encrypt the required secret files. -## Shared Borg backup credentials - -`borgbackup.yaml` contains `private-key` and `passphrase`. The resulting -secrets are shared by the TIDE and yisroelbaum.com backup jobs. - -## Forgejo - -`forgejo.yaml` contains `forgejo-mailer-user` and -`forgejo-mailer-passwd`. The host passes these secret paths to the -`yisroelbaum-web` module. - ## TIDE Create `tide.yaml` from `tide.yaml.example` and encrypt it with sops. It must @@ -44,5 +33,3 @@ APP_KEY=base64:... RABBI_GERZI_INITIAL_ADMIN_EMAIL=... RABBI_GERZI_INITIAL_ADMIN_PASSWORD=... ``` - -The host passes this environment file directly to the Rabbi Gerzi module. diff --git a/yisroelbaum-web.nix b/yisroelbaum-web.nix deleted file mode 100644 index 741cc60..0000000 --- a/yisroelbaum-web.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ config, ... }: -{ - services.yisroelbaum-web = { - enable = true; - secretFiles = { - borgPassphrase = config.sops.secrets."borg-passphrase".path; - borgPrivateKey = config.sops.secrets."borg-private-key".path; - forgejoMailerUser = config.sops.secrets."forgejo-mailer-user".path; - forgejoMailerPassword = config.sops.secrets."forgejo-mailer-passwd".path; - }; - }; - - sops.secrets = { - "forgejo-mailer-user" = { - sopsFile = ./secrets/forgejo.yaml; - mode = "0400"; - }; - "forgejo-mailer-passwd" = { - sopsFile = ./secrets/forgejo.yaml; - mode = "0400"; - }; - }; -}