From 1ddf4c01e1084cbbb3d6791d744e355c1cb987fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Numbus?= Date: Wed, 7 Jan 2026 20:11:16 +0100 Subject: [PATCH] Big update to logic and nix files. Need testing. --- deploy.sh | 534 +++++++++--------- templates/nix-config/configuration.nix | 1 + templates/nix-config/disks/snapraid.nix | 3 +- templates/nix-config/misc/activation.nix | 12 + templates/nix-config/podman/adguard.coming | 41 ++ templates/nix-config/podman/frigate.nix | 5 +- templates/nix-config/podman/gitea.nix | 5 +- .../nix-config/podman/home-assistant.nix | 5 +- templates/nix-config/podman/immich.nix | 5 +- templates/nix-config/podman/it-tools.nix | 5 +- templates/nix-config/podman/nextcloud.nix | 7 +- templates/nix-config/podman/passbolt.nix | 5 +- templates/nix-config/podman/pi-hole.nix | 7 +- templates/nix-config/podman/traefik.nix | 102 +--- templates/post-install/numbus-server.conf | 7 +- 15 files changed, 363 insertions(+), 381 deletions(-) create mode 100644 templates/nix-config/misc/activation.nix create mode 100644 templates/nix-config/podman/adguard.coming diff --git a/deploy.sh b/deploy.sh index 7fe07ba..add9707 100644 --- a/deploy.sh +++ b/deploy.sh @@ -1,8 +1,6 @@ #!/usr/bin/env nix-shell #!nix-shell -i bash -p bash coreutils gnused gum fastfetch xkcdpass sops ssh-to-age age sshpass envsubst pciutils usbutils mosquitto - - ### --> Default settings export GUM_SPIN_SPINNER="minidot" export GUM_SPIN_SPINNER_BOLD=true @@ -15,8 +13,6 @@ NECESSARY_VARIABLES_LIST=("TARGET_HOST" "REMOTE_PASS" "SSH_PUBLIC_KEY" "DOMAIN_N "HOME_SERVER_IP" "SELECTED_SERVICES") ### Default settings <-- - - user_input() { local VAR_NAME="${1}" local HEADER="${2}" @@ -46,9 +42,7 @@ user_input() { done } - - -necessary_credentials() { +necessary_information() { # Regex Definitions local IP_REGEX='^([0-9]{1,3}\.){3}[0-9]{1,3}$' local SUBNET_REGEX='^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$' @@ -57,35 +51,33 @@ necessary_credentials() { local PORT_REGEX='^[0-9]{1,5}$' local SSH_KEY_REGEX='^ssh-[a-z0-9]+ [A-Za-z0-9+/]+.*' - #TARGET SETTINGS echo -e "\n\n➡️ This script needs information about the target you want to install NixOS on\n" + #TARGET SETTINGS user_input "TARGET_HOST" " Please provide the IP address of the target host :" "For example : 192.168.1.100" "${IP_REGEX}" "Invalid IP address format." user_input "REMOTE_PASS" " Please enter the password for '${TARGET_USER}@${TARGET_HOST}' :" "${TARGET_HOST}'s password" "" "" "true" user_input "SSH_PUBLIC_KEY" " Please provide the public SSH key of an authorized device :" "For example : ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGhcYDmjMo5YApLkk/3P3HZCnOSzm0uYewNAbxL8Fci8 user@your-pc" "${SSH_KEY_REGEX}" "Invalid SSH key format (must start with ssh-...)." "true" - # TRAEFIK SETTINGS echo -e "\n\n➡️ You will access your services via a domain name (e.g. cloud.mydomain.com) and containers need credentials to create those subdomains\n" + # TRAEFIK SETTINGS user_input "DOMAIN_NAME" " Please provide the domain name (FQDN) your home server will use :" "For example : yourdomain.com" "${DOMAIN_REGEX}" "Invalid domain name format." user_input "EMAIL_ADDRESS" " Please provide a valid email address (will be used for ACME, and your services) :" "For example : myemail@gmail.com" "${EMAIL_REGEX}" "Invalid email address format." user_input "CF_DNS_API_TOKEN" " Please provide a cloudflare API token with DNS zone permission :" "For example : bA7hdvCOuXGytlNKohi3ZGtlVpf5CHpLuCMiJrE" "" "" "true" - # SMTP SETTINGS echo -e "\n\n➡️ Some services will be able to send you emails. For that you need an email that supports sending emails (like Gmail for example)\n" + # SMTP SETTINGS user_input "SENDER_EMAIL_ADDRESS" " Please provide a valid sender email address :" "For example : myemail@gmail.com" "${EMAIL_REGEX}" "Invalid email address format." user_input "SENDER_EMAIL_ADDRESS_PASSWORD" " Please provide the password of this email address :" "abcd efgh ijkl mnop" "" "" "true" user_input "SENDER_EMAIL_DOMAIN" " Please provide the SMTP server endpoint :" "For Gmail : smtp.gmail.com" "${DOMAIN_REGEX}" "Invalid domain name format." user_input "SENDER_EMAIL_PORT" " Please provide the smtp TLS port :" "For Gmail : 587" "${PORT_REGEX}" "Invalid port number." - # NETWORK SETTINGS echo -e "\n\n➡️ This server will connect to your local network and you will configure its IP address\n" + # NETWORK SETTINGS user_input "HOME_ROUTER_SUBNET" " Please provide your home network subnet :" "For example 192.168.1.0/24" "${SUBNET_REGEX}" "Invalid subnet format (e.g. 192.168.1.1/24)." user_input "HOME_ROUTER_IP" " Please provide the ip address of your router :" "Most likely 192.168.1.1 or 192.168.1.254" "${IP_REGEX}" "Invalid IP address format." user_input "HOME_SERVER_IP" " Please choose the ip address that your server will use (i.e. any address in the 192.168.1.1/24 range that is not in use.) :" "For example 192.168.1.5" "${IP_REGEX}" "Invalid IP address format." } - - -necessary_credentials_with_config() { +necessary_information_config() { echo -e "\n\n➡️ Please choose your configuration file :" local CONFIG_PATH="$(gum file)" @@ -106,41 +98,12 @@ necessary_credentials_with_config() { fi } - - -generate_folder_tree() { +setup_ssh() { mkdir -p final-nix-config/ mkdir -p final-nix-config/home/ mkdir -p final-nix-config/home/numbus-admin/ mkdir -p final-nix-config/home/numbus-admin/.ssh/ - mkdir -p final-nix-config/mnt/ - mkdir -p final-nix-config/mnt/config/ - mkdir -p final-nix-config/mnt/data/ - - mkdir -p final-nix-config/mnt/config/traefik/ - mkdir -p final-nix-config/mnt/config/traefik/rules/ - mkdir -p final-nix-config/mnt/config/traefik/certs/ - - mkdir -p final-nix-config/etc/ - mkdir -p final-nix-config/etc/nixos/ - mkdir -p final-nix-config/etc/secrets/ - mkdir -p final-nix-config/etc/secrets/disks/ - mkdir -p final-nix-config/etc/numbus-server/ - mkdir -p final-nix-config/etc/nixos/misc/ - mkdir -p final-nix-config/etc/nixos/disks/ - mkdir -p final-nix-config/etc/nixos/pcie-coral/ - mkdir -p final-nix-config/etc/nixos/podman/ - mkdir -p final-nix-config/etc/nixos/secrets/ - - mkdir -p final-nix-config/var/ - mkdir -p final-nix-config/var/lib/ - mkdir -p final-nix-config/var/lib/sops-nix -} - - - -setup_ssh() { echo -e "\n\n✅ Generating new SSH key for numbus-admin..." chmod 700 final-nix-config/home/numbus-admin/.ssh/ ssh-keygen -t "ed25519" -C "numbus-admin@numbus-server" -f "final-nix-config/home/numbus-admin/.ssh/id_ed25519" -N "" -q @@ -154,8 +117,6 @@ setup_ssh() { fi } - - ssh_to_host() { local COMMAND="${1}" ssh -i "final-nix-config/home/numbus-admin/.ssh/id_ed25519" "${TARGET_USER}@${TARGET_HOST}" "${COMMAND}" @@ -163,7 +124,7 @@ ssh_to_host() { hardware_detection() { ### --> Get hardware information - export TMPFILE="/tmp/nixos-installation-hardware-detection-temp-file" + local TMPFILE="/tmp/nixos-installation-hardware-detection-temp-file" ssh_to_host 'bash -s' << SSHEND for brand in Intel AMD NVIDIA; do @@ -249,7 +210,7 @@ SSHEND ### Get hardware information <-- scp -i "final-nix-config/home/numbus-admin/.ssh/id_ed25519" "${TARGET_USER}@${TARGET_HOST}":"${TMPFILE}" "${TMPFILE}" &> /dev/null - source "${TMPFILE}" + source "${TMPFILE}" && rm -rf "${TMPFILE}" ### --> Generate hardware-configuration.nix if ssh_to_host "sudo nixos-generate-config --no-filesystems --show-hardware-config" > final-nix-config/etc/nixos/hardware-configuration.nix; then @@ -265,7 +226,7 @@ services_selection() { echo -e "\n\n➡️ You will now select the services you want installed on your server:" local AVAILABLE_SERVICES=( "frigate" "gitea" "home-assistant" "immich" "it-tools" \ -"nextcloud" "passbolt" "pi-hole" "virtualization" ) + "nextcloud" "passbolt" "pi-hole" "virtualization" ) local SERVICES_DESCRIPTION=( "Pi-Hole : Block ads on all your devices" \ "Immich : Pictures and videos backup with local machine-learning" \ @@ -287,114 +248,7 @@ services_selection() { done } -files_generation() { - # Helper to generate standard DB credentials - generate_db_creds() { - local SERVICE_UPPER="${1}" - export "${SERVICE_UPPER}_DB_NAME"="$(xkcdpass -d "-" -n 2)" - export "${SERVICE_UPPER}_DB_USERNAME"="$(xkcdpass -d "-" -n 2)" - export "${SERVICE_UPPER}_DB_PASSWORD"="$(xkcdpass -d "-")" - } - - echo -e "\n✅ Copying the configuration to the new machine..." - cp -avu templates/nix-config/configuration.nix final-nix-config/etc/nixos/ - cp -avu templates/nix-config/flake.nix final-nix-config/etc/nixos/ - cp -avu templates/nix-config/misc/* final-nix-config/etc/nixos/misc/ - - echo -e "\n✅ Writing correct ips to configuration.nix..." - sed -i "s|HOME_SERVER_IP|${HOME_SERVER_IP}|g" final-nix-config/etc/nixos/misc/networking.nix - sed -i "s|HOME_ROUTER_IP|${HOME_ROUTER_IP}|g" final-nix-config/etc/nixos/misc/networking.nix - sed -i "s|TARGET_INTERFACE|${TARGET_INTERFACE}|g" final-nix-config/etc/nixos/misc/networking.nix - sed -i "s|DOMAIN_NAME|${DOMAIN_NAME}|g" final-nix-config/etc/nixos/misc/mail.nix - sed -i "s|EMAIL_ADDRESS|${EMAIL_ADDRESS}|g" final-nix-config/etc/nixos/misc/mail.nix - sed -i "s|TARGET_INTERFACE|${SENDER_EMAIL_DOMAIN}|g" final-nix-config/etc/nixos/misc/mail.nix - sed -i "s|TARGET_INTERFACE|${SENDER_EMAIL_ADDRESS}|g" final-nix-config/etc/nixos/misc/mail.nix - - echo -e "\n✅ Writing configuration files for the selected homelab services..." - cp templates/nix-config/podman/traefik.nix final-nix-config/etc/nixos/podman/traefik.nix - envsubst < templates/podman-config/traefik/traefik.yaml > final-nix-config/mnt/config/traefik/traefik.yaml - - for service in "${SELECTED_SERVICES[@]}"; do - if [[ "${service}" != "virtualization" ]]; then - cp templates/nix-config/podman/${service}.nix final-nix-config/etc/nixos/podman/${service}.nix - fi - case "${service}" in - frigate) - local FRIGATE_DEVICES_BLOCK="" - [[ "$TARGET_GRAPHICS_RENDERER" == "true" ]] && local FRIGATE_DEVICES_BLOCK+=" - /dev/dri:/dev/dri\n" - [[ "$TARGET_USB_CORAL" == "true" ]] && local FRIGATE_DEVICES_BLOCK+=" - /dev/bus/usb:/dev/bus/usb\n" - if [[ "$TARGET_PCIE_CORAL" == "true" ]]; then - local FRIGATE_DEVICES_BLOCK+=" - /dev/apex_0:/dev/apex_0\n" - sed -i "s|# ./pcie-coral/coral.nix| ./pcie-coral/coral.nix|" final-nix-config/etc/nixos/configuration.nix - cp -avu templates/nix-config/pcie-coral/* final-nix-config/etc/nixos/pcie-coral/ - fi - if [[ -n "$FRIGATE_DEVICES_BLOCK" ]]; then - local REPLACEMENT="devices:\n${FRIGATE_DEVICES_BLOCK%\\n}" - sed -i "s|# --- frigate devices --- #|$REPLACEMENT|" final-nix-config/etc/nixos/podman/frigate.nix - fi - ;; - home-assistant) - if [[ -n "$TARGET_ZIGBEE_DEVICE" ]]; then - local REPLACEMENT="devices:\n - /dev/serial/by-id/${TARGET_ZIGBEE_DEVICE}:/dev/ttyUSB0" - sed -i "s|# --- hass devices --- #|$REPLACEMENT|" final-nix-config/etc/nixos/podman/home-assistant.nix - fi - export HOME_ASSISTANT_MQTT_USER="$(xkcdpass -d "-" -n 2)" - export HOME_ASSISTANT_MQTT_PASSWORD="$(xkcdpass -d "-")" - mkdir -p final-nix-config/mnt/config/mqtt/ - envsubst < templates/podman-config/hass/mosquitto.conf > final-nix-config/mnt/config/mqtt/mosquitto.conf - touch final-nix-config/mnt/config/mqtt/password.txt - chmod 0700 final-nix-config/mnt/config/mqtt/password.txt - mosquitto_passwd -b final-nix-config/mnt/config/mqtt/password.txt "$HOME_ASSISTANT_MQTT_USER" "$HOME_ASSISTANT_MQTT_PASSWORD" - ;; - passbolt) - generate_db_creds "PASSBOLT" - envsubst < templates/podman-config/traefik/headers.yaml > final-nix-config/mnt/config/traefik/rules/headers.yaml - envsubst < templates/podman-config/traefik/tls.yaml > final-nix-config/mnt/config/traefik/rules/tls.yaml - ;; - pi-hole) - export FTLCONF_WEBSERVER_PASSWORD="$(xkcdpass -d "-")" - ;; - immich) - local IMMICH_DEVICES_BLOCK="" - if [[ "$TARGET_GRAPHICS_RENDERER" == "true" ]]; then - local IMMICH_DEVICES_BLOCK+=" - /dev/dri:/dev/dri\n" - fi - if [[ -n "$IMMICH_DEVICES_BLOCK" ]]; then - local REPLACEMENT="devices:\n${IMMICH_DEVICES_BLOCK%\\n}" - sed -i "s|# --- immich devices --- #|$REPLACEMENT|" final-nix-config/etc/nixos/podman/immich.nix - fi - generate_db_creds "IMMICH" - ;; - gitea) - generate_db_creds "GITEA" - ;; - nextcloud) - envsubst < templates/podman-config/traefik/nextcloud.yaml > final-nix-config/mnt/config/traefik/rules/nextcloud.yaml - ;; - virtualization) - sed -i "s|# virtualisation.libvirtd.enable = true;| virtualisation.libvirtd.enable = true;|" final-nix-config/etc/nixos/configuration.nix - sed -i "s|# programs.virt-manager.enable = true;| programs.virt-manager.enable = true;|" final-nix-config/etc/nixos/configuration.nix - sed -i 's|extraGroups = \[ "wheel" \];|extraGroups = [ "wheel" "libvirtd" ];|' final-nix-config/etc/nixos/configuration.nix - ;; - esac - done - - echo -e "\n✅ Generating sops-nix keys..." - ssh-to-age -private-key -i final-nix-config/home/numbus-admin/.ssh/id_ed25519 > final-nix-config/var/lib/sops-nix/key.txt - export SOPS_PUBLIC_KEY=$(age-keygen -y final-nix-config/var/lib/sops-nix/key.txt) - - echo -e "\n✅ Generating sops-nix configuration files..." - envsubst < templates/nix-config/sops-nix/.sops.yaml > final-nix-config/etc/nixos/.sops.yaml - - echo -e "\n✅ Encrypting secrets in the correct file..." - envsubst < "templates/nix-config/sops-nix/secrets.yaml" \ - | sops encrypt --filename-override secrets.yaml \ - --input-type yaml --output-type yaml \ - --age $SOPS_PUBLIC_KEY \ - --output final-nix-config/etc/nixos/secrets/secrets.yaml -} - -disk_config_generation() { +disks_selection() { ### --> Disk wiping warning gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 " ⚠️ $(gum style --foreground 212 'WARNING:') You will choose the disks to install NixOS on. @@ -407,8 +261,6 @@ disk_config_generation() { echo -e "\n\n🔎 Fetching and analyzing disks from target host... (This may take a moment)" ### Disk wiping warning <-- - - ### --> Disk selection if [[ "${#DISK_NAME[@]}" -eq 0 ]]; then echo -e "\n❌ No disks found on the target host. Aborting." @@ -429,6 +281,12 @@ disk_config_generation() { local SELECTED_BOOT_DISK=$(gum choose --limit 2 --header "$HEADER" "${GUM_PRINTED_ELEMENTS[@]}") + echo "" + gum style --foreground 212 "➡️ Please choose data and parity disks (up to 9 total) :" + + local SELECTED_DATA_DISK=$(gum choose --limit 9 --header "$HEADER" "${GUM_PRINTED_ELEMENTS[@]}") +### Disk selection <-- + for i in ${!DISK_NAME[@]}; do if printf '%s' "$SELECTED_BOOT_DISK" | grep -iqw "${DISK_NAME[${i}]}"; then BOOT_DISKS_ID+=("${DISK_ID[${i}]:-${DISK_DEVPATH[${i}]}}") @@ -454,11 +312,6 @@ disk_config_generation() { exit 1 fi - echo "" - gum style --foreground 212 "➡️ Please choose data and parity disks (up to 9 total) :" - - local SELECTED_DATA_DISK=$(gum choose --limit 9 --header "$HEADER" "${GUM_PRINTED_ELEMENTS[@]}") - for i in ${!DISK_NAME[@]}; do if printf '%s' "$SELECTED_DATA_DISK" | grep -iq "${DISK_NAME[${i}]}"; then DATA_DISKS_ID+=("${DISK_ID[${i}]:-${DISK_DEVPATH[${i}]}}") @@ -467,57 +320,146 @@ disk_config_generation() { done if [[ "${#DATA_DISKS_ID[@]}" -eq 1 ]]; then - PARITY_DISK_NUMBER=0 - CONTENT_DISK_NUMBER=1 + export PARITY_DISK_NUMBER=0 + export CONTENT_DISK_NUMBER=1 else - PARITY_DISK_NUMBER=$(((${#DATA_DISKS_ID[@]} + 2) / 3)) - CONTENT_DISK_NUMBER=$((${#DATA_DISKS_ID[@]} - PARITY_DISK_NUMBER)) + export PARITY_DISK_NUMBER=$(((${#DATA_DISKS_ID[@]} + 2) / 3)) + export CONTENT_DISK_NUMBER=$((${#DATA_DISKS_ID[@]} - PARITY_DISK_NUMBER)) fi -### Disk selection <-- -### --> Selection recap - RECAP_CONTENT=$(cat << EOF -### Disk Configuration Summary + export DATA_DISKS_ID + export DATA_DISKS_TYPE +} -Please review the selected disk layout before proceeding. +folder_tree_generation() { + mkdir -p final-nix-config/mnt/ + mkdir -p final-nix-config/mnt/config/ + mkdir -p final-nix-config/mnt/data/ -**Boot Disks (${#BOOT_DISKS_ID[@]}):** -* **Boot 1:** \`${BOOT_DISKS_ID[0]}\` -$( [[ -n "${BOOT_DISKS_ID[1]:-}" ]] && echo "* **Boot 2:** \`${BOOT_DISKS_ID[1]}\`" || echo "* **Boot 2:** *Not configured*" ) + mkdir -p final-nix-config/mnt/config/traefik/ + mkdir -p final-nix-config/mnt/config/traefik/rules/ + mkdir -p final-nix-config/mnt/config/traefik/certs/ -**Data Disks ($CONTENT_DISK_NUMBER):** -$( j=1 && for i in $(seq 0 $(($CONTENT_DISK_NUMBER - 1))); do echo "* **Data ${j}:** \`${DATA_DISKS_ID[${i}]}\`" && j=$((j + 1)); done ) -$( [[ $CONTENT_DISK_NUMBER -eq 0 ]] && echo "* *Not configured*" ) + mkdir -p final-nix-config/etc/ + mkdir -p final-nix-config/etc/nixos/ + mkdir -p final-nix-config/etc/secrets/ + mkdir -p final-nix-config/etc/secrets/disks/ + mkdir -p final-nix-config/etc/numbus-server/ + mkdir -p final-nix-config/etc/nixos/misc/ + mkdir -p final-nix-config/etc/nixos/disks/ + mkdir -p final-nix-config/etc/nixos/pcie-coral/ + mkdir -p final-nix-config/etc/nixos/podman/ + mkdir -p final-nix-config/etc/nixos/secrets/ -**Parity Disks ($PARITY_DISK_NUMBER):** -$( [[ $PARITY_DISK_NUMBER -gt 0 ]] && j=1 && for i in $(seq $CONTENT_DISK_NUMBER $((${#DATA_DISKS_ID[@]} - 1))); do echo "* **Parity ${j}:** \`${DATA_DISKS_ID[${i}]}\`" && j=$((j + 1)); done ) -$( [[ $PARITY_DISK_NUMBER -eq 0 ]] && echo "* *Not configured*" ) -EOF -) + mkdir -p final-nix-config/var/ + mkdir -p final-nix-config/var/lib/ + mkdir -p final-nix-config/var/lib/sops-nix +} - gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "$(gum format <<< "$RECAP_CONTENT")" - gum confirm "Proceed with this disk configuration?" || { echo -e "\n\n❌ Aborting as requested."; exit 1; } -### Selection recap <-- +services_generation() { + generate_db_creds() { + local SERVICE_UPPER="${1}" + export "${SERVICE_UPPER}_DB_NAME"="$(xkcdpass -d "-" -n 2)" + export "${SERVICE_UPPER}_DB_USERNAME"="$(xkcdpass -d "-" -n 2)" + export "${SERVICE_UPPER}_DB_PASSWORD"="$(xkcdpass -d "-")" + } -### --> Config generation + echo -e "\n✅ Writing configuration files for the selected homelab services..." + cp templates/nix-config/podman/traefik.nix final-nix-config/etc/nixos/podman/traefik.nix + envsubst < templates/podman-config/traefik/traefik.yaml > final-nix-config/mnt/config/traefik/traefik.yaml + + local j=0 + for service in "${SELECTED_SERVICES[@]}"; do + if [[ "${service}" != "virtualization" ]]; then + j=$((j + 1)) + cp templates/nix-config/podman/${service}.nix final-nix-config/etc/nixos/podman/${service}.nix + PODMAN_NETWORKS+=" \${pkgs.podman}/bin/podman network create --driver=bridge --subnet=172.16.${j}.0/24 --ip-range=172.16.${j}.0/24 --gateway=172.16.${j}.254 ${service}_backend" + PODMAN_NETWORKS+=" \${pkgs.podman}/bin/podman network create --driver=bridge --subnet=172.16.${j}0.0/24 --ip-range=172.16.${j}0.0/24 --gateway=172.16.${j}0.254 ${service}_frontend" + TRAEFIK_NETWORKS+=" ${service}_frontend:" + TRAEFIK_NETWORKS+=" ipv4_address: 172.16.${j}0.253" + TRAEFIK_NETWORKS_REF+=" ${service}_frontend:" + TRAEFIK_NETWORKS_REF+=" external: true" + fi + if [[ "${service}" == "frigate" ]]; then + local FRIGATE_DEVICES_BLOCK="" + [[ "${TARGET_GRAPHICS_RENDERER}" == "true" ]] && FRIGATE_DEVICES_BLOCK+=" - /dev/dri:/dev/dri\n" + [[ "${TARGET_USB_CORAL}" == "true" ]] && FRIGATE_DEVICES_BLOCK+=" - /dev/bus/usb:/dev/bus/usb\n" + if [[ "${TARGET_PCIE_CORAL}" == "true" ]]; then + FRIGATE_DEVICES_BLOCK+=" - /dev/apex_0:/dev/apex_0\n" + sed -i "s|# ./pcie-coral/coral.nix| ./pcie-coral/coral.nix|" final-nix-config/etc/nixos/configuration.nix + cp -avu templates/nix-config/pcie-coral/* final-nix-config/etc/nixos/pcie-coral/ + fi + if [[ -n "${FRIGATE_DEVICES_BLOCK}" ]]; then + local REPLACEMENT="devices:\n${FRIGATE_DEVICES_BLOCK%\\n}" + sed -i "s|# --- frigate devices --- #|$REPLACEMENT|" final-nix-config/etc/nixos/podman/frigate.nix + fi + elif [[ "${service}" == "gitea" ]]; then + generate_db_creds "GITEA" + elif [[ "${service}" == "home-assistant" ]]; then + if [[ -n "${TARGET_ZIGBEE_DEVICE}" ]]; then + local REPLACEMENT="devices:\n - /dev/serial/by-id/${TARGET_ZIGBEE_DEVICE}:/dev/ttyUSB0" + sed -i "s|# --- hass devices --- #|$REPLACEMENT|" final-nix-config/etc/nixos/podman/home-assistant.nix + fi + export HOME_ASSISTANT_MQTT_USER="$(xkcdpass -d "-" -n 2)" + export HOME_ASSISTANT_MQTT_PASSWORD="$(xkcdpass -d "-")" + mkdir -p final-nix-config/mnt/config/mqtt/ + envsubst < templates/podman-config/hass/mosquitto.conf > final-nix-config/mnt/config/mqtt/mosquitto.conf + touch final-nix-config/mnt/config/mqtt/password.txt + chmod 0700 final-nix-config/mnt/config/mqtt/password.txt + mosquitto_passwd -b final-nix-config/mnt/config/mqtt/password.txt "$HOME_ASSISTANT_MQTT_USER" "$HOME_ASSISTANT_MQTT_PASSWORD" + elif [[ "${service}" == "immich" ]]; then + local IMMICH_DEVICES_BLOCK="" + if [[ "$TARGET_GRAPHICS_RENDERER" == "true" ]]; then + IMMICH_DEVICES_BLOCK+=" - /dev/dri:/dev/dri\n" + fi + if [[ -n "$IMMICH_DEVICES_BLOCK" ]]; then + local REPLACEMENT="devices:\n${IMMICH_DEVICES_BLOCK%\\n}" + sed -i "s|# --- immich devices --- #|$REPLACEMENT|" final-nix-config/etc/nixos/podman/immich.nix + fi + generate_db_creds "IMMICH" +# elif [[ "${service}" == "it-tools" ]]; then + elif [[ "${service}" == "nextcloud" ]]; then + envsubst < templates/podman-config/traefik/nextcloud.yaml > final-nix-config/mnt/config/traefik/rules/nextcloud.yaml + elif [[ "${service}" == "passbolt" ]]; then + generate_db_creds "PASSBOLT" + envsubst < templates/podman-config/traefik/headers.yaml > final-nix-config/mnt/config/traefik/rules/headers.yaml + envsubst < templates/podman-config/traefik/tls.yaml > final-nix-config/mnt/config/traefik/rules/tls.yaml + elif [[ "${service}" == "pi-hole" ]]; then + export FTLCONF_WEBSERVER_PASSWORD="$(xkcdpass -d "-")" + elif [[ "${service}" == "virtualization" ]]; then + sed -i "s|# virtualisation.libvirtd.enable = true;| virtualisation.libvirtd.enable = true;|" final-nix-config/etc/nixos/configuration.nix + sed -i "s|# programs.virt-manager.enable = true;| programs.virt-manager.enable = true;|" final-nix-config/etc/nixos/configuration.nix + sed -i 's|extraGroups = \[ "wheel" \];|extraGroups = [ "wheel" "libvirtd" ];|' final-nix-config/etc/nixos/configuration.nix + fi + done + + export PODMAN_NETWORKS + export TRAEFIK_NETWORKS + export TRAEFIK_NETWORKS_REF +} + +disks_generation() { + # Boot disk(s) echo -e "\n\n✅ Generating disko configuration from templates..." local TEMPLATE_FILE="templates/nix-config/disks/boot-${#BOOT_DISKS_ID[@]}.nix" (envsubst < "$TEMPLATE_FILE") > final-nix-config/etc/nixos/disks/disko.nix + # Striped configuration if [[ "$CONTENT_DISK_NUMBER" -eq 1 && "$PARITY_DISK_NUMBER" -eq 0 ]]; then - export j="1" + export j=1 export CONTENT_DISK_ID="${DATA_DISKS_ID[0]}" if [[ "${DATA_DISKS_TYPE[0]}" == "HDD" ]]; then export ALLOW_DISCARDS="false"; else export ALLOW_DISCARDS="true"; fi (envsubst < "templates/nix-config/disks/content.nix") >> final-nix-config/etc/nixos/disks/disko.nix - sed -i "s|/mnt/content-1|/mnt/data-storage|" final-nix-config/etc/nixos/disks/disko.nix + sed -i "s|/mnt/content-1|/mnt/data|" final-nix-config/etc/nixos/disks/disko.nix + # Mirror configuration elif [[ "$CONTENT_DISK_NUMBER" -eq 1 && "$PARITY_DISK_NUMBER" -eq 1 ]]; then export CONTENT_DISK_ID="${DATA_DISKS_ID[0]}" export PARITY_DISK_ID="${DATA_DISKS_ID[1]}" (envsubst < "templates/nix-config/disks/mirror.nix") >> final-nix-config/etc/nixos/disks/disko.nix + # SnapRAID configuration elif [[ "$CONTENT_DISK_NUMBER" -gt 1 ]]; then - # Enable SnapRAID cp -avu templates/nix-config/disks/pcr-check.nix final-nix-config/etc/nixos/disks/ sed -i "s|# ./disks/snapraid.nix| ./disks/snapraid.nix|" final-nix-config/etc/nixos/configuration.nix j=0 @@ -528,11 +470,11 @@ EOF (envsubst < "templates/nix-config/disks/content.nix") >> final-nix-config/etc/nixos/disks/disko.nix SNAPRAID_CONTENT_FILES+=" \"/mnt/content-${j}/snapraid.content\""$'\n' SNAPRAID_DATA_DISKS+=" d${j} = \"/mnt/content-${j}\";"$'\n' - MOUNT_DEPENDENCIES_START+=" cryptsetup open ${CONTENT_DISK_ID}-part1 crypted-content-${j} --key-file /etc/secrets/disks/content-${j}"$'\n' - MOUNT_DEPENDENCIES_START+=" mkdir -p /mnt/content-${j}"$'\n' - MOUNT_DEPENDENCIES_START+=" mount /mnt/content-${j}"$'\n' - MOUNT_DEPENDENCIES_STOP+=" umount /mnt/content-${j}"$'\n' - MOUNT_DEPENDENCIES_STOP+=" cryptsetup close crypted-content-${j}"$'\n' + MOUNT_DEPENDENCIES_START+=" \${pkgs.cryptsetup}/bin/cryptsetup open ${CONTENT_DISK_ID}-part1 crypted-content-${j} --key-file /etc/secrets/disks/content-${j}"$'\n' + MOUNT_DEPENDENCIES_START+=" \${pkgs.coreutils}/bin/mkdir -p /mnt/content-${j}"$'\n' + MOUNT_DEPENDENCIES_START+=" \${pkgs.util-linux}/bin/mount /mnt/content-${j}"$'\n' + MOUNT_DEPENDENCIES_STOP+=" \${pkgs.util-linux}/bin/umount /mnt/content-${j}"$'\n' + MOUNT_DEPENDENCIES_STOP+=" \${pkgs.cryptsetup}/bin/cryptsetup close crypted-content-${j}"$'\n' done echo -e "\n✅ Generated $CONTENT_DISK_NUMBER data disk configuration(s)." j=0 @@ -542,11 +484,11 @@ EOF if [[ "${DATA_DISKS_TYPE[${i}]}" == "HDD" ]]; then export ALLOW_DISCARDS="false"; else export ALLOW_DISCARDS="true"; fi (envsubst < "templates/nix-config/disks/parity.nix") >> final-nix-config/etc/nixos/disks/disko.nix SNAPRAID_PARITY_FILES+=" \"/mnt/parity-${j}/snapraid.parity\""$'\n' - MOUNT_DEPENDENCIES_START+=" cryptsetup open ${PARITY_DISK_ID} crypted-parity-${j} --key-file /etc/secrets/disks/parity-${j}"$'\n' - MOUNT_DEPENDENCIES_START+=" mkdir -p /mnt/parity-${j}"$'\n' - MOUNT_DEPENDENCIES_START+=" mount /mnt/parity-${j}"$'\n' - MOUNT_DEPENDENCIES_STOP+=" umount /mnt/parity-${j}"$'\n' - MOUNT_DEPENDENCIES_STOP+=" cryptsetup close crypted-parity-${j}"$'\n' + MOUNT_DEPENDENCIES_START+=" \${pkgs.cryptsetup}/bin/cryptsetup open ${PARITY_DISK_ID}-part1 crypted-parity-${j} --key-file /etc/secrets/disks/parity-${j}"$'\n' + MOUNT_DEPENDENCIES_START+=" \${pkgs.coreutils}/bin/mkdir -p /mnt/parity-${j}"$'\n' + MOUNT_DEPENDENCIES_START+=" \${pkgs.util-linux}/bin/mount /mnt/parity-${j}"$'\n' + MOUNT_DEPENDENCIES_STOP+=" \${pkgs.util-linux}/bin/umount /mnt/parity-${j}"$'\n' + MOUNT_DEPENDENCIES_STOP+=" \${pkgs.cryptsetup}/bin/cryptsetup close crypted-parity-${j}"$'\n' done echo -e "\n✅ Generated $PARITY_DISK_NUMBER parity disk configuration(s)." export SNAPRAID_CONTENT_FILES @@ -556,6 +498,7 @@ EOF export MOUNT_DEPENDENCIES_STOP envsubst < templates/nix-config/disks/snapraid.nix > final-nix-config/etc/nixos/disks/snapraid.nix fi + # Close the disko.nix block cat <<'EOF' >> final-nix-config/etc/nixos/disks/disko.nix }; @@ -568,13 +511,13 @@ EOF if [[ -n "${DATA_DISKS_ID[@]}" ]]; then for i in ${!DATA_DISKS_ID[@]}; do if [[ "${DATA_DISKS_TYPE[${i}]}" == "HDD" ]]; then - DISK_ID_LIST+=("${DATA_DISKS_ID[${i}]}") + SPINDOWN_DISKS_ID+=("${DATA_DISKS_ID[${i}]}") fi done - if [[ -n "${DISK_ID_LIST[@]}" ]]; then + if [[ -n "${SPINDOWN_DISKS_ID[@]}" ]]; then cp -avu templates/nix-config/disks/spindown.nix final-nix-config/etc/nixos/disks/ local FORMATTED_DISKS="" - for disk in "${DISK_ID_LIST[@]}"; do + for disk in "${SPINDOWN_DISKS_ID[@]}"; do FORMATTED_DISKS+=" \"$disk\"\n" done sed -i "s|DISK_LIST|${FORMATTED_DISKS}|" final-nix-config/etc/nixos/disks/spindown.nix @@ -582,8 +525,10 @@ EOF fi fi ### Config generation <-- +} -### --> Generate unlock keys +keys_generation() { +### --> Generate disk keys for i in $(seq 1 "${#BOOT_DISKS_ID[@]}"); do PASS="$(xkcdpass)" echo -n "$PASS" > "final-nix-config/etc/secrets/disks/boot-${i}" @@ -609,30 +554,69 @@ EOF echo "$REMOTE_PASS" | sudo -S bash -c "printf '%s' '$PASS' > /etc/secrets/disks/parity-${i}" EOF done +### Generate disk keys <-- -### Generate unlock keys <-- + echo -e "\n✅ Generating sops-nix keys..." + ssh-to-age -private-key -i final-nix-config/home/numbus-admin/.ssh/id_ed25519 > final-nix-config/var/lib/sops-nix/key.txt + export SOPS_PUBLIC_KEY=$(age-keygen -y final-nix-config/var/lib/sops-nix/key.txt) + + echo -e "\n✅ Generating sops-nix configuration files..." + envsubst < templates/nix-config/sops-nix/.sops.yaml > final-nix-config/etc/nixos/.sops.yaml + + echo -e "\n✅ Encrypting secrets in the correct file..." + envsubst < "templates/nix-config/sops-nix/secrets.yaml" \ + | sops encrypt --filename-override secrets.yaml \ + --input-type yaml --output-type yaml \ + --age $SOPS_PUBLIC_KEY \ + --output final-nix-config/etc/nixos/secrets/secrets.yaml } -export_configuration() { - cp deploy.conf final-nix-config/etc/numbus-server/numbus-server.conf +nixos_generation() { + echo -e "\n✅ Copying the configuration to the new machine..." + cp -avu templates/nix-config/configuration.nix final-nix-config/etc/nixos/ + cp -avu templates/nix-config/flake.nix final-nix-config/etc/nixos/ + cp -avu templates/nix-config/misc/* final-nix-config/etc/nixos/misc/ - local CONFIG_EXPORT_DIR="final-nix-config/etc/numbus-server/" - local CONFIG_EXPORT_FILE="${CONFIG_EXPORT_DIR}/numbus-server.conf" - - cp -ravu templates/post-install/numbus-server.sh "$CONFIG_EXPORT_DIR" - - echo "# SERVICE SETTINGS" >> $CONFIG_EXPORT_FILE - echo "SELECTED_SERVICES=(${SELECTED_SERVICES[@]})" >> $CONFIG_EXPORT_FILE - echo "# DISK SETTINGS" >> $CONFIG_EXPORT_FILE - echo "BOOT_DISK_ID_LIST=(${BOOT_DISKS_ID[@]})" >> $CONFIG_EXPORT_FILE - echo "DATA_DISKS_ID_LIST=(${DATA_DISKS_ID[@]})" >> $CONFIG_EXPORT_FILE - echo "SPINDOWN_DISKS_ID_LIST=(${DISK_ID_LIST[@]})" >> $CONFIG_EXPORT_FILE - echo "CONTENT_DISK_NUMBER=$CONTENT_DISK_NUMBER" >> $CONFIG_EXPORT_FILE - echo "PARITY_DISK_NUMBER=$PARITY_DISK_NUMBER" >> $CONFIG_EXPORT_FILE + echo -e "\n✅ Writing correct ips to configuration.nix..." + sed -i "s|HOME_SERVER_IP|${HOME_SERVER_IP}|g" final-nix-config/etc/nixos/misc/networking.nix + sed -i "s|HOME_ROUTER_IP|${HOME_ROUTER_IP}|g" final-nix-config/etc/nixos/misc/networking.nix + sed -i "s|TARGET_INTERFACE|${TARGET_INTERFACE}|g" final-nix-config/etc/nixos/misc/networking.nix + sed -i "s|DOMAIN_NAME|${DOMAIN_NAME}|g" final-nix-config/etc/nixos/misc/mail.nix + sed -i "s|EMAIL_ADDRESS|${EMAIL_ADDRESS}|g" final-nix-config/etc/nixos/misc/mail.nix + sed -i "s|TARGET_INTERFACE|${SENDER_EMAIL_DOMAIN}|g" final-nix-config/etc/nixos/misc/mail.nix + sed -i "s|TARGET_INTERFACE|${SENDER_EMAIL_ADDRESS}|g" final-nix-config/etc/nixos/misc/mail.nix + sed -i "s|PODMAN_NETWORKS|${PODMAN_NETWORKS}|" final-nix-config/etc/nixos/misc/activation.nix + sed -i "s|TRAEFIK_NETWORKS|${TRAEFIK_NETWORKS}|" final-nix-config/etc/nixos/podman/traefik.nix + sed -i "s|TRAEFIK_NETWORKS_REF|${TRAEFIK_NETWORKS_REF}|" final-nix-config/etc/nixos/podman/traefik.nix } sum_up() { - RECAP_CONTENT=$(cat << EOF +### --> Disk selection recap + DISK_RECAP_CONTENT=$(cat << EOF +### Disk Configuration Summary + +Please review the selected disk layout before proceeding. + +**Boot Disks (${#BOOT_DISKS_ID[@]}):** +* **Boot 1:** \`${BOOT_DISKS_ID[0]}\` +$( [[ -n "${BOOT_DISKS_ID[1]:-}" ]] && echo "* **Boot 2:** \`${BOOT_DISKS_ID[1]}\`" || echo "* **Boot 2:** *Not configured*" ) + +**Data Disks ($CONTENT_DISK_NUMBER):** +$( j=1 && for i in $(seq 0 $(($CONTENT_DISK_NUMBER - 1))); do echo "* **Data ${j}:** \`${DATA_DISKS_ID[${i}]}\`" && j=$((j + 1)); done ) +$( [[ $CONTENT_DISK_NUMBER -eq 0 ]] && echo "* *Not configured*" ) + +**Parity Disks ($PARITY_DISK_NUMBER):** +$( [[ $PARITY_DISK_NUMBER -gt 0 ]] && j=1 && for i in $(seq $CONTENT_DISK_NUMBER $((${#DATA_DISKS_ID[@]} - 1))); do echo "* **Parity ${j}:** \`${DATA_DISKS_ID[${i}]}\`" && j=$((j + 1)); done ) +$( [[ $PARITY_DISK_NUMBER -eq 0 ]] && echo "* *Not configured*" ) +EOF +) + + gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "$(gum format <<< "$RECAP_CONTENT")" + gum confirm "Proceed with this disk configuration?" || { echo -e "\n\n❌ Aborting as requested."; exit 1; } +### Disk selection recap <-- + +### Keys recap <-- + KEYS_RECAP_CONTENT=$(cat << EOF ### Generated Secrets Summary Please save these secrets in a secure location (e.g., a password manager). @@ -661,11 +645,28 @@ EOF ) gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "$(gum format <<< "$RECAP_CONTENT")" - gum confirm "Do you want to deploy NixOS on the target host?" || { echo -e "\n\n❌ Aborting as requested"; exit 1; } +### Keys recap <-- } +export_configuration() { + cp deploy.conf final-nix-config/etc/numbus-server/numbus-server.conf + local CONFIG_EXPORT_DIR="final-nix-config/etc/numbus-server/" + local CONFIG_EXPORT_FILE="${CONFIG_EXPORT_DIR}/numbus-server.conf" + + cp -avu templates/post-install/numbus-server.sh "$CONFIG_EXPORT_DIR" + + echo "# SERVICE SETTINGS" >> $CONFIG_EXPORT_FILE + echo "SELECTED_SERVICES=(${SELECTED_SERVICES[@]})" >> $CONFIG_EXPORT_FILE + echo "# DISK SETTINGS" >> $CONFIG_EXPORT_FILE + echo "BOOT_DISKS_ID=(${BOOT_DISKS_ID[@]})" >> $CONFIG_EXPORT_FILE + echo "DATA_DISKS_ID=(${DATA_DISKS_ID[@]})" >> $CONFIG_EXPORT_FILE + echo "DATA_DISKS_TYPE=(${DATA_DISKS_TYPE[@]})" >> $CONFIG_EXPORT_FILE + echo "SPINDOWN_DISKS_ID=(${SPINDOWN_DISKS_ID[@]})" >> $CONFIG_EXPORT_FILE + echo "CONTENT_DISK_NUMBER=$CONTENT_DISK_NUMBER" >> $CONFIG_EXPORT_FILE + echo "PARITY_DISK_NUMBER=$PARITY_DISK_NUMBER" >> $CONFIG_EXPORT_FILE +} deploy() { git -C "/home/nixosd/numbus-server" add -f "final-nix-config" @@ -681,9 +682,10 @@ deploy() { sleep 1 } - - postrun_action() { + TARGET_USER="numbus-admin" + REMOTE_PASS="changeMe!" + echo -e "\n\n Now the remote machine will reboot. You will need to input the boot disk(s) passphrase. This will be the only time you will have to do so, it will be automatic in the future." @@ -691,20 +693,18 @@ postrun_action() { gum confirm "➡️ Select 'yes' once the machine rebooted and you unlocked the disks." || { echo -e "\n\n❌ Aborting as requested."; exit 1; } - gum spin --title "\n\n🔄 Waiting for the server to boot up..." --auto << EOF -while FOUND="false"; do - if ping -c1 -W1 $HOME_SERVER_IP >/dev/null 2>&1; then - FOUND="true" - exit 0 - (i++) - if [[ "\${i}" -gt 150 ]]; then - echo -e "\n\n❌ Could not connect to the server after 150 retries. \ -This is most likely due to a networking issue. Please double check your network settings. Aborting." - exit 1 + while FOUND="false"; do + if ping -c1 -W1 $HOME_SERVER_IP >/dev/null 2>&1; then + FOUND="true" + exit 0 + (i++) + if [[ "\${i}" -gt 150 ]]; then + echo -e "\n\n❌ Could not connect to the server after 150 retries. \ + This is most likely due to a networking issue. Please double check your network settings. Aborting." + exit 1 + fi fi - fi -done -EOF + done ssh_to_host 'bash -s' << EOF sed -i "s|# ./disks/pcr-check.nix| ./disks/pcr-check.nix|" /etc/nixos/configuration.nix @@ -734,7 +734,12 @@ securely on a hidden sheet of paper or add it to your password manager (local wi echo $REMOTE_PASS | sudo -S passwd numbus-admin } +nix_update() { + echo -e "\n\n🔄 Updating NixOS on the remote server..." + nixos-rebuild --target-host numbus-admin@${TARGET_HOST} \ + --use-remote-sudo switch --flake final-nix-config/etc/nixos#numbus-server +} congrats() { gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 " @@ -748,11 +753,6 @@ it simple and use defaults) and take care to note down all the passwords. Change Cheers !!" } -nixos_update() { - echo -e "\n\n🔄 Updating NixOS on the remote server..." - echo "coming soon !" -} - set -euo pipefail fastfetch --logo nixos --structure ' ' @@ -791,49 +791,57 @@ if [[ "$ACTION_ANSWER" == "[1] 🌐 Deploy NixOS on a remote machine" ]]; then gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "➡️ On the target host : start the computer and boot into the NixOS iso. Launch a console and set up a new user password" gum confirm "Do you understand and wish to proceed?" || { echo "❌ Aborting as requested"; exit 1; } - necessary_credentials - generate_folder_tree + necessary_information setup_ssh hardware_detection services_selection - for service in ${SELECTED_SERVICES[@]}; do - mkdir -p final-nix-config/mnt/config/"${service}" - mkdir -p final-nix-config/mnt/data/"${service}" - done - files_generation - disk_config_generation - export_configuration + disks_selection + folder_tree_generation + services_generation + disks_generation + keys_generation + nix_generation sum_up + export_configuration deploy - TARGET_USER="numbus-admin" - REMOTE_PASS="changeMe!" postrun_action congrats + elif [[ "$ACTION_ANSWER" == "[2] 💽 Deploy NixOS on a remote machine with a file configuration" ]]; then echo -e "\n➡️ Proceeding with deployment using a config file…" gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "➡️ On the target host : start the computer and boot into the NixOS iso. Launch a console and set up a new user password" gum confirm "Do you understand and wish to proceed?" || { echo "❌ Aborting as requested"; exit 1; } - necessary_credentials_with_config - generate_folder_tree + necessary_information_config setup_ssh hardware_detection - files_generation - disk_config_generation - export_configuration + services_selection + disks_selection + folder_tree_generation + services_generation + disks_generation + keys_generation + nix_generation sum_up + export_configuration deploy - TARGET_USER="numbus-admin" - REMOTE_PASS="changeMe!" postrun_action congrats + elif [[ "$ACTION_ANSWER" == "[3] 🛠️ Update a NixOS remote machine" ]]; then echo -e "\n➡️ Proceeding with update…" gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "➡️ On the target host : make sure the NixOS installation you want to update is up-and-running, accessible with SSH" gum confirm "Do you understand and wish to proceed?" || { echo "❌ Aborting as requested."; exit 1; } - nixos_update + necessary_information + setup_ssh + more_information_config + folder_tree_generation + nix_generation + nix_update + congrats + else - echo "Aborting - you did not type '1, 2 or 3'" + echo "Aborting - you did not type 1, 2 or 3" exit 1 fi \ No newline at end of file diff --git a/templates/nix-config/configuration.nix b/templates/nix-config/configuration.nix index 0ac8333..8d2a321 100644 --- a/templates/nix-config/configuration.nix +++ b/templates/nix-config/configuration.nix @@ -6,6 +6,7 @@ (modulesPath + "/profiles/qemu-guest.nix") inputs.sops-nix.nixosModules.sops ./disks/disko.nix + ./misc/activation.nix ./misc/mail.nix ./misc/networking.nix ./misc/smart.nix diff --git a/templates/nix-config/disks/snapraid.nix b/templates/nix-config/disks/snapraid.nix index 366ed1f..593a3f0 100644 --- a/templates/nix-config/disks/snapraid.nix +++ b/templates/nix-config/disks/snapraid.nix @@ -2,7 +2,7 @@ { ### --> MergerFS setup - fileSystems."/mnt/data-storage" = { + fileSystems."/mnt/data" = { device = "/mnt/content-*"; fsType = "fuse.mergerfs"; options = [ @@ -28,7 +28,6 @@ description = "This service will mount the encrypted disks for mergerFS"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.cryptsetup pkgs.mount ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; diff --git a/templates/nix-config/misc/activation.nix b/templates/nix-config/misc/activation.nix new file mode 100644 index 0000000..621bc68 --- /dev/null +++ b/templates/nix-config/misc/activation.nix @@ -0,0 +1,12 @@ +{ config, pkgs, ... }: + +{ + system.activationScripts.script.text = '' + #!/bin/bash + ${pkgs.coreutils}/bin/mkdir -p /mnt/config/ /mnt/data/ + ${pkgs.coreutils}/bin/chown -R numbus-admin:users /mnt/config/ + ${pkgs.coreutils}/bin/chown -R numbus-admin:users /mnt/data/ + +PODMAN_NETWORKS + ''; +} \ No newline at end of file diff --git a/templates/nix-config/podman/adguard.coming b/templates/nix-config/podman/adguard.coming new file mode 100644 index 0000000..e49c61e --- /dev/null +++ b/templates/nix-config/podman/adguard.coming @@ -0,0 +1,41 @@ +{ config, pkgs, ... }: + +let + container_name = "adguard"; + compose_file = "podman/adguard/compose.yaml"; + config_dir = "/mnt/config/adguard"; +in + +{ + config = { + environment.etc."${compose_file}".text = + /* + yaml + */ + '' + ''; + + systemd.services.${container_name} = { + description = "Podman container : ${container_name}"; + after = [ "network.target" "traefik.service" ]; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.podman-compose pkgs.podman ]; + + serviceConfig = { + User = "numbus-admin"; + Environment = [ "XDG_RUNTIME_DIR=/run/user/1000" ]; + Type = "exec"; + # Pull the latest image before running + ExecStartPre = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} pull"; + # Bring the service up + ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; + # Take it down gracefully + ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; + Restart = "on-failure"; + RestartSec = "10m"; + StartLimitBurst = "3"; + StartLimitIntervalSec = "30s"; + }; + }; + }; +} \ No newline at end of file diff --git a/templates/nix-config/podman/frigate.nix b/templates/nix-config/podman/frigate.nix index 53cb228..2aba347 100644 --- a/templates/nix-config/podman/frigate.nix +++ b/templates/nix-config/podman/frigate.nix @@ -57,7 +57,6 @@ in description = "Podman container : ${container_name}"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" "traefik.service" ]; - path = [ pkgs.podman-compose pkgs.podman ]; serviceConfig = { User = "numbus-admin"; @@ -69,8 +68,10 @@ in ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; - Restart = "on-failure"; + RestartSec = "10m"; + StartLimitBurst = "3"; + StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/gitea.nix b/templates/nix-config/podman/gitea.nix index 859a185..f8a7ad6 100644 --- a/templates/nix-config/podman/gitea.nix +++ b/templates/nix-config/podman/gitea.nix @@ -70,7 +70,6 @@ in description = "Podman container : ${container_name}"; after = [ "network.target" "traefik.service" ]; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.podman-compose pkgs.podman ]; serviceConfig = { User = "numbus-admin"; @@ -82,8 +81,10 @@ in ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; - Restart = "on-failure"; + RestartSec = "10m"; + StartLimitBurst = "3"; + StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/home-assistant.nix b/templates/nix-config/podman/home-assistant.nix index a74ef9f..ca396fc 100644 --- a/templates/nix-config/podman/home-assistant.nix +++ b/templates/nix-config/podman/home-assistant.nix @@ -56,7 +56,6 @@ in description = "Podman container : ${container_name}"; after = [ "network.target" "traefik.service" ]; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.podman-compose pkgs.podman ]; serviceConfig = { User = "numbus-admin"; @@ -68,8 +67,10 @@ in ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; - Restart = "on-failure"; + RestartSec = "10m"; + StartLimitBurst = "3"; + StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/immich.nix b/templates/nix-config/podman/immich.nix index 1f703b7..485b487 100644 --- a/templates/nix-config/podman/immich.nix +++ b/templates/nix-config/podman/immich.nix @@ -93,7 +93,6 @@ in description = "Podman container : ${container_name}"; after = [ "network.target" "traefik.service" ]; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.podman-compose pkgs.podman ]; serviceConfig = { User = "numbus-admin"; @@ -105,8 +104,10 @@ in ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; - Restart = "on-failure"; + RestartSec = "10m"; + StartLimitBurst = "3"; + StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/it-tools.nix b/templates/nix-config/podman/it-tools.nix index 18a6b92..495b7a7 100644 --- a/templates/nix-config/podman/it-tools.nix +++ b/templates/nix-config/podman/it-tools.nix @@ -36,7 +36,6 @@ in description = "Podman container : ${container_name}"; after = [ "network.target" "traefik.service" ]; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.podman-compose pkgs.podman ]; serviceConfig = { User = "numbus-admin"; @@ -48,8 +47,10 @@ in ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; - Restart = "on-failure"; + RestartSec = "10m"; + StartLimitBurst = "3"; + StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/nextcloud.nix b/templates/nix-config/podman/nextcloud.nix index cb11a8d..dfb055c 100644 --- a/templates/nix-config/podman/nextcloud.nix +++ b/templates/nix-config/podman/nextcloud.nix @@ -21,7 +21,7 @@ in nextcloud-aio: volumes: - nextcloud_aio_mastercontainer:/mnt/docker-aio-config - - /var/run/docker.sock:/var/run/docker.sock:ro + - /run/user/1000/podman/podman.sock:/var/run/docker.sock:ro environment: APACHE_PORT: 11000 NEXTCLOUD_TRUSTED_DOMAINS: nextcloud.$DOMAIN_NAME nextcloud-aio.$DOMAIN_NAME @@ -59,7 +59,6 @@ in description = "Podman container : ${container_name}"; after = [ "network.target" "traefik.service" ]; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.podman-compose pkgs.podman ]; serviceConfig = { User = "numbus-admin"; @@ -71,8 +70,10 @@ in ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; - Restart = "on-failure"; + RestartSec = "10m"; + StartLimitBurst = "3"; + StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/passbolt.nix b/templates/nix-config/podman/passbolt.nix index 4d96c66..6cfe89d 100644 --- a/templates/nix-config/podman/passbolt.nix +++ b/templates/nix-config/podman/passbolt.nix @@ -88,7 +88,6 @@ in description = "Podman container : ${container_name}"; after = [ "network.target" "traefik.service" ]; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.podman-compose pkgs.podman ]; serviceConfig = { User = "numbus-admin"; @@ -100,8 +99,10 @@ in ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; - Restart = "on-failure"; + RestartSec = "10m"; + StartLimitBurst = "3"; + StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/pi-hole.nix b/templates/nix-config/podman/pi-hole.nix index f0c0d67..a3b0c68 100644 --- a/templates/nix-config/podman/pi-hole.nix +++ b/templates/nix-config/podman/pi-hole.nix @@ -1,7 +1,7 @@ { config, pkgs, ... }: let - container_name = "pihole"; + container_name = "pi-hole"; compose_file = "podman/pihole/compose.yaml"; config_dir = "/mnt/config/pihole"; in @@ -64,7 +64,6 @@ in description = "Podman container : ${container_name}"; after = [ "network.target" "traefik.service" ]; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.podman-compose pkgs.podman ]; serviceConfig = { User = "numbus-admin"; @@ -76,8 +75,10 @@ in ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; - Restart = "on-failure"; + RestartSec = "10m"; + StartLimitBurst = "3"; + StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/traefik.nix b/templates/nix-config/podman/traefik.nix index 7acacc4..bd5fe8d 100644 --- a/templates/nix-config/podman/traefik.nix +++ b/templates/nix-config/podman/traefik.nix @@ -16,22 +16,9 @@ in services: traefik: image: docker.io/library/traefik:latest - container_name: pi-hole + container_name: traefik networks: - nextcloud-aio: - ipv4_address: 172.16.10.253 - passbolt_frontend: - ipv4_address: 172.16.20.253 - pihole: - ipv4_address: 172.16.30.253 - hass_frontend: - ipv4_address: 172.16.40.253 - immich_frontend: - ipv4_address: 172.16.50.253 - gitea_frontend: - ipv4_address: 172.16.60.253 - it-tools: - ipv4_address: 172.16.70.253 +TRAEFIK_NETWORKS ports: - 8080:80 - 8443:443 @@ -47,95 +34,18 @@ in - traefik.http.services.traefik.loadbalancer.server.port=8080 - traefik.http.services.traefik.loadbalancer.server.scheme=http - traefik.http.routers.traefik-https.entrypoints=websecure - - traefik.http.routers.traefik-https.rule=Host(`pi-hole.$DOMAIN_NAME`) + - traefik.http.routers.traefik-https.rule=Host(`traefik.$DOMAIN_NAME`) - traefik.http.routers.traefik-https.tls=true - traefik.http.routers.traefik-https.tls.certresolver=cloudflare restart: always networks: - nextcloud-aio: - name: nextcloud-aio - driver: bridge - ipam: - config: - - subnet: "172.16.10.0/24" - gateway: "172.16.10.254" - passbolt_backend: - name: passbolt_backend - driver: bridge - ipam: - config: - - subnet: "172.16.2.0/24" - gateway: "172.16.2.254" - passbolt_frontend: - name: passbolt_frontend - driver: bridge - ipam: - config: - - subnet: "172.16.20.0/24" - gateway: "172.16.20.254" - pihole: - name: pihole - driver: bridge - ipam: - config: - - subnet: "172.16.30.0/24" - gateway: "172.16.30.254" - hass_backend: - name: hass_backend - driver: bridge - ipam: - config: - - subnet: "172.16.4.0/24" - gateway: "172.16.4.254" - hass_frontend: - name: hass_frontend - driver: bridge - ipam: - config: - - subnet: "172.16.40.0/24" - gateway: "172.16.40.254" - immich_backend: - name: immich_backend - driver: bridge - ipam: - config: - - subnet: "172.16.5.0/24" - gateway: "172.16.5.254" - immich_frontend: - name: immich_frontend - driver: bridge - ipam: - config: - - subnet: "172.16.50.0/24" - gateway: "172.16.50.254" - gitea_backend: - name: gitea_backend - driver: bridge - ipam: - config: - - subnet: "172.16.6.0/24" - gateway: "172.16.6.254" - gitea_frontend: - name: gitea_frontend - driver: bridge - ipam: - config: - - subnet: "172.16.60.0/24" - gateway: "172.16.60.254" - it-tools: - name: it-tools - driver: bridge - ipam: - config: - - subnet: "172.16.70.0/24" - gateway: "172.16.70.254" +TRAEFIK_NETWORKS_REF ''; systemd.services.traefik = { description = "Podman container : ${container_name}"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.podman-compose pkgs.podman ]; serviceConfig = { User = "numbus-admin"; @@ -147,8 +57,10 @@ in ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; - Restart = "on-failure"; + RestartSec = "10m"; + StartLimitBurst = "3"; + StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/post-install/numbus-server.conf b/templates/post-install/numbus-server.conf index f057382..e61d766 100644 --- a/templates/post-install/numbus-server.conf +++ b/templates/post-install/numbus-server.conf @@ -17,8 +17,9 @@ NETWORK_HOME_SERVER_IP="192.168.1.5" # SERVICE SETTINGS SELECTED_SERVICES=("frigate" "home-assistant") # DISK SETTINGS -BOOT_DISK_ID_LIST=("/dev/disk/by-id/nvme001-dfzpjvp") -DATA_DISKS_ID_LIST=("/dev/disk/by-id/sata-barracuda-veojapoj") -SPINDOWN_DISKS_ID_LIST=("/dev/disk/by-id/sata-barracuda-veojapoj") +BOOT_DISKS_ID=("/dev/disk/by-id/nvme001-dfzpjvp") +DATA_DISKS_ID=("/dev/disk/by-id/sata-barracuda-veojapoj") +DATA_DISKS_TYPE=("HDD") +SPINDOWN_DISKS_ID=("/dev/disk/by-id/sata-barracuda-veojapoj") CONTENT_DISK_NUMBER=2 PARITY_DISK_NUMBER=2 \ No newline at end of file