From f445bd86590ac58108a1971464bbbf066f37ef7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Numbus?= Date: Sun, 22 Feb 2026 20:34:44 +0100 Subject: [PATCH] Added the rest of the configuration. Still some things to add. --- README.md | 30 ++- modules/default.nix | 7 +- modules/hardware/boot.nix | 11 + modules/hardware/cpu.nix | 7 + modules/hardware/default.nix | 9 + modules/hardware/disks.nix | 322 ++++++++++++++++++++++++++ modules/mail/default.nix | 7 + modules/mail/smtp.nix | 84 +++++++ modules/misc/default.nix | 10 + modules/misc/internationalisation.nix | 22 ++ modules/misc/power.nix | 28 +++ modules/misc/update.nix | 21 ++ modules/misc/users.nix | 16 ++ modules/networking/default.nix | 8 + modules/networking/firewall.nix | 11 + modules/networking/networking.nix | 52 +++++ modules/packages/default.nix | 9 + modules/packages/packages.nix | 25 ++ modules/packages/podman.nix | 13 ++ modules/packages/ssh.nix | 5 + modules/secrets.nix | 0 modules/services/immich.nix | 8 + modules/services/lib.nix | 3 +- 23 files changed, 705 insertions(+), 3 deletions(-) create mode 100644 modules/hardware/boot.nix create mode 100644 modules/hardware/cpu.nix create mode 100644 modules/hardware/default.nix create mode 100644 modules/hardware/disks.nix create mode 100644 modules/mail/default.nix create mode 100644 modules/mail/smtp.nix create mode 100644 modules/misc/default.nix create mode 100644 modules/misc/internationalisation.nix create mode 100644 modules/misc/power.nix create mode 100644 modules/misc/update.nix create mode 100644 modules/misc/users.nix create mode 100644 modules/networking/default.nix create mode 100644 modules/networking/firewall.nix create mode 100644 modules/networking/networking.nix create mode 100644 modules/packages/default.nix create mode 100644 modules/packages/packages.nix create mode 100644 modules/packages/podman.nix create mode 100644 modules/packages/ssh.nix create mode 100644 modules/secrets.nix diff --git a/README.md b/README.md index facea70..e026546 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,30 @@ -# numbus-server-module +# ☁️ Numbus Server: Your Personal Cloud, Simplified 🚀 +Welcome to the **Numbus Server** project! + +⚠️ This repository contains the NixOS module that configures the numbus server. **Please head to https://gittea.dev/numbus/numbus-server to get more information and installation instructions.** + +This repository provides a complete NixOS configuration to deploy a personal home server with a rich set of services in minutes. Our goal is to make self-hosting accessible to everyone, allowing you to take back control of your data with a solution that is easy to manage and highly reliable. + +## 🛠️ Key Technologies + +- **NixOS:** A declarative Linux distribution that makes system management a breeze. +- **Nix Flakes:** For reproducible builds and dependency management. +- **Numbus Server NixOS module:** To make user's configuration simpler. +- **Podman:** To run containerized services with ease. +- **Traefik:** A modern reverse proxy to access services securely. +- **Sops-nix:** For a secure and convenient way of managing secrets. +- **NixOS-anywhere:** For a seamless initial deployment to any machine. +- **Disko:** For a declarative and predictable disk partitioning. + +## 🔧 Numbus Server NixOS Module + +This repository contains the code of this module. This modules contains the **complex NixOS configuration** : networking, user creation, container management, secrets provisioning, power settings, and much more. Since all the **complexity** of the configuration is contained in this module, this allows the end user configuration to be very **simple and clean**. + +## 🤝 Contributing + +Contributions are welcome! If you have any ideas, suggestions, or bug reports, please open an issue or submit a pull request. + +## 📄 License + +This project is licensed under the AGPLv3. See the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/modules/default.nix b/modules/default.nix index 0bd7deb..b64d5e5 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -2,7 +2,12 @@ { imports = [ - ./global.nix + ./hardware/default.nix + ./mail/default.nix + ./misc/default.nix + ./networking/default.nix + ./packages/default.nix ./services/default.nix + ./global.nix ]; } \ No newline at end of file diff --git a/modules/hardware/boot.nix b/modules/hardware/boot.nix new file mode 100644 index 0000000..89c82ad --- /dev/null +++ b/modules/hardware/boot.nix @@ -0,0 +1,11 @@ +{ config, ... }: + +{ + boot.initrd.systemd.enable = true; + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + boot.kernel.sysctl = { + "vm.overcommit_memory" = 1; + }; +} \ No newline at end of file diff --git a/modules/hardware/cpu.nix b/modules/hardware/cpu.nix new file mode 100644 index 0000000..8dcb9dc --- /dev/null +++ b/modules/hardware/cpu.nix @@ -0,0 +1,7 @@ +{ config, ... }: + +{ + hardware.enableRedistributableFirmware = true; + hardware.cpu.intel.updateMicrocode = true; + hardware.cpu.amd.updateMicrocode = true; +} \ No newline at end of file diff --git a/modules/hardware/default.nix b/modules/hardware/default.nix new file mode 100644 index 0000000..1dc1e7c --- /dev/null +++ b/modules/hardware/default.nix @@ -0,0 +1,9 @@ +{ ... }: + +{ + imports = [ + ./boot.nix + ./cpu.nix + ./disks.nix + ]; +} \ No newline at end of file diff --git a/modules/hardware/disks.nix b/modules/hardware/disks.nix new file mode 100644 index 0000000..fcb533b --- /dev/null +++ b/modules/hardware/disks.nix @@ -0,0 +1,322 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.numbus.hardware; + + mkDataDisk = idx: device: { + name = "content-${toString idx}"; + value = { + type = "disk"; + device = device; + content = { + type = "gpt"; + partitions = { + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-content-${toString idx}"; + initrdUnlock = false; + settings = { + keyFile = "/etc/secrets/disks/content-${toString idx}"; + allowDiscards = true; + crypttabExtraOpts = [ "nofail" ]; + }; + content = { + type = "filesystem"; + format = cfg.dataDisksFilesystem; + mountpoint = "/mnt/content-${toString idx}"; + mountOptions = [ "nofail" "noauto" ]; + }; + }; + }; + }; + }; + }; + }; + + mkParityDisk = idx: device: { + name = "parity-${toString idx}"; + value = { + type = "disk"; + device = device; + content = { + type = "gpt"; + partitions = { + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-parity-${toString idx}"; + initrdUnlock = false; + settings = { + keyFile = "/etc/secrets/disks/parity-${toString idx}"; + allowDiscards = true; + crypttabExtraOpts = [ "nofail" ]; + }; + content = { + type = "filesystem"; + format = cfg.parityDisksFilesystem; + mountpoint = "/mnt/parity-${toString idx}"; + mountOptions = [ "nofail" "noauto" ]; + }; + }; + }; + }; + }; + }; + }; + + isMirror = length cfg.bootDisksList > 1; + + bootDisksConfig = if isMirror then { + mdadm = { + boot = { + type = "mdadm"; + level = 1; + metadata = "1.2"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + }; + disk = listToAttrs (imap1 (i: device: { + name = "boot-${toString i}"; + value = { + type = "disk"; + device = device; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "mdraid"; + name = "boot"; + }; + }; + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-boot-${toString i}"; + settings = { + allowDiscards = true; + keyFile = "/etc/secrets/disks/boot-${toString i}"; + }; + content = { + type = "lvm_pv"; + vg = "pool"; + }; + }; + }; + }; + }; + }; + }) cfg.bootDisksList); + } else { + disk = { + "boot-1" = { + type = "disk"; + device = head cfg.bootDisksList; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-boot-1"; + settings = { + keyFile = "/etc/secrets/disks/boot-1"; + allowDiscards = true; + }; + content = { + type = "lvm_pv"; + vg = "pool"; + }; + }; + }; + }; + }; + }; + }; + }; + + lvmConfig = { + lvm_vg = { + pool = { + type = "lvm_vg"; + lvs = { + swap = { + size = cfg.swapSize; + content = { + type = "swap"; + }; + } // optionalAttrs isMirror { lvm_type = "mirror"; }; + snapraid = { + size = "1G"; + content = { + type = "filesystem"; + format = "btrfs"; + mountpoint = "/mnt/content-0"; + }; + } // optionalAttrs isMirror { lvm_type = "mirror"; }; + root = { + size = "100%"; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "/rootfs" = { + mountpoint = "/"; + mountOptions = [ "compress=zstd" "noatime" ]; + }; + "/home" = { + mountpoint = "/home"; + mountOptions = [ "compress=zstd" ]; + }; + "/nix" = { + mountpoint = "/nix"; + mountOptions = [ "compress=zstd" "noatime" ]; + }; + }; + }; + } // optionalAttrs isMirror { lvm_type = "mirror"; }; + }; + }; + }; + }; + +in +{ + options.numbus.hardware = { + dataDisksList = mkOption { + type = types.listOf types.str; + default = []; + example = [ "/dev/disk/by-id/WD_Blue_ATO431_159Ejz224G0000382b" "/dev/disk/by-id/Seagate_Barracuda_159Ejz224G" ]; + description = "List by-id path of devices for data disks"; + }; + parityDisksList = mkOption { + type = types.listOf types.str; + default = []; + example = [ "/dev/disk/by-id/WD_Blue_ATO431_159Ejz224G0000382b" "/dev/disk/by-id/Seagate_Barracuda_159Ejz224G" ]; + description = "List of by-id path of devices for parity disks"; + }; + bootDisksList = mkOption { + type = types.listOf types.str; + default = []; + example = [ "/dev/disk/by-id/nvme_SAMSUNG_MZVPYEHCO_159Ejz224G0000" "/dev/disk/by-id/ata-San_Disk_159Ejz224G" ]; + description = "List of by-id path of devices for boot disks"; + }; + swapSize = mkOption { + type = types.str; + default = "16G"; + example = "16G"; + description = "Size of the swap partition"; + }; + dataDisksFilesystem = mkOption { + type = types.enum [ "xfs" "ext4" "btrfs" ]; + default = "xfs"; + example = "xfs"; + description = "Filesystem for data disks. Available filesystem options : xfs, ext4, btrfs"; + }; + parityDisksFilesystem = mkOption { + type = types.enum [ "xfs" "ext4" "btrfs" ]; + default = "xfs"; + example = "xfs"; + description = "Filesystem for parity disks. Available filesystem options : xfs, ext4, btrfs"; + }; + }; + + config = mkIf (cfg.bootDisksList != []) { + disko.devices = mkMerge [ + bootDisksConfig + lvmConfig + { + disk = listToAttrs (imap1 mkDataDisk cfg.dataDisksList); + } + { + disk = listToAttrs (imap1 mkParityDisk cfg.parityDisksList); + } + ]; + + services.snapraid = { + enable = true; + contentFiles = [ "/mnt/content-0/snapraid.content" ] ++ + (map (i: "/mnt/content-${toString i}/snapraid.content") (range 1 (length cfg.dataDisksList))); + parityFiles = map (i: "/mnt/parity-${toString i}/snapraid.parity") (range 1 (length cfg.parityDisksList)); + dataDisks = listToAttrs (imap1 (i: _: nameValuePair "d${toString i}" "/mnt/content-${toString i}") cfg.dataDisksList); + }; + + fileSystems."/mnt/data" = { + device = "/mnt/content-*"; + fsType = "fuse.mergerfs"; + options = [ + "category.create=ff" + "cache.files=partial" + "dropcacheonclose=true" + "defaults" + "noauto" + "nofail" + "allow_other" + "moveonenospc=1" + "minfreespace=50G" + "func.getattr=newest" + "fsname=mergerfs_data" + "x-mount.mkdir" + "x-systemd.automount" + ]; + }; + + systemd.services.mount-disks = { + description = "Mount data and parity disks"; + before = [ "mnt-data.mount" ]; + requiredBy = [ "mnt-data.mount" ]; + path = [ pkgs.cryptsetup pkgs.util-linux ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = let + mountDataDisk = i: '' + if [ ! -e /dev/mapper/crypted-content-${toString i} ]; then + cryptsetup luksOpen --key-file /etc/secrets/disks/content-${toString i} /dev/disk/by-partlabel/disk-content-${toString i}-luks crypted-content-${toString i} + fi + mkdir -p /mnt/content-${toString i} + if ! mountpoint -q /mnt/content-${toString i}; then + mount -t ${cfg.dataDisksFilesystem} /dev/mapper/crypted-content-${toString i} /mnt/content-${toString i} + fi + ''; + mountParityDisk = i: '' + if [ ! -e /dev/mapper/crypted-parity-${toString i} ]; then + cryptsetup luksOpen --key-file /etc/secrets/disks/parity-${toString i} /dev/disk/by-partlabel/disk-parity-${toString i}-luks crypted-parity-${toString i} + fi + mkdir -p /mnt/parity-${toString i} + if ! mountpoint -q /mnt/parity-${toString i}; then + mount -t ${cfg.parityDisksFilesystem} /dev/mapper/crypted-parity-${toString i} /mnt/parity-${toString i} + fi + ''; + in '' + ${concatMapStrings mountDataDisk (range 1 (length cfg.dataDisksList))} + ${concatMapStrings mountParityDisk (range 1 (length cfg.parityDisksList))} + ''; + }; + }; +} \ No newline at end of file diff --git a/modules/mail/default.nix b/modules/mail/default.nix new file mode 100644 index 0000000..2ba32c3 --- /dev/null +++ b/modules/mail/default.nix @@ -0,0 +1,7 @@ +{ ... }: + +{ + imports = [ + ./smtp.nix + ]; +} \ No newline at end of file diff --git a/modules/mail/smtp.nix b/modules/mail/smtp.nix new file mode 100644 index 0000000..c6ee718 --- /dev/null +++ b/modules/mail/smtp.nix @@ -0,0 +1,84 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.numbus.services.mail; +in + +{ + options.numbus.services.mail = { + enable = mkEnableOption "Email sending functionality"; + + userAddress = mkOption { + description = "The address of the user this server will send emails to"; + type = types.str; + example = "user@your-domain.com"; + }; + + adminAddress = mkOption { + description = "The address of the admin this server will send emails to"; + type = types.str; + example = "admin@your-domain.com"; + }; + + smtpUsername = mkOption { + description = "The username/email that will be use to authenticate to the SMTP server"; + type = types.str; + example = "your-smtp-enabled-address@your-domain.com"; + }; + + smtpPasswordPath = mkOption { + description = "The path to a file containing the password that will be use to authenticate to the SMTP server"; + type = types.path; + example = "/run/secrets/smtp-password"; + }; + + fromAddress = mkOption { + description = "This server will send emails from this address"; + type = types.str; + default = "numbus-server-noreply@${config.numbus.services.domain}"; + example = "numbus-server-noreply@your-domain.com"; + }; + + smtpServer = mkOption { + description = "The SMTP server address your server will use to send emails"; + type = types.str; + default = "smtp.gmail.com"; + example = "smtp.your-provider.com"; + }; + + smtpPort = mkOption { + description = "The SMTP port your server will connect to to send emails"; + type = types.port; + default = 587; + example = 587; + }; + }; + + config = mkIf cfg.enable { + environment.etc."aliases".text = '' + root: ${cfg.userAddress}, ${cfg.adminAddress} + default: ${cfg.userAddress}, ${cfg.adminAddress} + ''; + + programs.msmtp = { + enable = true; + defaults = { + aliases = "/etc/aliases"; + timeout = 60; + syslog = "on"; + }; + accounts.default = { + auth = true; + host = cfg.smtpServer; + port = cfg.smtpPort; + from = cfg.fromAddress; + user = cfg.smtpUsername; + tls = true; + tls_starttls = true; + passwordeval = "${pkgs.coreutils}/bin/cat ${cfg.smtpPasswordPath}"; + }; + }; + }; +} \ No newline at end of file diff --git a/modules/misc/default.nix b/modules/misc/default.nix new file mode 100644 index 0000000..bc990b8 --- /dev/null +++ b/modules/misc/default.nix @@ -0,0 +1,10 @@ +{ ... }: + +{ + imports = [ + ./internationalisation.nix + ./power.nix + ./update.nix + ./users.nix + ]; +} \ No newline at end of file diff --git a/modules/misc/internationalisation.nix b/modules/misc/internationalisation.nix new file mode 100644 index 0000000..47eb470 --- /dev/null +++ b/modules/misc/internationalisation.nix @@ -0,0 +1,22 @@ +{ config, ... }: + +{ + i18n.defaultLocale = "fr_FR.UTF-8"; + i18n.extraLocaleSettings = { + LC_ADDRESS = "fr_FR.UTF-8"; + LC_IDENTIFICATION = "fr_FR.UTF-8"; + LC_MEASUREMENT = "fr_FR.UTF-8"; + LC_MONETARY = "fr_FR.UTF-8"; + LC_NAME = "fr_FR.UTF-8"; + LC_NUMERIC = "fr_FR.UTF-8"; + LC_PAPER = "fr_FR.UTF-8"; + LC_TELEPHONE = "fr_FR.UTF-8"; + LC_TIME = "fr_FR.UTF-8"; + }; + + console.keyMap = "fr"; + services.xserver.xkb = { + layout = "fr"; + variant = ""; + }; +} \ No newline at end of file diff --git a/modules/misc/power.nix b/modules/misc/power.nix new file mode 100644 index 0000000..178d970 --- /dev/null +++ b/modules/misc/power.nix @@ -0,0 +1,28 @@ +{ config, lib, pkgs, ... }: + +let + hardDrives = config.numbus.hardware.dataDisksList ++ config.numbus.hardware.parityDisksList; +in + +{ + systemd.services.hd-idle = { + description = "External HD spin down daemon"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "simple"; + ExecStart = + let + idleTime = toString 1800; + hardDriveParameter = lib.strings.concatMapStringsSep " " (x: "-a ${x} -i ${idleTime}") hardDrives; + in + "${pkgs.hd-idle}/bin/hd-idle -i 0 ${hardDriveParameter}"; + }; + }; + + services.autoaspm.enable = true; + powerManagement.powertop.enable = true; + boot.kernelParams = [ + "pcie_aspm=force" + "consoleblank=60" + ]; +} \ No newline at end of file diff --git a/modules/misc/update.nix b/modules/misc/update.nix new file mode 100644 index 0000000..41771e8 --- /dev/null +++ b/modules/misc/update.nix @@ -0,0 +1,21 @@ +{ config, ... }: + +{ + system.autoUpgrade = { + enable = true; + allowReboot = false; + flake = inputs.self.outPath; + flags = [ "--print-build-logs" ]; + dates = "02:00"; + randomizedDelaySec = "45min"; + }; + + nix.gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 7d"; + }; + + nix.settings.experimental-features = [ "nix-command" "flakes" ]; + nix.settings.auto-optimise-store = true; +} \ No newline at end of file diff --git a/modules/misc/users.nix b/modules/misc/users.nix new file mode 100644 index 0000000..063817c --- /dev/null +++ b/modules/misc/users.nix @@ -0,0 +1,16 @@ +{ config, ... }: + +{ + users.users.numbus-admin = { + shell = pkgs.fish; + isNormalUser = true; + description = "Numbus Admin"; + extraGroups = [ "wheel" ]; + uid = 1000; + initialPassword = "changeMe!"; + # required for auto start before user login + linger = true; + # required for rootless container with multiple users + autoSubUidGidRange = true; + }; +} \ No newline at end of file diff --git a/modules/networking/default.nix b/modules/networking/default.nix new file mode 100644 index 0000000..d1beb31 --- /dev/null +++ b/modules/networking/default.nix @@ -0,0 +1,8 @@ +{ ... }: + +{ + imports = [ + ./firewall.nix + ./networking.nix + ]; +} \ No newline at end of file diff --git a/modules/networking/firewall.nix b/modules/networking/firewall.nix new file mode 100644 index 0000000..337cb7a --- /dev/null +++ b/modules/networking/firewall.nix @@ -0,0 +1,11 @@ +{ config, ... }: + +{ + networking.nftables.enable = true; + networking.firewall = { + enable = true; + allowPing = true; + allowedTCPPorts = [ 53 80 443 ]; + allowedUDPPorts = [ 53 443 ]; + }; +} \ No newline at end of file diff --git a/modules/networking/networking.nix b/modules/networking/networking.nix new file mode 100644 index 0000000..5f120c5 --- /dev/null +++ b/modules/networking/networking.nix @@ -0,0 +1,52 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.numbus.services.networking; +in + +{ + options.numbus.services.networking = { + ipAddress = mkOption { + description = "The IP address that this server will use"; + type = types.str; + example = "192.168.1.100"; + }; + interface = mkOption { + description = "The interface that this server will use to connect to the network"; + type = types.str; + example = "enp1s0"; + }; + routerIpAddress = mkOption { + description = "The IP address of the router of your network"; + type = types.str; + example = "192.168.1.1"; + }; + dnsServers = mkOption { + description = "The list of DNS servers that this server will use"; + type = types.listOf types.str; + default = [ "${cfg.ipAddress}" "9.9.9.9" ]; + example = [ "${cfg.ipAddress}" "9.9.9.9" ]; + }; + }; + + networking.hostName = "numbus-server"; + networking.networkmanager.enable = false; + + # Allow rootless containers to bind to port 53 and up + boot.kernel.sysctl."net.ipv4.ip_unprivileged_port_start" = 53; + + networking.bridges.br0.interfaces = [ "${cfg.interface}" ]; + networking.interfaces."${cfg.interface}".useDHCP = false; + networking.interfaces.br0.useDHCP = false; + networking.nameservers = ${cfg.dnsServers}; + networking.interfaces.br0.ipv4.addresses = [{ + address = "${cfg.ipAddress}"; + prefixLength = 24; + }]; + networking.defaultGateway = { + address = "${cfg.routerIpAddress}"; + interface = "br0"; + }; +} \ No newline at end of file diff --git a/modules/packages/default.nix b/modules/packages/default.nix new file mode 100644 index 0000000..401b24c --- /dev/null +++ b/modules/packages/default.nix @@ -0,0 +1,9 @@ +{ ... }: + +{ + imports = [ + ./packages.nix + ./podman.nix + ./ssh.nix + ]; +} \ No newline at end of file diff --git a/modules/packages/packages.nix b/modules/packages/packages.nix new file mode 100644 index 0000000..13dc56e --- /dev/null +++ b/modules/packages/packages.nix @@ -0,0 +1,25 @@ +{ config, pkgs, ... }: + +{ + nixpkgs.config.allowUnfree = true; + + environment.systemPackages = with pkgs; [ + git + ncdu + fastfetch + tpm2-tss + sops + age + powertop + pciutils + hdparm + hd-idle + hddtemp + smartmontools + cpufrequtils + intel-gpu-tools + snapraid + mergerfs + mergerfs-tools + ]; +} \ No newline at end of file diff --git a/modules/packages/podman.nix b/modules/packages/podman.nix new file mode 100644 index 0000000..a182fa7 --- /dev/null +++ b/modules/packages/podman.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ...}: + +{ + virtualisation.podman.enable = true; + virtualisation.podman.defaultNetwork.settings.dns_enabled = true; + + environment.systemPackages = with pkgs; [ + podman + podman-compose + podman-tui + slirp4netns + ]; +} \ No newline at end of file diff --git a/modules/packages/ssh.nix b/modules/packages/ssh.nix new file mode 100644 index 0000000..6cc7ccc --- /dev/null +++ b/modules/packages/ssh.nix @@ -0,0 +1,5 @@ +{ config, ... }: + +{ + services.openssh.enable = true; +} \ No newline at end of file diff --git a/modules/secrets.nix b/modules/secrets.nix new file mode 100644 index 0000000..e69de29 diff --git a/modules/services/immich.nix b/modules/services/immich.nix index d254ba6..88612ea 100644 --- a/modules/services/immich.nix +++ b/modules/services/immich.nix @@ -15,6 +15,14 @@ helper.mkPodmanService { name = "immich"; pod = "immich"; defaultPort = "2283"; + useSopsSecrets = true; + + extraConfig = { + numbus.services.immich.secretMapping = { + DB_PASSWORD = "db_password"; + DB_USERNAME = "db_username"; # Assuming you add this to schema + }; + }; # Compose file good composeText = '' diff --git a/modules/services/lib.nix b/modules/services/lib.nix index 3333f71..22482be 100644 --- a/modules/services/lib.nix +++ b/modules/services/lib.nix @@ -31,6 +31,7 @@ with lib; extraOptions ? {}, extraConfig ? {}, delaySec ? 180, + useSopsSecrets ? false, # New argument to enable sops integration middlewares ? [ "secureHeaders" ], dependencies ? [ "traefik.service" "${config.numbus.services.dns}.service" ], }: @@ -135,7 +136,7 @@ ${concatStringsSep "\n" (map (m: " - ${m}") middlewares)} Type = "exec"; ExecStartPre = [ "bash -c 'sleep $((RANDOM % ${toString delaySec}))'" - "-sudo -u numbus-admin podman-compose -f /etc/podman/${name}/compose.yaml pull" + "- sudo -u numbus-admin podman-compose -f /etc/podman/${name}/compose.yaml pull" ]; ExecStart = "sudo -u numbus-admin podman-compose --in-pod ${toString pod} -f /etc/podman/${name}/compose.yaml up --remove-orphans"; ExecStop = "sudo -u numbus-admin podman-compose --in-pod ${toString pod} -f /etc/podman/${name}/compose.yaml down";