diff --git a/.gitignore b/.gitignore index 5631c13..c347735 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ result-* # Ignore automatically generated direnv output .direnv + +# Docker garbage +hosts/andromeda/stacks/*/*.yml diff --git a/README.md b/README.md index c974c9e..08042cf 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,9 @@ TODO. ### Installing the Configuration -1. Copy/clone the configuration over to the host to install. +1. Copy/clone the configuration over to the host to install and `cd` into it. 2. Copy the sops key data to the host you are installing on (sops `key.txt` and `ssh_host_ed25519_key` to `/var/lib/sops-nix/`) 3. Run `sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount -f "$PWD#hostname"` to prepare the disk, replacing `hostname` with the host you want to install (ex. `andromeda`). -4. Before installing, prepare sops inside the mounted filesystem: `sudo mkdir -p /mnt/persist/var/lib/sops-nix/; sudo cp -r /var/lib/sops-nix/ /mnt/persist/var/lib/sops-nix/` +4. Before installing, prepare sops inside the mounted filesystem: `sudo mkdir -p /mnt/persist/var/lib/sops-nix/; sudo cp -r /var/lib/sops-nix/ /mnt/persist/var/lib/; sudo chmod -R 755 /mnt/persist/var/lib/sops-nix/` 5. Run `sudo nixos-install --flake "$PWD#hostname"` to install the OS, replacing `hostname` with the host you want to install (ex. `andromeda`). +6. Copy the current configuration into `/etc/nixos`: `sudo cp -r $PWD/. /mnt/persist/etc/nixos` diff --git a/hosts/andromeda/configuration.nix b/hosts/andromeda/configuration.nix index 50eb5d4..7e6366f 100755 --- a/hosts/andromeda/configuration.nix +++ b/hosts/andromeda/configuration.nix @@ -14,6 +14,9 @@ ../../system/sshd.nix ../../system/avahifixes.nix ../../system/i18n.nix + + # Docker stacks + ./andromeda/stacks/traefik/docker-compose.nix ]; users.mutableUsers = false; @@ -32,6 +35,10 @@ "networkmanager" ]; + packages = with pkgs; [ + git + ]; + openssh.authorizedKeys.keys = [ (builtins.readFile ../../data/id_user.pub) ]; @@ -46,12 +53,27 @@ # Services virtualisation.docker = { enable = true; + autoPrune.enable = true; + storageDriver = "btrfs"; }; + virtualisation.oci-containers.backend = "docker"; + + # Volumes + fileSystems."/mnt/NASBox" = { + device = "192.168.0.3:/mnt/Diskette/KubeData"; + fsType = "nfs"; + }; + environment.systemPackages = builtins.attrValues { inherit (pkgs) htop btop micro nano; }; + networking.firewall = { + enable = true; + allowedTCPPorts = [80 443 8000]; + }; + system.stateVersion = "24.11"; } diff --git a/hosts/andromeda/hardware-configuration.nix b/hosts/andromeda/hardware-configuration.nix index 6e470e7..b6935b7 100755 --- a/hosts/andromeda/hardware-configuration.nix +++ b/hosts/andromeda/hardware-configuration.nix @@ -9,12 +9,13 @@ ... }: { imports = [ - (modulesPath + "/installer/scan/not-detected.nix") + (modulesPath + "/profiles/qemu-guest.nix") ]; - boot.initrd.availableKernelModules = ["xhci_pci" "usbhid" "uas" "sd_mod"]; - boot.initrd.kernelModules = ["dm-snapshot"]; - boot.kernelModules = []; + boot.initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ahci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; + boot.initrd.kernelModules = [ "dm-snapshot" ]; + boot.kernelModules = [ "kvm-amd" ]; + boot.extraModulePackages = [ ]; # Enables DHCP on each ethernet and wireless interface. In case of scripted networking # (the default) this is the recommended approach. When using systemd-networkd it's @@ -23,5 +24,4 @@ networking.useDHCP = lib.mkDefault true; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; - hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; } diff --git a/hosts/andromeda/stacks/traefik/docker-compose.nix b/hosts/andromeda/stacks/traefik/docker-compose.nix new file mode 100644 index 0000000..ab1b51c --- /dev/null +++ b/hosts/andromeda/stacks/traefik/docker-compose.nix @@ -0,0 +1,39 @@ +# Auto-generated using compose2nix v0.3.1. +{ pkgs, lib, ... }: + +{ + # Containers + virtualisation.oci-containers.containers."traefik-reverse-proxy" = { + image = "traefik:v3.3"; + volumes = [ + "/var/run/docker.sock:/var/run/docker.sock:rw" + ]; + cmd = [ "--api.insecure=true" "--entryPoints.web.address=:8000" "--providers.docker" ]; + log-driver = "journald"; + extraOptions = [ + "--network=host" + ]; + }; + + systemd.services."docker-traefik-reverse-proxy" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + partOf = [ + "docker-compose-traefik-root.target" + ]; + wantedBy = [ + "docker-compose-traefik-root.target" + ]; + }; + + # Root service + # When started, this will automatically create all resources and start + # the containers. When stopped, this will teardown all resources. + systemd.targets."docker-compose-traefik-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + wantedBy = [ "multi-user.target" ]; + }; +} diff --git a/hosts/andromeda/stacks/traefik/docker-compose.yml b/hosts/andromeda/stacks/traefik/docker-compose.yml new file mode 100644 index 0000000..2f3092a --- /dev/null +++ b/hosts/andromeda/stacks/traefik/docker-compose.yml @@ -0,0 +1,12 @@ +version: '3' + +services: + reverse-proxy: + # The official v3 Traefik docker image + image: traefik:v3.3 + # Enables the web UI and tells Traefik to listen to docker + command: --api.insecure=true --entryPoints.web.address=:8000 --providers.docker + network_mode: host + volumes: + # So that Traefik can listen to the Docker events + - /var/run/docker.sock:/var/run/docker.sock diff --git a/system/disko.nix b/system/disko.nix index 225480d..a586c7a 100755 --- a/system/disko.nix +++ b/system/disko.nix @@ -21,28 +21,38 @@ size = "100%"; name = "NixOS"; content = { - type = "btrfs"; - extraArgs = ["-f"]; - subvolumes = { - root = { - name = "root"; - mountpoint = "/"; - }; - persist = { - name = "persist"; - mountpoint = "/persist"; - mountOptions = ["subvol=persist" "noatime"]; - }; - home = { - name = "home"; - mountpoint = "/home"; - mountOptions = ["subvol=home" "noatime"]; - }; - nix = { - name = "nix"; - mountpoint = "/nix"; - mountOptions = ["compress=zstd" "subvol=nix" "noatime"]; - }; + type = "lvm_pv"; + vg = "root_vg"; + }; + }; + }; + }; + }; + }; + lvm_vg = { + root_vg = { + type = "lvm_vg"; + lvs = { + root = { + size = "100%FREE"; + content = { + type = "btrfs"; + extraArgs = ["-f"]; + subvolumes = { + "/root" = { + mountpoint = "/"; + }; + "/persist" = { + mountpoint = "/persist"; + mountOptions = ["subvol=persist" "noatime"]; + }; + "/home" = { + mountpoint = "/home"; + mountOptions = ["subvol=home" "noatime"]; + }; + "/nix" = { + mountpoint = "/nix"; + mountOptions = ["subvol=nix" "noatime"]; }; }; }; diff --git a/system/sops.nix b/system/sops.nix index 2a6c84a..b135691 100755 --- a/system/sops.nix +++ b/system/sops.nix @@ -9,10 +9,10 @@ in sops = { defaultSopsFile = "${secretspath}/secrets.yaml"; age = { - # I'd prefer different OpenSSH keys for different hosts so I'm not 100% screwed if one of my devices get compromised. - # Therefore, we set a custom path for the sops key. - sshKeyPaths = ["/var/lib/sops-nix/ssh_host_ed25519_key"]; - keyFile = "/var/lib/sops-nix/key.txt"; + # I'd prefer different OpenSSH keys for different hosts so I'm not 100% screwed if one of my devices get compromised (SSH traffic potentially being decrypted and analyzed). + # Therefore, we set a custom path for the sops key & let the SSH key be generated automagically. + sshKeyPaths = ["/persist/var/lib/sops-nix/ssh_host_ed25519_key"]; + keyFile = "/persist/var/lib/sops-nix/key.txt"; generateKey = false; }; secrets = {