Big update to logic and nix files. Need testing.

This commit is contained in:
Raphaël Numbus
2026-01-07 20:11:16 +01:00
parent c6eb5097e4
commit 1ddf4c01e1
15 changed files with 363 additions and 381 deletions
+271 -263
View File
@@ -1,8 +1,6 @@
#!/usr/bin/env nix-shell #!/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 #!nix-shell -i bash -p bash coreutils gnused gum fastfetch xkcdpass sops ssh-to-age age sshpass envsubst pciutils usbutils mosquitto
### --> Default settings ### --> Default settings
export GUM_SPIN_SPINNER="minidot" export GUM_SPIN_SPINNER="minidot"
export GUM_SPIN_SPINNER_BOLD=true 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") "HOME_SERVER_IP" "SELECTED_SERVICES")
### Default settings <-- ### Default settings <--
user_input() { user_input() {
local VAR_NAME="${1}" local VAR_NAME="${1}"
local HEADER="${2}" local HEADER="${2}"
@@ -46,9 +42,7 @@ user_input() {
done done
} }
necessary_information() {
necessary_credentials() {
# Regex Definitions # Regex Definitions
local IP_REGEX='^([0-9]{1,3}\.){3}[0-9]{1,3}$' 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}$' 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 PORT_REGEX='^[0-9]{1,5}$'
local SSH_KEY_REGEX='^ssh-[a-z0-9]+ [A-Za-z0-9+/]+.*' 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" 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 "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 "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" 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" 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 "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 "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" 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" 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" " 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_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_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." 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" 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_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_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." 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_information_config() {
necessary_credentials_with_config() {
echo -e "\n\n➡️ Please choose your configuration file :" echo -e "\n\n➡️ Please choose your configuration file :"
local CONFIG_PATH="$(gum file)" local CONFIG_PATH="$(gum file)"
@@ -106,41 +98,12 @@ necessary_credentials_with_config() {
fi fi
} }
setup_ssh() {
generate_folder_tree() {
mkdir -p final-nix-config/ mkdir -p final-nix-config/
mkdir -p final-nix-config/home/ mkdir -p final-nix-config/home/
mkdir -p final-nix-config/home/numbus-admin/ mkdir -p final-nix-config/home/numbus-admin/
mkdir -p final-nix-config/home/numbus-admin/.ssh/ 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..." echo -e "\n\n✅ Generating new SSH key for numbus-admin..."
chmod 700 final-nix-config/home/numbus-admin/.ssh/ 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 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 fi
} }
ssh_to_host() { ssh_to_host() {
local COMMAND="${1}" local COMMAND="${1}"
ssh -i "final-nix-config/home/numbus-admin/.ssh/id_ed25519" "${TARGET_USER}@${TARGET_HOST}" "${COMMAND}" 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() { hardware_detection() {
### --> Get hardware information ### --> 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 ssh_to_host 'bash -s' << SSHEND
for brand in Intel AMD NVIDIA; do for brand in Intel AMD NVIDIA; do
@@ -249,7 +210,7 @@ SSHEND
### Get hardware information <-- ### Get hardware information <--
scp -i "final-nix-config/home/numbus-admin/.ssh/id_ed25519" "${TARGET_USER}@${TARGET_HOST}":"${TMPFILE}" "${TMPFILE}" &> /dev/null 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 ### --> 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 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:" 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" \ 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" \ local SERVICES_DESCRIPTION=( "Pi-Hole : Block ads on all your devices" \
"Immich : Pictures and videos backup with local machine-learning" \ "Immich : Pictures and videos backup with local machine-learning" \
@@ -287,114 +248,7 @@ services_selection() {
done done
} }
files_generation() { disks_selection() {
# 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() {
### --> Disk wiping warning ### --> Disk wiping warning
gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 " 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. ⚠️ $(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)" echo -e "\n\n🔎 Fetching and analyzing disks from target host... (This may take a moment)"
### Disk wiping warning <-- ### Disk wiping warning <--
### --> Disk selection ### --> Disk selection
if [[ "${#DISK_NAME[@]}" -eq 0 ]]; then if [[ "${#DISK_NAME[@]}" -eq 0 ]]; then
echo -e "\n❌ No disks found on the target host. Aborting." 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[@]}") 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 for i in ${!DISK_NAME[@]}; do
if printf '%s' "$SELECTED_BOOT_DISK" | grep -iqw "${DISK_NAME[${i}]}"; then if printf '%s' "$SELECTED_BOOT_DISK" | grep -iqw "${DISK_NAME[${i}]}"; then
BOOT_DISKS_ID+=("${DISK_ID[${i}]:-${DISK_DEVPATH[${i}]}}") BOOT_DISKS_ID+=("${DISK_ID[${i}]:-${DISK_DEVPATH[${i}]}}")
@@ -454,11 +312,6 @@ disk_config_generation() {
exit 1 exit 1
fi 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 for i in ${!DISK_NAME[@]}; do
if printf '%s' "$SELECTED_DATA_DISK" | grep -iq "${DISK_NAME[${i}]}"; then if printf '%s' "$SELECTED_DATA_DISK" | grep -iq "${DISK_NAME[${i}]}"; then
DATA_DISKS_ID+=("${DISK_ID[${i}]:-${DISK_DEVPATH[${i}]}}") DATA_DISKS_ID+=("${DISK_ID[${i}]:-${DISK_DEVPATH[${i}]}}")
@@ -467,57 +320,146 @@ disk_config_generation() {
done done
if [[ "${#DATA_DISKS_ID[@]}" -eq 1 ]]; then if [[ "${#DATA_DISKS_ID[@]}" -eq 1 ]]; then
PARITY_DISK_NUMBER=0 export PARITY_DISK_NUMBER=0
CONTENT_DISK_NUMBER=1 export CONTENT_DISK_NUMBER=1
else else
PARITY_DISK_NUMBER=$(((${#DATA_DISKS_ID[@]} + 2) / 3)) export PARITY_DISK_NUMBER=$(((${#DATA_DISKS_ID[@]} + 2) / 3))
CONTENT_DISK_NUMBER=$((${#DATA_DISKS_ID[@]} - PARITY_DISK_NUMBER)) export CONTENT_DISK_NUMBER=$((${#DATA_DISKS_ID[@]} - PARITY_DISK_NUMBER))
fi fi
### Disk selection <--
### --> Selection recap export DATA_DISKS_ID
RECAP_CONTENT=$(cat << EOF export DATA_DISKS_TYPE
### Disk Configuration Summary }
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[@]}):** mkdir -p final-nix-config/mnt/config/traefik/
* **Boot 1:** \`${BOOT_DISKS_ID[0]}\` mkdir -p final-nix-config/mnt/config/traefik/rules/
$( [[ -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/certs/
**Data Disks ($CONTENT_DISK_NUMBER):** mkdir -p final-nix-config/etc/
$( j=1 && for i in $(seq 0 $(($CONTENT_DISK_NUMBER - 1))); do echo "* **Data ${j}:** \`${DATA_DISKS_ID[${i}]}\`" && j=$((j + 1)); done ) mkdir -p final-nix-config/etc/nixos/
$( [[ $CONTENT_DISK_NUMBER -eq 0 ]] && echo "* *Not configured*" ) 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):** mkdir -p final-nix-config/var/
$( [[ $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 ) mkdir -p final-nix-config/var/lib/
$( [[ $PARITY_DISK_NUMBER -eq 0 ]] && echo "* *Not configured*" ) mkdir -p final-nix-config/var/lib/sops-nix
EOF }
)
gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "$(gum format <<< "$RECAP_CONTENT")" services_generation() {
gum confirm "Proceed with this disk configuration?" || { echo -e "\n\n❌ Aborting as requested."; exit 1; } generate_db_creds() {
### Selection recap <-- 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..." echo -e "\n\n✅ Generating disko configuration from templates..."
local TEMPLATE_FILE="templates/nix-config/disks/boot-${#BOOT_DISKS_ID[@]}.nix" local TEMPLATE_FILE="templates/nix-config/disks/boot-${#BOOT_DISKS_ID[@]}.nix"
(envsubst < "$TEMPLATE_FILE") > final-nix-config/etc/nixos/disks/disko.nix (envsubst < "$TEMPLATE_FILE") > final-nix-config/etc/nixos/disks/disko.nix
# Striped configuration # Striped configuration
if [[ "$CONTENT_DISK_NUMBER" -eq 1 && "$PARITY_DISK_NUMBER" -eq 0 ]]; then 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]}" 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 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 (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 # Mirror configuration
elif [[ "$CONTENT_DISK_NUMBER" -eq 1 && "$PARITY_DISK_NUMBER" -eq 1 ]]; then elif [[ "$CONTENT_DISK_NUMBER" -eq 1 && "$PARITY_DISK_NUMBER" -eq 1 ]]; then
export CONTENT_DISK_ID="${DATA_DISKS_ID[0]}" export CONTENT_DISK_ID="${DATA_DISKS_ID[0]}"
export PARITY_DISK_ID="${DATA_DISKS_ID[1]}" export PARITY_DISK_ID="${DATA_DISKS_ID[1]}"
(envsubst < "templates/nix-config/disks/mirror.nix") >> final-nix-config/etc/nixos/disks/disko.nix (envsubst < "templates/nix-config/disks/mirror.nix") >> final-nix-config/etc/nixos/disks/disko.nix
# SnapRAID configuration # SnapRAID configuration
elif [[ "$CONTENT_DISK_NUMBER" -gt 1 ]]; then elif [[ "$CONTENT_DISK_NUMBER" -gt 1 ]]; then
# Enable SnapRAID
cp -avu templates/nix-config/disks/pcr-check.nix final-nix-config/etc/nixos/disks/ 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 sed -i "s|# ./disks/snapraid.nix| ./disks/snapraid.nix|" final-nix-config/etc/nixos/configuration.nix
j=0 j=0
@@ -528,11 +470,11 @@ EOF
(envsubst < "templates/nix-config/disks/content.nix") >> final-nix-config/etc/nixos/disks/disko.nix (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_CONTENT_FILES+=" \"/mnt/content-${j}/snapraid.content\""$'\n'
SNAPRAID_DATA_DISKS+=" d${j} = \"/mnt/content-${j}\";"$'\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+=" \${pkgs.cryptsetup}/bin/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+=" \${pkgs.coreutils}/bin/mkdir -p /mnt/content-${j}"$'\n'
MOUNT_DEPENDENCIES_START+=" mount /mnt/content-${j}"$'\n' MOUNT_DEPENDENCIES_START+=" \${pkgs.util-linux}/bin/mount /mnt/content-${j}"$'\n'
MOUNT_DEPENDENCIES_STOP+=" umount /mnt/content-${j}"$'\n' MOUNT_DEPENDENCIES_STOP+=" \${pkgs.util-linux}/bin/umount /mnt/content-${j}"$'\n'
MOUNT_DEPENDENCIES_STOP+=" cryptsetup close crypted-content-${j}"$'\n' MOUNT_DEPENDENCIES_STOP+=" \${pkgs.cryptsetup}/bin/cryptsetup close crypted-content-${j}"$'\n'
done done
echo -e "\n✅ Generated $CONTENT_DISK_NUMBER data disk configuration(s)." echo -e "\n✅ Generated $CONTENT_DISK_NUMBER data disk configuration(s)."
j=0 j=0
@@ -542,11 +484,11 @@ EOF
if [[ "${DATA_DISKS_TYPE[${i}]}" == "HDD" ]]; then export ALLOW_DISCARDS="false"; else export ALLOW_DISCARDS="true"; fi 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 (envsubst < "templates/nix-config/disks/parity.nix") >> final-nix-config/etc/nixos/disks/disko.nix
SNAPRAID_PARITY_FILES+=" \"/mnt/parity-${j}/snapraid.parity\""$'\n' 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+=" \${pkgs.cryptsetup}/bin/cryptsetup open ${PARITY_DISK_ID}-part1 crypted-parity-${j} --key-file /etc/secrets/disks/parity-${j}"$'\n'
MOUNT_DEPENDENCIES_START+=" mkdir -p /mnt/parity-${j}"$'\n' MOUNT_DEPENDENCIES_START+=" \${pkgs.coreutils}/bin/mkdir -p /mnt/parity-${j}"$'\n'
MOUNT_DEPENDENCIES_START+=" mount /mnt/parity-${j}"$'\n' MOUNT_DEPENDENCIES_START+=" \${pkgs.util-linux}/bin/mount /mnt/parity-${j}"$'\n'
MOUNT_DEPENDENCIES_STOP+=" umount /mnt/parity-${j}"$'\n' MOUNT_DEPENDENCIES_STOP+=" \${pkgs.util-linux}/bin/umount /mnt/parity-${j}"$'\n'
MOUNT_DEPENDENCIES_STOP+=" cryptsetup close crypted-parity-${j}"$'\n' MOUNT_DEPENDENCIES_STOP+=" \${pkgs.cryptsetup}/bin/cryptsetup close crypted-parity-${j}"$'\n'
done done
echo -e "\n✅ Generated $PARITY_DISK_NUMBER parity disk configuration(s)." echo -e "\n✅ Generated $PARITY_DISK_NUMBER parity disk configuration(s)."
export SNAPRAID_CONTENT_FILES export SNAPRAID_CONTENT_FILES
@@ -556,6 +498,7 @@ EOF
export MOUNT_DEPENDENCIES_STOP export MOUNT_DEPENDENCIES_STOP
envsubst < templates/nix-config/disks/snapraid.nix > final-nix-config/etc/nixos/disks/snapraid.nix envsubst < templates/nix-config/disks/snapraid.nix > final-nix-config/etc/nixos/disks/snapraid.nix
fi fi
# Close the disko.nix block # Close the disko.nix block
cat <<'EOF' >> final-nix-config/etc/nixos/disks/disko.nix cat <<'EOF' >> final-nix-config/etc/nixos/disks/disko.nix
}; };
@@ -568,13 +511,13 @@ EOF
if [[ -n "${DATA_DISKS_ID[@]}" ]]; then if [[ -n "${DATA_DISKS_ID[@]}" ]]; then
for i in ${!DATA_DISKS_ID[@]}; do for i in ${!DATA_DISKS_ID[@]}; do
if [[ "${DATA_DISKS_TYPE[${i}]}" == "HDD" ]]; then if [[ "${DATA_DISKS_TYPE[${i}]}" == "HDD" ]]; then
DISK_ID_LIST+=("${DATA_DISKS_ID[${i}]}") SPINDOWN_DISKS_ID+=("${DATA_DISKS_ID[${i}]}")
fi fi
done 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/ cp -avu templates/nix-config/disks/spindown.nix final-nix-config/etc/nixos/disks/
local FORMATTED_DISKS="" local FORMATTED_DISKS=""
for disk in "${DISK_ID_LIST[@]}"; do for disk in "${SPINDOWN_DISKS_ID[@]}"; do
FORMATTED_DISKS+=" \"$disk\"\n" FORMATTED_DISKS+=" \"$disk\"\n"
done done
sed -i "s|DISK_LIST|${FORMATTED_DISKS}|" final-nix-config/etc/nixos/disks/spindown.nix sed -i "s|DISK_LIST|${FORMATTED_DISKS}|" final-nix-config/etc/nixos/disks/spindown.nix
@@ -582,8 +525,10 @@ EOF
fi fi
fi fi
### Config generation <-- ### Config generation <--
}
### --> Generate unlock keys keys_generation() {
### --> Generate disk keys
for i in $(seq 1 "${#BOOT_DISKS_ID[@]}"); do for i in $(seq 1 "${#BOOT_DISKS_ID[@]}"); do
PASS="$(xkcdpass)" PASS="$(xkcdpass)"
echo -n "$PASS" > "final-nix-config/etc/secrets/disks/boot-${i}" 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}" echo "$REMOTE_PASS" | sudo -S bash -c "printf '%s' '$PASS' > /etc/secrets/disks/parity-${i}"
EOF EOF
done 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() { nixos_generation() {
cp deploy.conf final-nix-config/etc/numbus-server/numbus-server.conf 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/" echo -e "\n✅ Writing correct ips to configuration.nix..."
local CONFIG_EXPORT_FILE="${CONFIG_EXPORT_DIR}/numbus-server.conf" 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
cp -ravu templates/post-install/numbus-server.sh "$CONFIG_EXPORT_DIR" 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
echo "# SERVICE SETTINGS" >> $CONFIG_EXPORT_FILE sed -i "s|EMAIL_ADDRESS|${EMAIL_ADDRESS}|g" final-nix-config/etc/nixos/misc/mail.nix
echo "SELECTED_SERVICES=(${SELECTED_SERVICES[@]})" >> $CONFIG_EXPORT_FILE sed -i "s|TARGET_INTERFACE|${SENDER_EMAIL_DOMAIN}|g" final-nix-config/etc/nixos/misc/mail.nix
echo "# DISK SETTINGS" >> $CONFIG_EXPORT_FILE sed -i "s|TARGET_INTERFACE|${SENDER_EMAIL_ADDRESS}|g" final-nix-config/etc/nixos/misc/mail.nix
echo "BOOT_DISK_ID_LIST=(${BOOT_DISKS_ID[@]})" >> $CONFIG_EXPORT_FILE sed -i "s|PODMAN_NETWORKS|${PODMAN_NETWORKS}|" final-nix-config/etc/nixos/misc/activation.nix
echo "DATA_DISKS_ID_LIST=(${DATA_DISKS_ID[@]})" >> $CONFIG_EXPORT_FILE sed -i "s|TRAEFIK_NETWORKS|${TRAEFIK_NETWORKS}|" final-nix-config/etc/nixos/podman/traefik.nix
echo "SPINDOWN_DISKS_ID_LIST=(${DISK_ID_LIST[@]})" >> $CONFIG_EXPORT_FILE sed -i "s|TRAEFIK_NETWORKS_REF|${TRAEFIK_NETWORKS_REF}|" final-nix-config/etc/nixos/podman/traefik.nix
echo "CONTENT_DISK_NUMBER=$CONTENT_DISK_NUMBER" >> $CONFIG_EXPORT_FILE
echo "PARITY_DISK_NUMBER=$PARITY_DISK_NUMBER" >> $CONFIG_EXPORT_FILE
} }
sum_up() { 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 ### Generated Secrets Summary
Please save these secrets in a secure location (e.g., a password manager). 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 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; } 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() { deploy() {
git -C "/home/nixosd/numbus-server" add -f "final-nix-config" git -C "/home/nixosd/numbus-server" add -f "final-nix-config"
@@ -681,9 +682,10 @@ deploy() {
sleep 1 sleep 1
} }
postrun_action() { 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. 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." 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 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
while FOUND="false"; do if ping -c1 -W1 $HOME_SERVER_IP >/dev/null 2>&1; then
if ping -c1 -W1 $HOME_SERVER_IP >/dev/null 2>&1; then FOUND="true"
FOUND="true" exit 0
exit 0 (i++)
(i++) if [[ "\${i}" -gt 150 ]]; then
if [[ "\${i}" -gt 150 ]]; then echo -e "\n\n❌ Could not connect to the server after 150 retries. \
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."
This is most likely due to a networking issue. Please double check your network settings. Aborting." exit 1
exit 1 fi
fi fi
fi done
done
EOF
ssh_to_host 'bash -s' << EOF ssh_to_host 'bash -s' << EOF
sed -i "s|# ./disks/pcr-check.nix| ./disks/pcr-check.nix|" /etc/nixos/configuration.nix 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 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() { congrats() {
gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 " 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 !!" Cheers !!"
} }
nixos_update() {
echo -e "\n\n🔄 Updating NixOS on the remote server..."
echo "coming soon !"
}
set -euo pipefail set -euo pipefail
fastfetch --logo nixos --structure ' ' 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. 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" 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; } gum confirm "Do you understand and wish to proceed?" || { echo "❌ Aborting as requested"; exit 1; }
necessary_credentials necessary_information
generate_folder_tree
setup_ssh setup_ssh
hardware_detection hardware_detection
services_selection services_selection
for service in ${SELECTED_SERVICES[@]}; do disks_selection
mkdir -p final-nix-config/mnt/config/"${service}" folder_tree_generation
mkdir -p final-nix-config/mnt/data/"${service}" services_generation
done disks_generation
files_generation keys_generation
disk_config_generation nix_generation
export_configuration
sum_up sum_up
export_configuration
deploy deploy
TARGET_USER="numbus-admin"
REMOTE_PASS="changeMe!"
postrun_action postrun_action
congrats congrats
elif [[ "$ACTION_ANSWER" == "[2] 💽 Deploy NixOS on a remote machine with a file configuration" ]]; then 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…" 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. 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" 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; } gum confirm "Do you understand and wish to proceed?" || { echo "❌ Aborting as requested"; exit 1; }
necessary_credentials_with_config necessary_information_config
generate_folder_tree
setup_ssh setup_ssh
hardware_detection hardware_detection
files_generation services_selection
disk_config_generation disks_selection
export_configuration folder_tree_generation
services_generation
disks_generation
keys_generation
nix_generation
sum_up sum_up
export_configuration
deploy deploy
TARGET_USER="numbus-admin"
REMOTE_PASS="changeMe!"
postrun_action postrun_action
congrats congrats
elif [[ "$ACTION_ANSWER" == "[3] 🛠️ Update a NixOS remote machine" ]]; then elif [[ "$ACTION_ANSWER" == "[3] 🛠️ Update a NixOS remote machine" ]]; then
echo -e "\n➡️ Proceeding with update…" 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 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" to update is up-and-running, accessible with SSH"
gum confirm "Do you understand and wish to proceed?" || { echo "❌ Aborting as requested."; exit 1; } 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 else
echo "Aborting - you did not type '1, 2 or 3'" echo "Aborting - you did not type 1, 2 or 3"
exit 1 exit 1
fi fi
+1
View File
@@ -6,6 +6,7 @@
(modulesPath + "/profiles/qemu-guest.nix") (modulesPath + "/profiles/qemu-guest.nix")
inputs.sops-nix.nixosModules.sops inputs.sops-nix.nixosModules.sops
./disks/disko.nix ./disks/disko.nix
./misc/activation.nix
./misc/mail.nix ./misc/mail.nix
./misc/networking.nix ./misc/networking.nix
./misc/smart.nix ./misc/smart.nix
+1 -2
View File
@@ -2,7 +2,7 @@
{ {
### --> MergerFS setup ### --> MergerFS setup
fileSystems."/mnt/data-storage" = { fileSystems."/mnt/data" = {
device = "/mnt/content-*"; device = "/mnt/content-*";
fsType = "fuse.mergerfs"; fsType = "fuse.mergerfs";
options = [ options = [
@@ -28,7 +28,6 @@
description = "This service will mount the encrypted disks for mergerFS"; description = "This service will mount the encrypted disks for mergerFS";
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.cryptsetup pkgs.mount ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = true; RemainAfterExit = true;
+12
View File
@@ -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
'';
}
@@ -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";
};
};
};
}
+3 -2
View File
@@ -57,7 +57,6 @@ in
description = "Podman container : ${container_name}"; description = "Podman container : ${container_name}";
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" "traefik.service" ]; wantedBy = [ "multi-user.target" "traefik.service" ];
path = [ pkgs.podman-compose pkgs.podman ];
serviceConfig = { serviceConfig = {
User = "numbus-admin"; User = "numbus-admin";
@@ -69,8 +68,10 @@ in
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully # Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "10m";
StartLimitBurst = "3";
StartLimitIntervalSec = "30s";
}; };
}; };
}; };
+3 -2
View File
@@ -70,7 +70,6 @@ in
description = "Podman container : ${container_name}"; description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ]; after = [ "network.target" "traefik.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.podman-compose pkgs.podman ];
serviceConfig = { serviceConfig = {
User = "numbus-admin"; User = "numbus-admin";
@@ -82,8 +81,10 @@ in
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully # Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "10m";
StartLimitBurst = "3";
StartLimitIntervalSec = "30s";
}; };
}; };
}; };
@@ -56,7 +56,6 @@ in
description = "Podman container : ${container_name}"; description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ]; after = [ "network.target" "traefik.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.podman-compose pkgs.podman ];
serviceConfig = { serviceConfig = {
User = "numbus-admin"; User = "numbus-admin";
@@ -68,8 +67,10 @@ in
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully # Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "10m";
StartLimitBurst = "3";
StartLimitIntervalSec = "30s";
}; };
}; };
}; };
+3 -2
View File
@@ -93,7 +93,6 @@ in
description = "Podman container : ${container_name}"; description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ]; after = [ "network.target" "traefik.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.podman-compose pkgs.podman ];
serviceConfig = { serviceConfig = {
User = "numbus-admin"; User = "numbus-admin";
@@ -105,8 +104,10 @@ in
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully # Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "10m";
StartLimitBurst = "3";
StartLimitIntervalSec = "30s";
}; };
}; };
}; };
+3 -2
View File
@@ -36,7 +36,6 @@ in
description = "Podman container : ${container_name}"; description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ]; after = [ "network.target" "traefik.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.podman-compose pkgs.podman ];
serviceConfig = { serviceConfig = {
User = "numbus-admin"; User = "numbus-admin";
@@ -48,8 +47,10 @@ in
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully # Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "10m";
StartLimitBurst = "3";
StartLimitIntervalSec = "30s";
}; };
}; };
}; };
+4 -3
View File
@@ -21,7 +21,7 @@ in
nextcloud-aio: nextcloud-aio:
volumes: volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config - 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: environment:
APACHE_PORT: 11000 APACHE_PORT: 11000
NEXTCLOUD_TRUSTED_DOMAINS: nextcloud.$DOMAIN_NAME nextcloud-aio.$DOMAIN_NAME NEXTCLOUD_TRUSTED_DOMAINS: nextcloud.$DOMAIN_NAME nextcloud-aio.$DOMAIN_NAME
@@ -59,7 +59,6 @@ in
description = "Podman container : ${container_name}"; description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ]; after = [ "network.target" "traefik.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.podman-compose pkgs.podman ];
serviceConfig = { serviceConfig = {
User = "numbus-admin"; User = "numbus-admin";
@@ -71,8 +70,10 @@ in
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully # Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "10m";
StartLimitBurst = "3";
StartLimitIntervalSec = "30s";
}; };
}; };
}; };
+3 -2
View File
@@ -88,7 +88,6 @@ in
description = "Podman container : ${container_name}"; description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ]; after = [ "network.target" "traefik.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.podman-compose pkgs.podman ];
serviceConfig = { serviceConfig = {
User = "numbus-admin"; User = "numbus-admin";
@@ -100,8 +99,10 @@ in
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully # Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "10m";
StartLimitBurst = "3";
StartLimitIntervalSec = "30s";
}; };
}; };
}; };
+4 -3
View File
@@ -1,7 +1,7 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
let let
container_name = "pihole"; container_name = "pi-hole";
compose_file = "podman/pihole/compose.yaml"; compose_file = "podman/pihole/compose.yaml";
config_dir = "/mnt/config/pihole"; config_dir = "/mnt/config/pihole";
in in
@@ -64,7 +64,6 @@ in
description = "Podman container : ${container_name}"; description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ]; after = [ "network.target" "traefik.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.podman-compose pkgs.podman ];
serviceConfig = { serviceConfig = {
User = "numbus-admin"; User = "numbus-admin";
@@ -76,8 +75,10 @@ in
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully # Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "10m";
StartLimitBurst = "3";
StartLimitIntervalSec = "30s";
}; };
}; };
}; };
+7 -95
View File
@@ -16,22 +16,9 @@ in
services: services:
traefik: traefik:
image: docker.io/library/traefik:latest image: docker.io/library/traefik:latest
container_name: pi-hole container_name: traefik
networks: networks:
nextcloud-aio: TRAEFIK_NETWORKS
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
ports: ports:
- 8080:80 - 8080:80
- 8443:443 - 8443:443
@@ -47,95 +34,18 @@ in
- traefik.http.services.traefik.loadbalancer.server.port=8080 - traefik.http.services.traefik.loadbalancer.server.port=8080
- traefik.http.services.traefik.loadbalancer.server.scheme=http - traefik.http.services.traefik.loadbalancer.server.scheme=http
- traefik.http.routers.traefik-https.entrypoints=websecure - 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=true
- traefik.http.routers.traefik-https.tls.certresolver=cloudflare - traefik.http.routers.traefik-https.tls.certresolver=cloudflare
restart: always restart: always
networks: networks:
nextcloud-aio: TRAEFIK_NETWORKS_REF
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"
''; '';
systemd.services.traefik = { systemd.services.traefik = {
description = "Podman container : ${container_name}"; description = "Podman container : ${container_name}";
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.podman-compose pkgs.podman ];
serviceConfig = { serviceConfig = {
User = "numbus-admin"; User = "numbus-admin";
@@ -147,8 +57,10 @@ in
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans"; ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully # Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "10m";
StartLimitBurst = "3";
StartLimitIntervalSec = "30s";
}; };
}; };
}; };
+4 -3
View File
@@ -17,8 +17,9 @@ NETWORK_HOME_SERVER_IP="192.168.1.5"
# SERVICE SETTINGS # SERVICE SETTINGS
SELECTED_SERVICES=("frigate" "home-assistant") SELECTED_SERVICES=("frigate" "home-assistant")
# DISK SETTINGS # DISK SETTINGS
BOOT_DISK_ID_LIST=("/dev/disk/by-id/nvme001-dfzpjvp") BOOT_DISKS_ID=("/dev/disk/by-id/nvme001-dfzpjvp")
DATA_DISKS_ID_LIST=("/dev/disk/by-id/sata-barracuda-veojapoj") DATA_DISKS_ID=("/dev/disk/by-id/sata-barracuda-veojapoj")
SPINDOWN_DISKS_ID_LIST=("/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 CONTENT_DISK_NUMBER=2
PARITY_DISK_NUMBER=2 PARITY_DISK_NUMBER=2