From 385374e15ef364ed20c193df59a29146c1ec6e76 Mon Sep 17 00:00:00 2001 From: Christoph Urlacher Date: Thu, 4 Apr 2024 18:18:28 +0200 Subject: [PATCH] Add ThinkNix config --- ThinkNix/configuration.nix | 294 ++++++++++++++++++++++ ThinkNix/hardware-configuration.nix | 33 +++ ThinkNix/services/0_TEMPLATE.nix | 32 +++ ThinkNix/services/adguard.nix | 49 ++++ ThinkNix/services/kopia.nix | 96 +++++++ ThinkNix/services/nginx-proxy-manager.nix | 36 +++ ThinkNix/services/portainer.nix | 30 +++ 7 files changed, 570 insertions(+) create mode 100644 ThinkNix/configuration.nix create mode 100644 ThinkNix/hardware-configuration.nix create mode 100644 ThinkNix/services/0_TEMPLATE.nix create mode 100644 ThinkNix/services/adguard.nix create mode 100644 ThinkNix/services/kopia.nix create mode 100644 ThinkNix/services/nginx-proxy-manager.nix create mode 100644 ThinkNix/services/portainer.nix diff --git a/ThinkNix/configuration.nix b/ThinkNix/configuration.nix new file mode 100644 index 0000000..85ae55b --- /dev/null +++ b/ThinkNix/configuration.nix @@ -0,0 +1,294 @@ +# Edit this configuration file to define what should be installed on +# your system. Help is available in the configuration.nix(5) man page +# and in the NixOS manual (accessible by running ‘nixos-help’). +{ + config, + pkgs, + ... +}: { + imports = [ + # Include the results of the hardware scan. + ./hardware-configuration.nix + + + # DNS (required for internet) + ./services/adguard.nix + # ./services/pihole.nix + + # General + # ./services/kopia.nix + ./services/nginx-proxy-manager.nix + ./services/portainer.nix + ]; + + # Bootloader. + boot = { + loader.grub.enable = true; + loader.grub.device = "/dev/sda"; + loader.grub.useOSProber = true; + + # NOTE: I think this needs a separate EFI partition? + # loader.systemd-boot = { + # enable = true; + # configurationLimit = 5; + # editor = false; + # # canTouchEfiVariables = true; + # # efiSysMountPoint = "/boot"; + # }; + }; + + # hardware = { + # opengl = { + # enable = true; + # driSupport = true; + # driSupport32Bit = true; + # }; + + # nvidia = { + # modesetting.enable = true; + # powerManagement.enable = false; # Experimental option, maybe this is the reason fileflows fails after some time? + # open = false; + # nvidiaSettings = false; + # }; + # }; + + networking = { + hostName = "thinknix"; # Define your hostname. + # wireless.enable = true; # Enables wireless support via wpa_supplicant. + + # Configure network proxy if necessary + # proxy.default = "http://user:password@proxy:port/"; + # proxy.noProxy = "127.0.0.1,localhost,internal.domain"; + + # Enable networking + networkmanager.enable = true; + + interfaces.ens18.ipv4.addresses = [{ + address = "192.168.86.26"; + prefixLength = 24; + }]; + defaultGateway = "192.168.86.5"; + nameservers = [ + "127.0.0.1" + # "192.168.86.25" + # "8.8.8.8" + ]; + }; + + systemd.services.init-behind-nginx-docker-network = { + description = "Create a docker network bridge for all services behind nginx-proxy-manager."; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig.Type = "oneshot"; + script = let + dockercli = "${config.virtualisation.docker.package}/bin/docker"; + network = "behind-nginx"; + in '' + # Put a true at the end to prevent getting non-zero return code, which will + # crash the whole service. + check=$(${dockercli} network ls | grep ${network} || true) + if [ -z "$check" ]; then + # TODO: Disable IP masquerading to show individual containers in AdGuard/Pi-Hole + # - Disabling this prevents containers from having internet connection. DNS issue? + # ${dockercli} network create -o "com.docker.network.bridge.enable_ip_masquerade"="false" ${network} + + ${dockercli} network create ${network} + else + echo "${network} already exists in docker" + fi + ''; + }; + + # Set your time zone. + time.timeZone = "Europe/Berlin"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + + i18n.extraLocaleSettings = { + LC_ADDRESS = "de_DE.UTF-8"; + LC_IDENTIFICATION = "de_DE.UTF-8"; + LC_MEASUREMENT = "de_DE.UTF-8"; + LC_MONETARY = "de_DE.UTF-8"; + LC_NAME = "de_DE.UTF-8"; + LC_NUMERIC = "de_DE.UTF-8"; + LC_PAPER = "de_DE.UTF-8"; + LC_TELEPHONE = "de_DE.UTF-8"; + LC_TIME = "de_DE.UTF-8"; + }; + + # Configure console keymap + console.keyMap = "us-acentos"; + + # Define a user account. Don't forget to set a password with ‘passwd’. + users.users.christoph = { + isNormalUser = true; + description = "Christoph"; + extraGroups = ["networkmanager" "wheel" "docker"]; + shell = pkgs.fish; + packages = with pkgs; []; + }; + + users.users.git = { + uid = 500; + group = "git"; + isNormalUser = false; + isSystemUser = true; + description = "Gitea User"; + extraGroups = ["docker"]; + shell = pkgs.fish; + }; + + home-manager.users.christoph = {pkgs, ...}: { + home.packages = with pkgs; [ + lazygit + keychain + alejandra + nnn + busybox + glances + ripgrep + + docker-compose + ]; + + programs = { + fish = { + enable = true; + }; + + git = { + enable = true; + userEmail = "christoph.urlacher@protonmail.com"; + userName = "Christoph Urlacher"; + }; + + keychain = { + enable = true; + enableFishIntegration = true; + agents = ["ssh"]; + keys = ["id_ed25519"]; + }; + + starship = { + enable = true; + enableFishIntegration = true; + }; + + yt-dlp = { + enable = true; + }; + }; + + home.stateVersion = "23.05"; + }; + + virtualisation = { + docker = { + enable = true; + autoPrune.enable = true; + # enableNvidia = true; + # rootless = { + # enable = true; + # setSocketVariable = true; + # }; + daemon.settings = { + dns = [ + # TODO: Does this circumvent my DNS for each container? + # It might improve gitea actions though... + "8.8.8.8" + + # TODO: Might prevent containers from having DNS? + # "127.0.0.1" + # "192.168.86.25" + ]; + }; + }; + oci-containers.backend = "docker"; + }; + + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ + # vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default. + wget + helix + git + ]; + + programs = { + firejail.enable = true; + fish.enable = true; + git.enable = true; + neovim.enable = true; + # fuse.userAllowOther = true; + }; + + # Some programs need SUID wrappers, can be configured further or are + # started in user sessions. + # programs.mtr.enable = true; + # programs.gnupg.agent = { + # enable = true; + # enableSSHSupport = true; + # }; + + # List services that you want to enable: + + services = { + # Configure keymap in X11 + xserver = { + layout = "us"; + xkbVariant = "altgr-intl"; + # videoDrivers = ["nvidia"]; + }; + + # Trims the journal if it gets too large + journald.extraConfig = '' + SystemMaxUse=50M + ''; + + # Enable the OpenSSH daemon. + openssh.enable = true; + + ntp.enable = true; + qemuGuest.enable = true; + # TODO: Might prevent containers from having working DNS + # resolved.fallbackDns = ["8.8.8.8"]; + }; + + networking.firewall = { + # Open ports in the firewall. + allowedTCPPorts = [ + # PiHole requires these ports, as it's running in --net=host mode + 53 + 80 + + # 3000 # Gitea runner needs to reach local gitea instance + ]; + allowedUDPPorts = [ + # PiHole requires these ports, as it's running in --net=host mode + 53 + 67 # PiHole DHCP + + # 3000 # Gitea runner needs to reach local gitea instance + ]; + # Or disable the firewall altogether. + enable = true; + + trustedInterfaces = [ + "docker0" + ]; + }; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "23.05"; # Did you read the comment? +} diff --git a/ThinkNix/hardware-configuration.nix b/ThinkNix/hardware-configuration.nix new file mode 100644 index 0000000..8b2c36f --- /dev/null +++ b/ThinkNix/hardware-configuration.nix @@ -0,0 +1,33 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/2d1b1f62-f008-4562-906e-5a63d854b18b"; + fsType = "ext4"; + }; + + swapDevices = [ ]; + + # 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 + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.br-962bf00415f9.useDHCP = lib.mkDefault true; + # networking.interfaces.docker0.useDHCP = lib.mkDefault true; + # networking.interfaces.ens18.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/ThinkNix/services/0_TEMPLATE.nix b/ThinkNix/services/0_TEMPLATE.nix new file mode 100644 index 0000000..c624945 --- /dev/null +++ b/ThinkNix/services/0_TEMPLATE.nix @@ -0,0 +1,32 @@ +{ + config, + lib, + pkgs, + ... +}: { + virtualisation.oci-containers.containers.NAME = { + image = ""; + autoStart = true; + + dependsOn = [ + # "pihole" + ]; + + ports = []; + + volumes = []; + + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "Europe/Berlin"; + # NVIDIA_VISIBLE_DEVICES = "all"; + # NVIDIA_DRIVER_CAPABILITIES = "all"; + }; + + extraOptions = [ + # "--gpus=all" + "--net=behind-nginx" + ]; + }; +} diff --git a/ThinkNix/services/adguard.nix b/ThinkNix/services/adguard.nix new file mode 100644 index 0000000..933896a --- /dev/null +++ b/ThinkNix/services/adguard.nix @@ -0,0 +1,49 @@ +{ + config, + lib, + pkgs, + ... +}: { + virtualisation.oci-containers.containers.adguard = { + image = "adguard/adguardhome"; + autoStart = true; + + dependsOn = []; + + ports = [ + # DNS server + "53:53/tcp" + "53:53/udp" + # "853:853/tcp" # DNS over TLS + # "853:853/udp" # DNS over QUIC + + # DHCP server + # "67:67/udp" + # "68:68/tcp" + # "68:68/udp" + + # Admin panel + DNS over HTTPS + # "80:80/tcp" + # "443:443/tcp" + # "443:443/udp" + # "3100:3000/tcp" # Web interface + + # DNSCrypt + # "5443:5443/tcp" + # "5443:5443/udp" + + # "6060:6060/tcp" # Debugging + ]; + + volumes = [ + "adguard_config:/opt/adguardhome/conf" + "adguard_work:/opt/adguardhome/work" + ]; + + environment = {}; + + extraOptions = [ + "--net=behind-nginx" + ]; + }; +} diff --git a/ThinkNix/services/kopia.nix b/ThinkNix/services/kopia.nix new file mode 100644 index 0000000..7bce343 --- /dev/null +++ b/ThinkNix/services/kopia.nix @@ -0,0 +1,96 @@ +{ + config, + lib, + pkgs, + ... +}: { + virtualisation.oci-containers.containers.kopia = { + image = "kopia/kopia:latest"; + autoStart = true; + + dependsOn = []; + + ports = [ + # "51515:51515" + ]; + + volumes = [ + "kopia_config:/app/config" + "kopia_cache:/app/cache" + "kopia_logs:/app/logs" + "kopia_temp:/tmp" + + # Repository, where snapshots are stored (incrementally) + "/media/synology-syncthing:/repository" + + # Folders that are backed up + "adguard_config:/data/adguard_config:ro" + "adguard_work:/data/adguard_work:ro" + "authelia_config:/data/authelia_config:ro" + "bazarr_config:/data/bazarr_config:ro" + "box-fileflows_config:/data/box-fileflows_config:ro" + "box-hydra_config:/data/box-hydra_config:ro" + "box-sabnzbd_config:/data/box-sabnzbd_config:ro" + "box-stash_blobs:/data/box-stash_blobs:ro" + "box-stash_config:/data/box-stash_config:ro" + "box-stash_generated:/data/box-stash_generated:ro" + "box-stash_metadata:/data/box-stash_metadata:ro" + "fileflows_config:/data/fileflows_config:ro" + "formula10_data:/data/formula10_data:ro" + "gitea-db_data:/data/gitea-db_data:ro" + "gitea-runner_config:/data/gitea-runner_config:ro" + "gitea-runner_data:/data/gitea-runner_data:ro" + "gitea_data:/data/gitea_data:ro" + "heidi_config:/data/heidi_config:ro" + "homeassistant_config:/data/homeassistant_config:ro" + "homepage_config:/data/homepage_config:ro" + "immich-database_data:/data/immich-database_data:ro" + "immich_config:/data/immich_config:ro" + "immich_data:/data/immich_data:ro" + "immich_machine-learning:/data/immich_machine-learning:ro" + "jellyfin_config:/data/jellyfin_config:ro" + "jellyseerr_config:/data/jellyseerr_config:ro" + "jellystat-db_data:/data/jellystat-db_data:ro" + "jellystat_data:/data/jellystat_data:ro" + "nextcloud-db_data:/data/nextcloud-db_data:ro" + "nextcloud_data:/data/nextcloud_data:ro" + "nginx_config:/data/nginx_config:ro" + "nginx_letsencrypt:/data/nginx_letsencrypt:ro" + "nginx_snippets:/data/nginx_snippets:ro" + "paperless-postgres_data:/data/paperless-postgres_data:ro" + "paperless_data:/data/paperless_data:ro" + "portainer_config:/data/portainer_config:ro" + "prowlarr_config:/data/prowlarr_config:ro" + "radarr_config:/data/radarr_config:ro" + "sabnzbd_config:/data/sabnzbd_config:ro" + "sonarr_config:/data/sonarr_config:ro" + "uptime-kuma_config:/data/uptime-kuma_config:ro" + "wireguard_vps_config:/data/wireguard_vps_config:ro" + ]; + + environment = { + TZ = "Europe/Berlin"; + USER = "christoph"; + KOPIA_PASSWORD = (builtins.readFile ./kopia.password); + }; + + entrypoint = "/bin/kopia"; + + cmd = [ + "server" + "start" + "--disable-csrf-token-checks" + "--insecure" + "--address=0.0.0.0:51515" + "--server-username=christoph" + "--server-password=kopia" + ]; + + extraOptions = [ + "--privileged" + "--device=/dev/fuse:/dev/fuse:rwm" + "--cap-add=SYS_ADMIN" + "--net=behind-nginx" + ]; + }; +} diff --git a/ThinkNix/services/nginx-proxy-manager.nix b/ThinkNix/services/nginx-proxy-manager.nix new file mode 100644 index 0000000..a088b6c --- /dev/null +++ b/ThinkNix/services/nginx-proxy-manager.nix @@ -0,0 +1,36 @@ +{ + config, + lib, + pkgs, + ... +}: { + virtualisation.oci-containers.containers.nginx-proxy-manager = { + image = "jc21/nginx-proxy-manager:latest"; + autoStart = true; + + dependsOn = [ + # "pihole" + ]; + + ports = [ + "80:80" + # "81:81" # Web interface + "443:443" + ]; + + volumes = [ + "nginx_config:/data" + "nginx_snippets:/snippets" + "nginx_letsencrypt:/etc/letsencrypt" + ]; + + environment = { + DISABLE_IPV6 = "true"; + }; + + extraOptions = [ + # "--net=host" + "--net=behind-nginx" + ]; + }; +} diff --git a/ThinkNix/services/portainer.nix b/ThinkNix/services/portainer.nix new file mode 100644 index 0000000..d0b67b2 --- /dev/null +++ b/ThinkNix/services/portainer.nix @@ -0,0 +1,30 @@ +{ + config, + lib, + pkgs, + ... +}: { + virtualisation.oci-containers.containers.portainer = { + image = "portainer/portainer-ce:latest"; + autoStart = true; + + dependsOn = []; + + ports = [ + # "8000:8000" + # "9443:9443" + ]; + + volumes = [ + "portainer_config:/data" + + "/var/run/docker.sock:/var/run/docker.sock" + ]; + + environment = {}; + + extraOptions = [ + "--net=behind-nginx" + ]; + }; +}