{ description = "A very basic flake"; inputs = { deploy-rs = { url = "github:serokell/deploy-rs"; inputs.nixpkgs.follows = "nixpkgs"; }; image-builder.url = "git+https://git.asonix.dog/asonix/nixos-aarch64-images"; nixpkgs.url = "github:nixos/nixpkgs/master"; sops-nix = { url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; }; outputs = { self, deploy-rs, image-builder, nixpkgs, sops-nix }: let pkgs = import nixpkgs { system = "aarch64-linux"; }; btrbkPrimary = { subvolumes ? [ ] }: { snapshot_dir = "@snapshots"; subvolume = builtins.foldl' (acc: subvol: acc // { ${subvol} = { }; }) { } subvolumes; }; btrbkSecondary = { targetDir, subvolumes ? [ ] }: { target = "send-receive ${targetDir}"; subvolume = builtins.foldl' (acc: subvol: acc // { ${subvol} = { snapshot_dir = "@snapshots"; snapshot_preserve_min = "all"; snapshot_create = "no"; }; }) { } subvolumes; }; sharedModule = { services.openssh.settings.PasswordAuthentication = false; # Use the extlinux boot loader. (NixOS wants to enable GRUB by default) boot.loader.grub.enable = false; # Enables the generation of /boot/extlinux/extlinux.conf boot.loader.generic-extlinux-compatible.enable = true; fileSystems."/" = { device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888"; fsType = "ext4"; }; environment.systemPackages = with pkgs; [ bottom btrbk cryptsetup htop ]; sops = { age.keyFile = "/home/asonix/.config/sops/age/keys.txt"; age.generateKey = true; secrets.private_key = { format = "yaml"; sopsFile = ./secrets/btrbk.yaml; }; secrets.nextcloudKeyFile = { format = "binary"; sopsFile = ./secrets/nextcloudKeyFile.bin; }; secrets.redtailKeyFile = { format = "binary"; sopsFile = ./secrets/redtailKeyFile.bin; }; secrets.whitestormKeyFile = { format = "binary"; sopsFile = ./secrets/whitestormKeyFile.bin; }; }; }; btrbkModule = ({ primaryIp ? null, mountDir, subvolumes }: { config, ... }: let primary = { snapshot_preserve_min = "2d"; snapshot_preserve = "35d 20w 12m"; transaction_log = "/var/log/btrbk.log"; volume = { "${mountDir}" = btrbkPrimary { inherit subvolumes; }; }; }; secondary = { backend_remote = "btrfs-progs-sudo"; ssh_identity = config.sops.secrets.private_key.path; ssh_user = "btrbk"; stream_buffer = "512m"; stream_compress = "gzip"; stream_compress_level = "default"; stream_compress_threads = "default"; target_preserve = "24h 7d"; target_preserve_min = "24h"; transaction_log = "/var/log/btrbk.log"; volume = { "ssh://${primaryIp}${mountDir}" = btrbkSecondary { targetDir = "${mountDir}/@snapshots"; inherit subvolumes; }; }; }; selected = if primaryIp == null then primary else secondary; in { services.btrbk = { sshAccess = [ { key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHTqU3EvTgY5/e9m6YyQWypQPK58t9iPmPnPYAvnODGB asonix@lionheart"; roles = [ "source" "info" "send" ]; } ]; extraPackages = with pkgs; [ gzip ]; instances.btrbk = { onCalendar = "hourly"; settings = selected; }; }; } ); makeDockerConfig = { hostname, extraModules ? [ ] }: with image-builder.packages.aarch64-linux.modules; nixpkgs.lib.nixosSystem { system = "aarch64-linux"; modules = [ sops-nix.nixosModules.sops sharedModule userModule ({ config, ... }: { environment.systemPackages = with pkgs; [ docker docker-compose ]; networking.hostName = hostname; virtualisation.docker.enable = true; }) ] ++ extraModules; }; makeNextcloudConfig = { hostname, primaryIp ? null }: with image-builder.packages.aarch64-linux.modules; let mountDir = "/btrfs/hdd"; in makeDockerConfig { inherit hostname; extraModules = [ rockPro64v2 (btrbkModule { inherit mountDir primaryIp; subvolumes = [ "@nc-config" "@nc-data" "@postgres" "@redis" "@gitea" "@gitea-conf" "@pihole" "@papermc" "@docker-cfg" "@garage" "@garage-config" ]; }) ({ config, ... }: { environment.etc.crypttab = { enable = true; text = '' cryptdrive1 /dev/sda1 ${config.sops.secrets.nextcloudKeyFile.path} luks cryptdrive2 /dev/sdb1 ${config.sops.secrets.nextcloudKeyFile.path} luks cryptdrive3 /dev/sdc1 ${config.sops.secrets.nextcloudKeyFile.path} luks ''; }; fileSystems."${mountDir}" = { device = "/dev/mapper/cryptdrive1"; fsType = "btrfs"; options = [ "defaults" "compress=zstd" "rw" ]; }; }) ]; }; makePostgresConfig = { hostname, keyFile, primaryIp ? null }: with image-builder.packages.aarch64-linux.modules; let mountDir = "/btrfs/ssd"; in makeDockerConfig { inherit hostname; extraModules = [ rock64 (btrbkModule { inherit mountDir primaryIp; subvolumes = [ "postgres" "postgres-cfg" ]; }) ({ config, ... }: let keyFilePath = config.sops.secrets."${keyFile}".path; in { environment.etc.crypttab = { enable = true; text = '' cryptdrive1 /dev/sda1 ${keyFilePath} luks ''; }; fileSystems."${mountDir}" = { device = "/dev/mapper/cryptdrive1"; fsType = "btrfs"; options = [ "defaults" "compress=zstd" "rw" ]; }; }) ]; }; deployer = { hostname, configuration }: { hostname = hostname; profiles.system = { sshUser = "asonix"; user = "root"; magicRollback = false; sshOpts = [ "-i" "/home/asonix/.ssh/kube-rsa" "-t" ]; path = deploy-rs.lib.aarch64-linux.activate.nixos configuration; }; }; in { nixosConfigurations = { nextcloud1 = makeNextcloudConfig { hostname = "nextcloud1"; # primaryIp = "192.168.20.28"; }; nextcloud2 = makeNextcloudConfig { hostname = "nextcloud2"; primaryIp = "192.168.20.21"; }; redtail1 = makePostgresConfig { hostname = "redtail1"; keyFile = "redtailKeyFile"; primaryIp = "192.168.20.24"; }; redtail2 = makePostgresConfig { hostname = "redtail2"; keyFile = "redtailKeyFile"; # primaryIp = "192.168.20.23"; }; whitestorm1 = makePostgresConfig { hostname = "whitestorm1"; keyFile = "whitestormKeyFile"; # primaryIp = "192.168.20.11"; }; whitestorm2 = makePostgresConfig { hostname = "whitestorm2"; keyFile = "whitestormKeyFile"; primaryIp = "192.168.20.26"; }; }; deploy.nodes.nextcloud2 = deployer { hostname = "192.168.20.28"; configuration = self.nixosConfigurations.nextcloud2; }; }; }