From 14c5190dc8b78a9074bddbae2946ae423c557f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Numbus?= Date: Sun, 11 Jan 2026 17:45:11 +0100 Subject: [PATCH] Update services. Update configuration. --- deploy.conf | 4 ++ deploy.sh | 66 +++++++++++++++++-- templates/nix-config/misc/activation.nix | 1 + templates/nix-config/misc/networking.nix | 24 ++----- templates/nix-config/podman/frigate.nix | 3 +- templates/nix-config/podman/gitea.nix | 3 +- .../nix-config/podman/home-assistant.nix | 3 +- templates/nix-config/podman/immich.nix | 3 +- templates/nix-config/podman/it-tools.nix | 3 +- templates/nix-config/podman/nextcloud.nix | 7 +- templates/nix-config/podman/passbolt.nix | 3 +- templates/nix-config/podman/pi-hole.nix | 45 +++++++------ templates/nix-config/podman/traefik.nix | 7 +- 13 files changed, 111 insertions(+), 61 deletions(-) diff --git a/deploy.conf b/deploy.conf index e5caabc..5be3d33 100644 --- a/deploy.conf +++ b/deploy.conf @@ -1,19 +1,23 @@ #TARGET SETTINGS export TARGET_HOST="192.168.1.10" export SSH_PUBLIC_KEY="ssh-ed25519 AAAAoefzefpoipoeCEZJCPEACPAcjapjcpajepcjAPJECJPEJAPJAZ yours@yourdomain.com" + # TRAEFIK SETTINGS export DOMAIN_NAME="yourdomain.com" export EMAIL_ADDRESS="your-mail@yourdomain.com" export CF_DNS_API_TOKEN="yourToken" + # SMTP SETTINGS export SENDER_EMAIL_ADDRESS="youraddress@gmail.com" export SENDER_EMAIL_ADDRESS_PASSWORD="emrp raps vzoi vnoe" export SENDER_EMAIL_DOMAIN="smtp.yourdomain.com" export SENDER_EMAIL_PORT="587" + #NETWORK SETTINGS export HOME_ROUTER_SUBNET="192.168.1.0/24" export HOME_ROUTER_IP="192.168.1.1" export HOME_SERVER_IP="192.168.1.5" + # SERVICES SETTINGS export SELECTED_SERVICES=( "frigate" "gitea" "home-assistant" "immich" "it-tools" \ "nextcloud" "passbolt" "pi-hole" "virtualization" ) diff --git a/deploy.sh b/deploy.sh index eeccf8e..af65fdd 100644 --- a/deploy.sh +++ b/deploy.sh @@ -1,5 +1,5 @@ #!/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 curl jq ### --> Default settings export GUM_SPIN_SPINNER="minidot" @@ -728,6 +728,60 @@ export_configuration() { echo "export TRAEFIK_REF_NETWORKS=\"${TRAEFIK_REF_NETWORKS}\"" >> $CONFIG_EXPORT_FILE } +cloudflare_dns_setup() { + echo -e "\n\n☁️ Configuring Cloudflare DNS records..." + + # 1. Get Zone ID + local ZONE_ID + ZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=${DOMAIN_NAME}" \ + -H "Authorization: Bearer ${CF_DNS_API_TOKEN}" \ + -H "Content-Type: application/json" | jq -r '.result[0].id') + + if [[ "${ZONE_ID}" == "null" || -z "${ZONE_ID}" ]]; then + echo -e "\n\n⚠️ Could not fetch Zone ID for ${DOMAIN_NAME}. Please check your Cloudflare \"DNS ZONE\" API token" + echo "Check out the Numbus-Server documentation to see out to get one." + fi + + # 2. Iterate services + for service in "${SELECTED_SERVICES[@]}"; do + if [[ "${service}" == "virtualization" ]]; then continue; fi + + local SUBDOMAIN="${service}.${DOMAIN_NAME}" + echo -n " - Checking for existing record : ${SUBDOMAIN}..." + + # Check existence + local RECORD_ID + RECORD_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=${SUBDOMAIN}&type=A" \ + -H "Authorization: Bearer ${CF_DNS_API_TOKEN}" \ + -H "Content-Type: application/json" | jq -r '.result[0].id') + + if [[ "${RECORD_ID}" != "null" && -n "${RECORD_ID}" ]]; then + RECORD_ID_CONTENT=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=${SUBDOMAIN}&type=A" \ + -H "Authorization: Bearer ${CF_DNS_API_TOKEN}" \ + -H "Content-Type: application/json" | jq -r '.result[0].content') + if [[ "${RECORD_ID_CONTENT}" == "${HOME_SERVER_IP}" ]]; then + echo " ✅ Already configured" + else + echo " ⚠️ A DNS record is configured but does not point to the correct IP" + echo "Do you want to update it? It could break past DNS record you defined" + fi + else + echo -n " ⏳ Creating..." + local CREATE_RES + CREATE_RES=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \ + -H "Authorization: Bearer ${CF_DNS_API_TOKEN}" \ + -H "Content-Type: application/json" \ + --data "{\"type\":\"A\",\"name\":\"${SUBDOMAIN}\",\"content\":\"${HOME_SERVER_IP}\",\"ttl\":1,\"proxied\":false}" | jq -r '.success') + + if [[ "${CREATE_RES}" == "true" ]]; then + echo " ✅ Created." + else + echo " ❌ Failed." + fi + fi + done +} + deploy() { git -C "/home/nixosd/numbus-server" add -f "final-nix-config" @@ -772,10 +826,10 @@ postrun_action() { ssh_to_host 'bash -s' << EOF echo "Enrolling boot disk key to TPM..." if [[ ${#BOOT_DISKS_ID[@]} -eq 1 ]]; then - echo $REMOTE_PASS | sudo -S systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 --unlock-key-file=/etc/secrets/disks/boot-1 /dev/${BOOT_DISKS_1_NAME} + echo $REMOTE_PASS | sudo -S systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 --unlock-key-file=/etc/secrets/disks/boot-1 /dev/${BOOT_DISK_1_NAME} elif [[ ${#BOOT_DISKS_ID[@]} -eq 2 ]]; then - echo $REMOTE_PASS | sudo -S systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 --unlock-key-file=/etc/secrets/disks/boot-1 /dev/${BOOT_DISKS_1_NAME} - echo $REMOTE_PASS | sudo -S systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 --unlock-key-file=/etc/secrets/disks/boot-2 /dev/${BOOT_DISKS_2_NAME} + echo $REMOTE_PASS | sudo -S systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 --unlock-key-file=/etc/secrets/disks/boot-1 /dev/${BOOT_DISK_1_NAME} + echo $REMOTE_PASS | sudo -S systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 --unlock-key-file=/etc/secrets/disks/boot-2 /dev/${BOOT_DISK_2_NAME} fi echo "Getting PCRS 15 hash..." @@ -786,6 +840,8 @@ sed -i "s|# systemIdentity.pcr15 = "PCR_HASH";| systemIdentity.pcr15 = "PCR_HA sed -i "s|PCR_HASH|\${PCR_HASH}|" /etc/nixos/configuration.nix EOF + + gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 " ⚠️ $(gum style --foreground 212 'WARNING:') You will now set the password of the numbus-admin user. \ You will almost never user it. Consider using a very strong password : you can write it down \ @@ -864,6 +920,7 @@ if [[ "$ACTION_ANSWER" == "[1] 🌐 Deploy NixOS on a remote machine" ]]; then disks_generation keys_generation nix_generation + cloudflare_dns_setup sum_up export_configuration deploy @@ -885,6 +942,7 @@ elif [[ "$ACTION_ANSWER" == "[2] 💽 Deploy NixOS on a remote machine with a fi disks_generation keys_generation nix_generation + cloudflare_dns_setup sum_up export_configuration deploy diff --git a/templates/nix-config/misc/activation.nix b/templates/nix-config/misc/activation.nix index 9738976..147196c 100644 --- a/templates/nix-config/misc/activation.nix +++ b/templates/nix-config/misc/activation.nix @@ -20,6 +20,7 @@ mkdir -p /mnt/config/ /mnt/data/ /home/numbus-admin/.numbus-server/ chown -R numbus-admin:users /mnt/config/ chown -R numbus-admin:users /mnt/data/ + chown -R 100032:users /mnt/data/nextcloud/ chown -R numbus-admin:users /home/numbus-admin/.numbus-server/ touch /home/numbus-admin/.numbus-server/chowned.true diff --git a/templates/nix-config/misc/networking.nix b/templates/nix-config/misc/networking.nix index 5e510fe..db79c4d 100644 --- a/templates/nix-config/misc/networking.nix +++ b/templates/nix-config/misc/networking.nix @@ -6,14 +6,18 @@ networking.wireless.enable = false; networking.networkmanager.enable = false; + services.resolved.enable = false; networking.nftables.enable = true; networking.firewall.enable = true; + # Allow rootless containers to bind to port 53 and up + boot.kernel.sysctl."net.ipv4.ip_unprivileged_port_start" = 53; + # Bridge configuration for VMs networking.bridges.br0.interfaces = [ "TARGET_INTERFACE" ]; networking.interfaces.br0.useDHCP = false; - networking.nameservers = [ "HOME_SERVER_IP" "9.9.9.9" ]; + networking.nameservers = [ "127.0.0.1" "9.9.9.9" ]; networking.interfaces.br0.ipv4.addresses = [{ address = "HOME_SERVER_IP"; prefixLength = 24; @@ -23,22 +27,8 @@ interface = "br0"; }; - networking.nftables.tables.nat = { - family = "ip"; - content = '' - chain prerouting { - type nat hook prerouting priority dstnat; policy accept; - iifname "br0" tcp dport 80 redirect to :8080 - iifname "br0" tcp dport 443 redirect to :8443 - iifname "br0" tcp dport 53 redirect to :5353 - iifname "br0" udp dport 53 redirect to :5353 - iifname "br0" udp dport 67 redirect to :6767 - } - ''; - }; - # Open ports in the firewall networking.firewall.allowPing = true; - networking.firewall.allowedTCPPorts = [ 5353 8080 8443 ]; - networking.firewall.allowedUDPPorts = [ 5353 6767 ]; + networking.firewall.allowedTCPPorts = [ 53 80 443 ]; + networking.firewall.allowedUDPPorts = [ 53 443 ]; } \ No newline at end of file diff --git a/templates/nix-config/podman/frigate.nix b/templates/nix-config/podman/frigate.nix index db4e3f0..e16d693 100644 --- a/templates/nix-config/podman/frigate.nix +++ b/templates/nix-config/podman/frigate.nix @@ -71,9 +71,8 @@ in # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; Restart = "on-failure"; - RestartSec = "10m"; + RestartSec = "5m"; StartLimitBurst = "3"; - StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/gitea.nix b/templates/nix-config/podman/gitea.nix index 42a40ac..6fe2497 100644 --- a/templates/nix-config/podman/gitea.nix +++ b/templates/nix-config/podman/gitea.nix @@ -84,9 +84,8 @@ in # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; Restart = "on-failure"; - RestartSec = "10m"; + RestartSec = "5m"; StartLimitBurst = "3"; - StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/home-assistant.nix b/templates/nix-config/podman/home-assistant.nix index b8587e5..487b11b 100644 --- a/templates/nix-config/podman/home-assistant.nix +++ b/templates/nix-config/podman/home-assistant.nix @@ -70,9 +70,8 @@ in # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; Restart = "on-failure"; - RestartSec = "10m"; + RestartSec = "5m"; StartLimitBurst = "3"; - StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/immich.nix b/templates/nix-config/podman/immich.nix index ee5949e..55f01b6 100644 --- a/templates/nix-config/podman/immich.nix +++ b/templates/nix-config/podman/immich.nix @@ -107,9 +107,8 @@ in # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; Restart = "on-failure"; - RestartSec = "10m"; + RestartSec = "5m"; StartLimitBurst = "3"; - StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/it-tools.nix b/templates/nix-config/podman/it-tools.nix index 98b1720..3392d58 100644 --- a/templates/nix-config/podman/it-tools.nix +++ b/templates/nix-config/podman/it-tools.nix @@ -50,9 +50,8 @@ in # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; Restart = "on-failure"; - RestartSec = "10m"; + RestartSec = "5m"; StartLimitBurst = "3"; - StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/nextcloud.nix b/templates/nix-config/podman/nextcloud.nix index 000e1fa..e4be29a 100644 --- a/templates/nix-config/podman/nextcloud.nix +++ b/templates/nix-config/podman/nextcloud.nix @@ -15,7 +15,7 @@ in '' services: nextcloud-aio-mastercontainer: - image: nextcloud/all-in-one:latest + image: ghcr.io/nextcloud-releases/all-in-one:latest container_name: nextcloud-aio-mastercontainer networks: nextcloud-aio: @@ -32,9 +32,9 @@ in NEXTCLOUD_UPLOAD_LIMIT: 16G NEXTCLOUD_MAX_TIME: 3600 NEXTCLOUD_MEMORY_LIMIT: 2048M - SKIP_DOMAIN_VALIDATION: true NEXTCLOUD_ADDITIONAL_APKS: imagemagick NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS: imagick + WATCHTOWER_DOCKER_SOCKET_PATH: /run/user/1000/podman/podman.sock labels: - traefik.enable=true - traefik.http.services.nextcloud-aio.loadbalancer.server.port=8080 @@ -73,9 +73,8 @@ in # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; Restart = "on-failure"; - RestartSec = "10m"; + RestartSec = "5m"; StartLimitBurst = "3"; - StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/passbolt.nix b/templates/nix-config/podman/passbolt.nix index 00c5d09..feab218 100644 --- a/templates/nix-config/podman/passbolt.nix +++ b/templates/nix-config/podman/passbolt.nix @@ -102,9 +102,8 @@ in # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; Restart = "on-failure"; - RestartSec = "10m"; + RestartSec = "5m"; StartLimitBurst = "3"; - StartLimitIntervalSec = "30s"; }; }; }; diff --git a/templates/nix-config/podman/pi-hole.nix b/templates/nix-config/podman/pi-hole.nix index 034e317..d68acaa 100644 --- a/templates/nix-config/podman/pi-hole.nix +++ b/templates/nix-config/podman/pi-hole.nix @@ -2,8 +2,8 @@ let container_name = "pi-hole"; - compose_file = "podman/pihole/compose.yaml"; - config_dir = "/mnt/config/pihole"; + compose_file = "podman/pi-hole/compose.yaml"; + config_dir = "/mnt/config/pi-hole"; in { @@ -18,7 +18,7 @@ in image: pihole/pihole:latest container_name: pi-hole networks: - pihole_frontend: + pi-hole_frontend: ports: # DNS Ports - "53:53/tcp" @@ -26,30 +26,35 @@ in environment: TZ: $TZ FTLCONF_webserver_api_password: $FTLCONF_webserver_api_password - FTLCONF_dns_listeningMode: all + FTLCONF_dns_listeningMode: "all" FTLCONF_dns_revServers: true,$HOME_ROUTER_SUBNET,$HOME_ROUTER_IP,home - FTLCONF_dns_domain_name: home - FTLCONF_dns_domain_local: true + FTLCONF_dns_domain_name: "home" + FTLCONF_dns_domain_local: "true" FTLCONF_dns_hosts: | - $HOME_SERVER_IP dns.$DOMAIN_NAME - $HOME_SERVER_IP reverse.$DOMAIN_NAME + $HOME_SERVER_IP frigate.$DOMAIN_NAME + $HOME_SERVER_IP gitea.$DOMAIN_NAME + $HOME_SERVER_IP home-assistant.$DOMAIN_NAME + $HOME_SERVER_IP immich.$DOMAIN_NAME + $HOME_SERVER_IP it-tools.$DOMAIN_NAME $HOME_SERVER_IP nextcloud.$DOMAIN_NAME $HOME_SERVER_IP nextcloud-aio.$DOMAIN_NAME - $HOME_SERVER_IP hass.$DOMAIN_NAME $HOME_SERVER_IP passbolt.$DOMAIN_NAME - FTLCONF_dhcp_active: false - FTLCONF_dns_upstreams: 9.9.9.11;149.112.112.11 - PIHOLE_UID: 1000 - PIHOLE_GID: 1000 + $HOME_SERVER_IP pi-hole.$DOMAIN_NAME + $HOME_SERVER_IP traefik.$DOMAIN_NAME + FTLCONF_dhcp_active: "false" + FTLCONF_dns_upstreams: 9.9.9.9;149.112.112.112 + FTLCONF_ntp_ipv4_active: "false" + FTLCONF_ntp_ipv6_active: "false" + FTLCONF_ntp_sync_active: "false" volumes: - ${config_dir}:/etc/pihole cap_add: - - SYS_TIME + - NET_ADMIN - SYS_NICE labels: - traefik.enable=true - - traefik.http.services.pihole.loadbalancer.server.port=443 - - traefik.http.services.pihole.loadbalancer.server.scheme=https + - traefik.http.services.pihole.loadbalancer.server.port=80 + - traefik.http.services.pihole.loadbalancer.server.scheme=http - traefik.http.routers.pihole-https.entrypoints=websecure - traefik.http.routers.pihole-https.rule=Host(`pi-hole.$DOMAIN_NAME`) - traefik.http.routers.pihole-https.tls=true @@ -57,7 +62,7 @@ in restart: unless-stopped networks: - pihole_frontend: + pi-hole_frontend: external: true ''; systemd.services.${container_name} = { @@ -70,6 +75,8 @@ in serviceConfig = { User = "numbus-admin"; Environment = [ "XDG_RUNTIME_DIR=/run/user/1000" ]; + AmbientCapabilities = "CAP_NET_ADMIN CAP_SYS_NICE"; + LimitNICE = -20; Type = "exec"; # Pull the latest image before running ExecStartPre = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} pull"; @@ -78,11 +85,9 @@ in # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; Restart = "on-failure"; - RestartSec = "10m"; + RestartSec = "5m"; StartLimitBurst = "3"; - StartLimitIntervalSec = "30s"; }; }; }; } - diff --git a/templates/nix-config/podman/traefik.nix b/templates/nix-config/podman/traefik.nix index 0802a0e..63a3cca 100644 --- a/templates/nix-config/podman/traefik.nix +++ b/templates/nix-config/podman/traefik.nix @@ -20,8 +20,8 @@ in networks: TRAEFIK_NETWORKS ports: - - 8080:80 - - 8443:443 + - "80:80" + - "443:443" volumes: - /run/user/1000/podman/podman.sock:/run/docker.sock:ro - ${config_dir}/rules/:/etc/traefik/conf/:ro @@ -59,9 +59,8 @@ TRAEFIK_REF_NETWORKS # Take it down gracefully ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down"; Restart = "on-failure"; - RestartSec = "10m"; + RestartSec = "5m"; StartLimitBurst = "3"; - StartLimitIntervalSec = "30s"; }; }; };