add yisroelbaum web stack module
This commit is contained in:
commit
4a4de4eb0a
6 changed files with 456 additions and 0 deletions
173
nix/module.nix
Normal file
173
nix/module.nix
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
{ resume }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.yisroelbaum-web;
|
||||
domainName = "yisroelbaum.com";
|
||||
resumePackage = resume.packages.${pkgs.stdenv.hostPlatform.system}.default;
|
||||
secretFileOption =
|
||||
description:
|
||||
lib.mkOption {
|
||||
type = lib.types.path;
|
||||
inherit description;
|
||||
};
|
||||
in
|
||||
{
|
||||
options.services.yisroelbaum-web = {
|
||||
enable = lib.mkEnableOption "the yisroelbaum.com web stack";
|
||||
|
||||
secretFiles = {
|
||||
borgPassphrase = secretFileOption "Borg repository passphrase file.";
|
||||
borgPrivateKey = secretFileOption "Borg repository SSH private key file.";
|
||||
forgejoMailerUser = secretFileOption "Forgejo SMTP username file.";
|
||||
forgejoMailerPassword = secretFileOption "Forgejo SMTP password file.";
|
||||
rabbiGerziEnvironment = secretFileOption "Rabbi Gerzi runtime dotenv file.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
users.users.${config.services.nginx.user}.extraGroups = [ "acme" ];
|
||||
|
||||
services = {
|
||||
jellyfin.enable = true;
|
||||
|
||||
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}";
|
||||
};
|
||||
};
|
||||
secrets.mailer = {
|
||||
USER = cfg.secretFiles.forgejoMailerUser;
|
||||
PASSWD = cfg.secretFiles.forgejoMailerPassword;
|
||||
};
|
||||
};
|
||||
|
||||
rabbi-gerzi = {
|
||||
enable = true;
|
||||
frontend = {
|
||||
hostName = "rabbigerzi.${domainName}";
|
||||
nginx = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
};
|
||||
backend = {
|
||||
hostName = "rabbigerziapi.${domainName}";
|
||||
environmentFile = cfg.secretFiles.rabbiGerziEnvironment;
|
||||
nginx = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"${domainName}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/".root = "${resumePackage}";
|
||||
};
|
||||
|
||||
"jellyfin.${domainName}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/".proxyPass = "http://localhost:8096";
|
||||
};
|
||||
|
||||
"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 ${cfg.secretFiles.borgPassphrase}";
|
||||
};
|
||||
doInit = true;
|
||||
compression = "auto,zstd";
|
||||
startAt = "*-*-* 03:15:00";
|
||||
persistentTimer = true;
|
||||
prune.keep = {
|
||||
daily = 7;
|
||||
weekly = 4;
|
||||
monthly = 6;
|
||||
};
|
||||
environment.BORG_RSH = "ssh -i ${cfg.secretFiles.borgPrivateKey} -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
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
security.acme = {
|
||||
defaults = {
|
||||
webroot = "/var/lib/acme/acme-challenge/";
|
||||
email = "yisroel.d.baum@gmail.com";
|
||||
};
|
||||
acceptTerms = true;
|
||||
};
|
||||
|
||||
systemd.services.borgbackup-job-forgejo = {
|
||||
after = [
|
||||
"sops-install-secrets.service"
|
||||
"network-online.target"
|
||||
];
|
||||
wants = [ "network-online.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
82
nix/tests/module.nix
Normal file
82
nix/tests/module.nix
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
nixpkgs,
|
||||
self,
|
||||
system,
|
||||
}:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
evaluatedSystem = nixpkgs.lib.nixosSystem {
|
||||
inherit system;
|
||||
modules = [
|
||||
self.nixosModules.default
|
||||
{
|
||||
system.stateVersion = "25.11";
|
||||
services.yisroelbaum-web = {
|
||||
enable = true;
|
||||
secretFiles = {
|
||||
borgPassphrase = "/run/secrets/borg-passphrase";
|
||||
borgPrivateKey = "/run/secrets/borg-private-key";
|
||||
forgejoMailerUser = "/run/secrets/forgejo-mailer-user";
|
||||
forgejoMailerPassword = "/run/secrets/forgejo-mailer-password";
|
||||
rabbiGerziEnvironment = "/run/secrets/rabbi-gerzi.env";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
evaluatedConfig = evaluatedSystem.config;
|
||||
virtualHosts = evaluatedConfig.services.nginx.virtualHosts;
|
||||
certificates = evaluatedConfig.security.acme.certs;
|
||||
forgejoBackup = evaluatedConfig.services.borgbackup.jobs.forgejo;
|
||||
forgejoBackupService = evaluatedConfig.systemd.services.borgbackup-job-forgejo;
|
||||
publicHostNames = [
|
||||
"yisroelbaum.com"
|
||||
"jellyfin.yisroelbaum.com"
|
||||
"git.yisroelbaum.com"
|
||||
"rabbigerzi.yisroelbaum.com"
|
||||
"rabbigerziapi.yisroelbaum.com"
|
||||
];
|
||||
in
|
||||
assert evaluatedConfig.services.nginx.enable;
|
||||
assert evaluatedConfig.services.jellyfin.enable;
|
||||
assert evaluatedConfig.services.forgejo.enable;
|
||||
assert evaluatedConfig.services.rabbi-gerzi.enable;
|
||||
assert
|
||||
virtualHosts."yisroelbaum.com".locations."/".root
|
||||
== "${self.inputs.resume.packages.${system}.default}";
|
||||
assert virtualHosts."jellyfin.yisroelbaum.com".locations."/".proxyPass == "http://localhost:8096";
|
||||
assert virtualHosts."git.yisroelbaum.com".locations."/".proxyPass == "http://127.0.0.1:3000";
|
||||
assert !virtualHosts."git.yisroelbaum.com".locations."/".recommendedProxySettings;
|
||||
assert nixpkgs.lib.hasInfix "proxy_set_header X-Forwarded-Proto $scheme;"
|
||||
virtualHosts."git.yisroelbaum.com".locations."/".extraConfig;
|
||||
assert builtins.all (
|
||||
hostName:
|
||||
virtualHosts.${hostName}.forceSSL
|
||||
&& virtualHosts.${hostName}.enableACME
|
||||
&& certificates.${hostName}.domain == hostName
|
||||
) publicHostNames;
|
||||
assert builtins.all (certificate: !(nixpkgs.lib.hasPrefix "*." certificate.domain)) (
|
||||
builtins.attrValues certificates
|
||||
);
|
||||
assert evaluatedConfig.services.forgejo.settings.server.ROOT_URL == "https://git.yisroelbaum.com/";
|
||||
assert evaluatedConfig.services.forgejo.settings.server.DOMAIN == "git.yisroelbaum.com";
|
||||
assert evaluatedConfig.services.forgejo.settings.server.SSH_PORT == 2222;
|
||||
assert evaluatedConfig.services.forgejo.settings.mailer.FROM == "me@yisroelbaum.com";
|
||||
assert evaluatedConfig.services.forgejo.secrets.mailer.USER == "/run/secrets/forgejo-mailer-user";
|
||||
assert
|
||||
evaluatedConfig.services.forgejo.secrets.mailer.PASSWD == "/run/secrets/forgejo-mailer-password";
|
||||
assert evaluatedConfig.services.rabbi-gerzi.frontend.hostName == "rabbigerzi.yisroelbaum.com";
|
||||
assert evaluatedConfig.services.rabbi-gerzi.backend.hostName == "rabbigerziapi.yisroelbaum.com";
|
||||
assert
|
||||
evaluatedConfig.services.rabbi-gerzi.backend.environmentFile == "/run/secrets/rabbi-gerzi.env";
|
||||
assert forgejoBackup.repo == "ssh://n5lniyfd@n5lniyfd.repo.borgbase.com/./repo";
|
||||
assert forgejoBackup.startAt == "*-*-* 03:15:00";
|
||||
assert forgejoBackup.persistentTimer;
|
||||
assert forgejoBackup.prune.keep.daily == 7;
|
||||
assert forgejoBackup.prune.keep.weekly == 4;
|
||||
assert forgejoBackup.prune.keep.monthly == 6;
|
||||
assert builtins.elem evaluatedConfig.services.forgejo.stateDir forgejoBackup.paths;
|
||||
assert builtins.elem "sops-install-secrets.service" forgejoBackupService.after;
|
||||
pkgs.runCommand "yisroelbaum-web-module-eval" { } ''
|
||||
touch "$out"
|
||||
''
|
||||
Loading…
Add table
Add a link
Reference in a new issue