From 0f49c6c37c93009a0d337ab19d6dc9650f1b1667 Mon Sep 17 00:00:00 2001 From: plasmagoat Date: Tue, 18 Nov 2025 20:00:39 +0100 Subject: [PATCH 1/2] dump --- docs/README.md | 4 +- docs/current-deployment.md | 2 +- docs/fleet-overview.md | 2 +- docs/nodes.md | 4 +- docs/services.md | 111 +++++++++++- hosts/sandbox/default.nix | 8 +- infrastructure/proxmox/main.tf | 2 +- infrastructure/proxmox/terraform.tfstate | 2 +- .../proxmox/terraform.tfstate.backup | 2 +- machines/monitor/loki.nix | 2 +- modules/homelab/lib/systems/proxy.nix | 2 +- modules/homelab/services/alertmanager.nix | 162 ++++++++++++++++++ modules/homelab/services/caddy.nix | 96 +++++++++++ modules/homelab/services/default.nix | 20 +++ modules/homelab/services/example.nix | 86 ++++++++++ .../services/monitoring/monitoring-stack.nix | 60 ------- modules/homelab/services/monitoring/tempo.nix | 0 modules/homelab/services/prometheus.nix | 1 - modules/homelab/services/vaultwarden.nix | 137 +++++++++++++++ nixos/base.nix | 6 +- nixos/flake.nix | 3 - nixos/hosts/dns/host.nix | 8 +- nixos/hosts/dns/networking.nix | 18 +- nixos/hosts/forgejo-runner/networking.nix | 7 +- nixos/hosts/forgejo-runner/sops.nix | 5 +- nixos/hosts/forgejo/host.nix | 8 +- nixos/hosts/forgejo/networking.nix | 6 +- nixos/hosts/monitoring/loki.nix | 2 +- nixos/hosts/monitoring/networking.nix | 6 +- .../traefik/configuration/infra/routers.nix | 7 + .../traefik/configuration/infra/services.nix | 2 + nixos/hosts/traefik/networking.nix | 22 ++- nixos/hosts/traefik/traefik.nix | 41 ++++- nixos/modules/node-exporter.nix | 16 +- nixos/users/plasmagoat.nix | 7 +- 35 files changed, 747 insertions(+), 120 deletions(-) create mode 100644 modules/homelab/services/alertmanager.nix create mode 100644 modules/homelab/services/caddy.nix create mode 100644 modules/homelab/services/example.nix delete mode 100644 modules/homelab/services/monitoring/monitoring-stack.nix delete mode 100644 modules/homelab/services/monitoring/tempo.nix create mode 100644 modules/homelab/services/vaultwarden.nix diff --git a/docs/README.md b/docs/README.md index 9aca520..1572f61 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,7 +2,7 @@ > Auto-generated documentation for the homelab deployment > -> Generated on: Wed, 30 Jul 2025 02:13:08 +0200 +> Generated on: Wed, 30 Jul 2025 02:30:55 +0200 > Source: /home/plasmagoat/homelab ## 📚 Documentation Files @@ -44,7 +44,7 @@ homelab-generate-docs /path/to/output - **Total Nodes**: 2 - **Homelab-Enabled Nodes**: 2 -- **Generated**: Wed, 30 Jul 2025 02:13:11 +0200 +- **Generated**: Wed, 30 Jul 2025 02:30:59 +0200 ## 🛠️ Management Tools diff --git a/docs/current-deployment.md b/docs/current-deployment.md index fbfabf3..03b9e71 100644 --- a/docs/current-deployment.md +++ b/docs/current-deployment.md @@ -2,7 +2,7 @@ > Current homelab deployment configuration > -> Generated on: Wed, 30 Jul 2025 02:13:01 +0200 +> Generated on: Wed, 30 Jul 2025 02:30:45 +0200 > Working directory: /home/plasmagoat/homelab ## Deployment Summary diff --git a/docs/fleet-overview.md b/docs/fleet-overview.md index 92f2991..186fc31 100644 --- a/docs/fleet-overview.md +++ b/docs/fleet-overview.md @@ -2,7 +2,7 @@ > Auto-generated fleet overview > -> Generated on: Wed, 30 Jul 2025 02:12:41 +0200 +> Generated on: Wed, 30 Jul 2025 02:30:24 +0200 > Source: /home/plasmagoat/homelab ## Fleet Statistics diff --git a/docs/nodes.md b/docs/nodes.md index de23565..f4efc67 100644 --- a/docs/nodes.md +++ b/docs/nodes.md @@ -2,7 +2,7 @@ > Detailed per-node configuration > -> Generated on: Wed, 30 Jul 2025 02:12:50 +0200 +> Generated on: Wed, 30 Jul 2025 02:30:33 +0200 ## Node: photos @@ -29,6 +29,7 @@ | Service | Enabled | Port | Description | Tags | |---------|---------|------|-------------|------| +| `example` | ❌ | 1234 | Example Homelab Service | | | `gatus` | ❌ | 8080 | Gatus Status Page | | | `grafana` | ❌ | 3000 | Grafana Metrics Dashboard | | | `minio` | ✅ | 9000 | minio | | @@ -61,6 +62,7 @@ | Service | Enabled | Port | Description | Tags | |---------|---------|------|-------------|------| +| `example` | ❌ | 1234 | Example Homelab Service | | | `gatus` | ✅ | 8080 | Gatus Status Page | | | `grafana` | ✅ | 3000 | Grafana Metrics Dashboard | | | `minio` | ❌ | 9000 | minio | | diff --git a/docs/services.md b/docs/services.md index f7cba44..04cf779 100644 --- a/docs/services.md +++ b/docs/services.md @@ -2,7 +2,7 @@ > Complete service documentation with core options, feature integrations, and smart defaults > -> Generated on: Wed, 30 Jul 2025 02:12:53 +0200 +> Generated on: Wed, 30 Jul 2025 02:30:36 +0200 This document provides comprehensive documentation for homelab services, organized by: - **Core Service Options**: The main service configuration @@ -11,12 +11,13 @@ This document provides comprehensive documentation for homelab services, organiz ## Overview -**Total Available Services:** 4 +**Total Available Services:** 5 ## Service Integration Matrix | Service | Core Options | Monitoring | Logging | Proxy | Deployments | |---------|--------------|------------|---------|-------|-------------| +| `example` | 5 | 📊 | 📝 | 🔀 | 0 | | `gatus` | 11 | 📊 | 📝 | 🔀 | 1 | | `grafana` | 3 | 📊 | 📝 | 🔀 | 1 | | `minio` | 4 | ❌ | ❌ | ❌ | 1 | @@ -26,6 +27,112 @@ This document provides comprehensive documentation for homelab services, organiz ## Service Documentation +### example + +**Deployment Status:** 0/2 nodes have this service enabled + +#### Core Service Options + +The main configuration options for example: + +```nix +homelab.services.example = { + description = Example Homelab Service; # No description + enable = false; # Whether to enable Example Homelab Service. + openFirewall = true; # Whether to open the ports specified in `port` and `webPort` in the firewall. + port = 1234; # No description + systemdServices = [ + "example.service", + "example" +]; # Systemd services to monitor +}; +``` + +#### Feature Integrations + +##### 📊 Monitoring Integration + +Available monitoring options: + +```nix +homelab.services.example = { + # ... core options above ... + + monitoring.enable = true; # Enable monitoring for example + monitoring.extraLabels = {}; # No description + monitoring.healthCheck.conditions = [ + "[STATUS] == 200" +]; # Health check conditions. Setting conditions enables health checks. + monitoring.healthCheck.enable = true; # No description + monitoring.healthCheck.extraChecks = []; # Additional health checks. Adding checks enables health monitoring. + # monitoring.healthCheck.path = ; # Health check endpoint path. Setting this enables health checks. + monitoring.metrics.enable = false; # No description + monitoring.metrics.extraEndpoints = []; # Additional metrics endpoints. Adding endpoints enables metrics collection. + # monitoring.metrics.path = ; # Metrics endpoint path. Setting this enables metrics collection. +}; +``` + +**example sets these monitoring defaults:** +```nix + enable = true; + extraLabels = {}; + healthCheck = {"conditions":["[STATUS] == 200"],"enable":true,"extraChecks":[],"path":null}; + metrics = {"enable":false,"extraEndpoints":[],"path":null}; +``` + +##### 📝 Logging Integration + +Available logging options: + +```nix +homelab.services.example = { + # ... core options above ... + + logging.enable = false; # Enable logging for example + logging.extraLabels = {}; # No description + logging.extraSources = []; # No description + logging.files = []; # No description + # logging.multiline = ; # No description + logging.parsing.extractFields = []; # No description + # logging.parsing.regex = ; # No description +}; +``` + +**example sets these logging defaults:** +```nix + enable = false; + extraLabels = {}; + extraSources = []; + files = []; + multiline = null; + parsing = {"extractFields":[],"regex":null}; +``` + +##### 🔀 Proxy Integration + +Available proxy options: + +```nix +homelab.services.example = { + # ... core options above ... + + proxy.additionalSubdomains = []; # No description + proxy.enable = true; # Enable reverse proxy for example + proxy.enableAuth = false; # No description + proxy.subdomain = example; # No description +}; +``` + +**example sets these proxy defaults:** +```nix + additionalSubdomains = []; + enable = true; + enableAuth = false; + subdomain = example; +``` + +--- + ### gatus **Deployment Status:** 1/2 nodes have this service enabled diff --git a/hosts/sandbox/default.nix b/hosts/sandbox/default.nix index ebf4475..efad52b 100644 --- a/hosts/sandbox/default.nix +++ b/hosts/sandbox/default.nix @@ -42,9 +42,11 @@ }; # services.loki.enable = true; - services.prometheus.enable = true; - services.grafana.enable = true; - services.gatus.enable = true; + # services.prometheus.enable = true; + # services.grafana.enable = true; + # services.gatus.enable = true; + services.vaultwarden.enable = true; + services.caddy.enable = true; }; system.stateVersion = "25.05"; diff --git a/infrastructure/proxmox/main.tf b/infrastructure/proxmox/main.tf index 2741f89..62ac638 100644 --- a/infrastructure/proxmox/main.tf +++ b/infrastructure/proxmox/main.tf @@ -9,5 +9,5 @@ module "sandbox_vm" { # You can override any default variable here: # cpu_cores = 4 # memory = 2048 - # disk_size = "10G" + disk_size = "10G" } diff --git a/infrastructure/proxmox/terraform.tfstate b/infrastructure/proxmox/terraform.tfstate index 9b4fec3..59a4f97 100644 --- a/infrastructure/proxmox/terraform.tfstate +++ b/infrastructure/proxmox/terraform.tfstate @@ -1 +1 @@ -{"version":4,"terraform_version":"1.9.1","serial":16,"lineage":"c76b2921-285f-1904-f2ab-e6a410d16442","outputs":{},"resources":[{"module":"module.sandbox_vm","mode":"managed","type":"proxmox_vm_qemu","name":"nixos-vm","provider":"provider[\"registry.opentofu.org/telmate/proxmox\"]","instances":[{"schema_version":0,"attributes":{"additional_wait":5,"agent":1,"agent_timeout":90,"args":"","automatic_reboot":true,"balloon":0,"bios":"seabios","boot":" ","bootdisk":"","ci_wait":null,"cicustom":null,"cipassword":"$6$rounds=4096$h9zcOYHvB.sy0Ff/$M4cbXjzqmJZ7xRTl3ILWXrg9PePqNzpv.L7MnvMrhcGieK3hrPniU5YEY2Z5/NC1n4QM7VLRSwyP9g9zdjp67/","ciupgrade":true,"ciuser":"root","clone":null,"clone_id":9000,"clone_wait":10,"cores":0,"cpu":[{"affinity":"","cores":2,"flags":[],"limit":0,"numa":false,"sockets":1,"type":"host","units":0,"vcores":0}],"cpu_type":"","current_node":"proxmox-01","default_ipv4_address":"192.168.1.228","default_ipv6_address":"","define_connection_info":true,"desc":"Managed by Terraform.","disk":[],"disks":[{"ide":[{"ide0":[],"ide1":[{"cdrom":[],"cloudinit":[{"storage":"local-lvm"}],"disk":[],"ignore":false,"passthrough":[]}],"ide2":[],"ide3":[]}],"sata":[],"scsi":[],"virtio":[{"virtio0":[{"cdrom":[],"disk":[{"asyncio":"","backup":true,"cache":"","discard":false,"format":"raw","id":0,"iops_r_burst":0,"iops_r_burst_length":0,"iops_r_concurrent":0,"iops_wr_burst":0,"iops_wr_burst_length":0,"iops_wr_concurrent":0,"iothread":false,"linked_disk_id":-1,"mbps_r_burst":0,"mbps_r_concurrent":0,"mbps_wr_burst":0,"mbps_wr_concurrent":0,"readonly":false,"replicate":false,"serial":"","size":"5G","storage":"pv1","wwn":""}],"ignore":false,"passthrough":[]}],"virtio1":[],"virtio10":[],"virtio11":[],"virtio12":[],"virtio13":[],"virtio14":[],"virtio15":[],"virtio2":[],"virtio3":[],"virtio4":[],"virtio5":[],"virtio6":[],"virtio7":[],"virtio8":[],"virtio9":[]}]}],"efidisk":[],"force_create":false,"force_recreate_on_change_of":null,"full_clone":true,"hagroup":"","hastate":"","hostpci":[],"hotplug":"network,disk,usb","id":"proxmox-01/qemu/123","ipconfig0":"ip=dhcp","ipconfig1":null,"ipconfig10":null,"ipconfig11":null,"ipconfig12":null,"ipconfig13":null,"ipconfig14":null,"ipconfig15":null,"ipconfig2":null,"ipconfig3":null,"ipconfig4":null,"ipconfig5":null,"ipconfig6":null,"ipconfig7":null,"ipconfig8":null,"ipconfig9":null,"kvm":true,"linked_vmid":0,"machine":"","memory":1024,"name":"sandbox","nameserver":null,"network":[{"bridge":"vmbr0","firewall":false,"id":0,"link_down":false,"macaddr":"bc:24:11:46:6c:00","model":"virtio","mtu":0,"queues":0,"rate":0,"tag":0}],"numa":false,"onboot":false,"os_network_config":null,"os_type":null,"pci":[],"pcis":[],"pool":"","protection":false,"pxe":null,"qemu_os":"l26","reboot_required":false,"scsihw":"virtio-scsi-single","searchdomain":null,"serial":[{"id":0,"type":"socket"}],"skip_ipv4":false,"skip_ipv6":true,"smbios":[{"family":"","manufacturer":"","product":"","serial":"","sku":"","uuid":"5ae92cdd-a036-4602-af8c-358197f958d9","version":""}],"sockets":0,"ssh_forward_ip":null,"ssh_host":"192.168.1.228","ssh_port":"22","ssh_private_key":null,"ssh_user":null,"sshkeys":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICUP7m8jZJiclZGfSje8CeBYFhX10SrdtjYziuChmj1X plasmagoat@macbook-air\n","startup":"","tablet":true,"tags":"","target_node":"proxmox-01","target_nodes":null,"timeouts":null,"tpm_state":[],"unused_disk":[],"usb":[],"usbs":[],"vcpus":0,"vga":[],"vm_state":"running","vmid":123},"sensitive_attributes":[[{"type":"get_attr","value":"ssh_private_key"}],[{"type":"get_attr","value":"cipassword"}]],"private":"eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWZhdWx0IjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInJlYWQiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19"}]}],"check_results":null} +{"version":4,"terraform_version":"1.9.1","serial":17,"lineage":"c76b2921-285f-1904-f2ab-e6a410d16442","outputs":{},"resources":[{"module":"module.sandbox_vm","mode":"managed","type":"proxmox_vm_qemu","name":"nixos-vm","provider":"provider[\"registry.opentofu.org/telmate/proxmox\"]","instances":[{"schema_version":0,"attributes":{"additional_wait":5,"agent":1,"agent_timeout":90,"args":"","automatic_reboot":true,"balloon":0,"bios":"seabios","boot":" ","bootdisk":"","ci_wait":null,"cicustom":null,"cipassword":"$6$rounds=4096$h9zcOYHvB.sy0Ff/$M4cbXjzqmJZ7xRTl3ILWXrg9PePqNzpv.L7MnvMrhcGieK3hrPniU5YEY2Z5/NC1n4QM7VLRSwyP9g9zdjp67/","ciupgrade":true,"ciuser":"root","clone":null,"clone_id":9000,"clone_wait":10,"cores":0,"cpu":[{"affinity":"","cores":2,"flags":[],"limit":0,"numa":false,"sockets":1,"type":"host","units":0,"vcores":0}],"cpu_type":"","current_node":"proxmox-01","default_ipv4_address":"192.168.1.228","default_ipv6_address":"2a05:f6c7:2030:0:be24:11ff:fe46:6c00","define_connection_info":true,"desc":"Managed by Terraform.","disk":[],"disks":[{"ide":[{"ide0":[],"ide1":[{"cdrom":[],"cloudinit":[{"storage":"local-lvm"}],"disk":[],"ignore":false,"passthrough":[]}],"ide2":[],"ide3":[]}],"sata":[],"scsi":[],"virtio":[{"virtio0":[{"cdrom":[],"disk":[{"asyncio":"","backup":true,"cache":"","discard":false,"format":"raw","id":0,"iops_r_burst":0,"iops_r_burst_length":0,"iops_r_concurrent":0,"iops_wr_burst":0,"iops_wr_burst_length":0,"iops_wr_concurrent":0,"iothread":false,"linked_disk_id":-1,"mbps_r_burst":0,"mbps_r_concurrent":0,"mbps_wr_burst":0,"mbps_wr_concurrent":0,"readonly":false,"replicate":false,"serial":"","size":"10G","storage":"pv1","wwn":""}],"ignore":false,"passthrough":[]}],"virtio1":[],"virtio10":[],"virtio11":[],"virtio12":[],"virtio13":[],"virtio14":[],"virtio15":[],"virtio2":[],"virtio3":[],"virtio4":[],"virtio5":[],"virtio6":[],"virtio7":[],"virtio8":[],"virtio9":[]}]}],"efidisk":[],"force_create":false,"force_recreate_on_change_of":null,"full_clone":true,"hagroup":"","hastate":"","hostpci":[],"hotplug":"network,disk,usb","id":"proxmox-01/qemu/123","ipconfig0":"ip=dhcp","ipconfig1":null,"ipconfig10":null,"ipconfig11":null,"ipconfig12":null,"ipconfig13":null,"ipconfig14":null,"ipconfig15":null,"ipconfig2":null,"ipconfig3":null,"ipconfig4":null,"ipconfig5":null,"ipconfig6":null,"ipconfig7":null,"ipconfig8":null,"ipconfig9":null,"kvm":true,"linked_vmid":0,"machine":"","memory":1024,"name":"sandbox","nameserver":null,"network":[{"bridge":"vmbr0","firewall":false,"id":0,"link_down":false,"macaddr":"bc:24:11:46:6c:00","model":"virtio","mtu":0,"queues":0,"rate":0,"tag":0}],"numa":false,"onboot":false,"os_network_config":null,"os_type":null,"pci":[],"pcis":[],"pool":"","protection":false,"pxe":null,"qemu_os":"l26","reboot_required":false,"scsihw":"virtio-scsi-single","searchdomain":null,"serial":[{"id":0,"type":"socket"}],"skip_ipv4":false,"skip_ipv6":true,"smbios":[{"family":"","manufacturer":"","product":"","serial":"","sku":"","uuid":"5ae92cdd-a036-4602-af8c-358197f958d9","version":""}],"sockets":0,"ssh_forward_ip":null,"ssh_host":"192.168.1.228","ssh_port":"22","ssh_private_key":null,"ssh_user":null,"sshkeys":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICUP7m8jZJiclZGfSje8CeBYFhX10SrdtjYziuChmj1X plasmagoat@macbook-air\n","startup":"","tablet":true,"tags":"","target_node":"proxmox-01","target_nodes":null,"timeouts":null,"tpm_state":[],"unused_disk":[],"usb":[],"usbs":[],"vcpus":0,"vga":[],"vm_state":"running","vmid":123},"sensitive_attributes":[[{"type":"get_attr","value":"cipassword"}],[{"type":"get_attr","value":"ssh_private_key"}]],"private":"eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWZhdWx0IjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInJlYWQiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19"}]}],"check_results":null} diff --git a/infrastructure/proxmox/terraform.tfstate.backup b/infrastructure/proxmox/terraform.tfstate.backup index 848b2ff..9b4fec3 100644 --- a/infrastructure/proxmox/terraform.tfstate.backup +++ b/infrastructure/proxmox/terraform.tfstate.backup @@ -1 +1 @@ -{"version":4,"terraform_version":"1.9.1","serial":15,"lineage":"c76b2921-285f-1904-f2ab-e6a410d16442","outputs":{},"resources":[{"module":"module.sandbox_vm","mode":"managed","type":"proxmox_vm_qemu","name":"nixos-vm","provider":"provider[\"registry.opentofu.org/telmate/proxmox\"]","instances":[{"schema_version":0,"attributes":{"additional_wait":5,"agent":1,"agent_timeout":90,"args":"","automatic_reboot":true,"balloon":0,"bios":"seabios","boot":" ","bootdisk":"","ci_wait":null,"cicustom":null,"cipassword":"","ciupgrade":true,"ciuser":"root","clone":null,"clone_id":9000,"clone_wait":10,"cores":0,"cpu":[{"affinity":"","cores":2,"flags":[],"limit":0,"numa":false,"sockets":1,"type":"host","units":0,"vcores":0}],"cpu_type":"","current_node":"proxmox-01","default_ipv4_address":"192.168.1.228","default_ipv6_address":"2a05:f6c7:2030:0:be24:11ff:fe46:6c00","define_connection_info":true,"desc":"Managed by Terraform.","disk":[],"disks":[{"ide":[{"ide0":[],"ide1":[{"cdrom":[],"cloudinit":[{"storage":"local-lvm"}],"disk":[],"ignore":false,"passthrough":[]}],"ide2":[],"ide3":[]}],"sata":[],"scsi":[],"virtio":[{"virtio0":[{"cdrom":[],"disk":[{"asyncio":"","backup":true,"cache":"","discard":false,"format":"raw","id":0,"iops_r_burst":0,"iops_r_burst_length":0,"iops_r_concurrent":0,"iops_wr_burst":0,"iops_wr_burst_length":0,"iops_wr_concurrent":0,"iothread":false,"linked_disk_id":-1,"mbps_r_burst":0,"mbps_r_concurrent":0,"mbps_wr_burst":0,"mbps_wr_concurrent":0,"readonly":false,"replicate":false,"serial":"","size":"5G","storage":"pv1","wwn":""}],"ignore":false,"passthrough":[]}],"virtio1":[],"virtio10":[],"virtio11":[],"virtio12":[],"virtio13":[],"virtio14":[],"virtio15":[],"virtio2":[],"virtio3":[],"virtio4":[],"virtio5":[],"virtio6":[],"virtio7":[],"virtio8":[],"virtio9":[]}]}],"efidisk":[],"force_create":false,"force_recreate_on_change_of":null,"full_clone":true,"hagroup":"","hastate":"","hostpci":[],"hotplug":"network,disk,usb","id":"proxmox-01/qemu/123","ipconfig0":"ip=dhcp","ipconfig1":null,"ipconfig10":null,"ipconfig11":null,"ipconfig12":null,"ipconfig13":null,"ipconfig14":null,"ipconfig15":null,"ipconfig2":null,"ipconfig3":null,"ipconfig4":null,"ipconfig5":null,"ipconfig6":null,"ipconfig7":null,"ipconfig8":null,"ipconfig9":null,"kvm":true,"linked_vmid":0,"machine":"","memory":1024,"name":"sandbox","nameserver":null,"network":[{"bridge":"vmbr0","firewall":false,"id":0,"link_down":false,"macaddr":"bc:24:11:46:6c:00","model":"virtio","mtu":0,"queues":0,"rate":0,"tag":0}],"numa":false,"onboot":false,"os_network_config":null,"os_type":null,"pci":[],"pcis":[],"pool":"","protection":false,"pxe":null,"qemu_os":"l26","reboot_required":false,"scsihw":"virtio-scsi-single","searchdomain":null,"serial":[{"id":0,"type":"socket"}],"skip_ipv4":false,"skip_ipv6":true,"smbios":[{"family":"","manufacturer":"","product":"","serial":"","sku":"","uuid":"5ae92cdd-a036-4602-af8c-358197f958d9","version":""}],"sockets":0,"ssh_forward_ip":null,"ssh_host":"192.168.1.228","ssh_port":"22","ssh_private_key":null,"ssh_user":null,"sshkeys":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICUP7m8jZJiclZGfSje8CeBYFhX10SrdtjYziuChmj1X plasmagoat@macbook-air\n","startup":"","tablet":true,"tags":"","target_node":"proxmox-01","target_nodes":null,"timeouts":null,"tpm_state":[],"unused_disk":[],"usb":[],"usbs":[],"vcpus":0,"vga":[],"vm_state":"running","vmid":123},"sensitive_attributes":[[{"type":"get_attr","value":"ssh_private_key"}],[{"type":"get_attr","value":"cipassword"}]],"private":"eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWZhdWx0IjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInJlYWQiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19"}]}],"check_results":null} +{"version":4,"terraform_version":"1.9.1","serial":16,"lineage":"c76b2921-285f-1904-f2ab-e6a410d16442","outputs":{},"resources":[{"module":"module.sandbox_vm","mode":"managed","type":"proxmox_vm_qemu","name":"nixos-vm","provider":"provider[\"registry.opentofu.org/telmate/proxmox\"]","instances":[{"schema_version":0,"attributes":{"additional_wait":5,"agent":1,"agent_timeout":90,"args":"","automatic_reboot":true,"balloon":0,"bios":"seabios","boot":" ","bootdisk":"","ci_wait":null,"cicustom":null,"cipassword":"$6$rounds=4096$h9zcOYHvB.sy0Ff/$M4cbXjzqmJZ7xRTl3ILWXrg9PePqNzpv.L7MnvMrhcGieK3hrPniU5YEY2Z5/NC1n4QM7VLRSwyP9g9zdjp67/","ciupgrade":true,"ciuser":"root","clone":null,"clone_id":9000,"clone_wait":10,"cores":0,"cpu":[{"affinity":"","cores":2,"flags":[],"limit":0,"numa":false,"sockets":1,"type":"host","units":0,"vcores":0}],"cpu_type":"","current_node":"proxmox-01","default_ipv4_address":"192.168.1.228","default_ipv6_address":"","define_connection_info":true,"desc":"Managed by Terraform.","disk":[],"disks":[{"ide":[{"ide0":[],"ide1":[{"cdrom":[],"cloudinit":[{"storage":"local-lvm"}],"disk":[],"ignore":false,"passthrough":[]}],"ide2":[],"ide3":[]}],"sata":[],"scsi":[],"virtio":[{"virtio0":[{"cdrom":[],"disk":[{"asyncio":"","backup":true,"cache":"","discard":false,"format":"raw","id":0,"iops_r_burst":0,"iops_r_burst_length":0,"iops_r_concurrent":0,"iops_wr_burst":0,"iops_wr_burst_length":0,"iops_wr_concurrent":0,"iothread":false,"linked_disk_id":-1,"mbps_r_burst":0,"mbps_r_concurrent":0,"mbps_wr_burst":0,"mbps_wr_concurrent":0,"readonly":false,"replicate":false,"serial":"","size":"5G","storage":"pv1","wwn":""}],"ignore":false,"passthrough":[]}],"virtio1":[],"virtio10":[],"virtio11":[],"virtio12":[],"virtio13":[],"virtio14":[],"virtio15":[],"virtio2":[],"virtio3":[],"virtio4":[],"virtio5":[],"virtio6":[],"virtio7":[],"virtio8":[],"virtio9":[]}]}],"efidisk":[],"force_create":false,"force_recreate_on_change_of":null,"full_clone":true,"hagroup":"","hastate":"","hostpci":[],"hotplug":"network,disk,usb","id":"proxmox-01/qemu/123","ipconfig0":"ip=dhcp","ipconfig1":null,"ipconfig10":null,"ipconfig11":null,"ipconfig12":null,"ipconfig13":null,"ipconfig14":null,"ipconfig15":null,"ipconfig2":null,"ipconfig3":null,"ipconfig4":null,"ipconfig5":null,"ipconfig6":null,"ipconfig7":null,"ipconfig8":null,"ipconfig9":null,"kvm":true,"linked_vmid":0,"machine":"","memory":1024,"name":"sandbox","nameserver":null,"network":[{"bridge":"vmbr0","firewall":false,"id":0,"link_down":false,"macaddr":"bc:24:11:46:6c:00","model":"virtio","mtu":0,"queues":0,"rate":0,"tag":0}],"numa":false,"onboot":false,"os_network_config":null,"os_type":null,"pci":[],"pcis":[],"pool":"","protection":false,"pxe":null,"qemu_os":"l26","reboot_required":false,"scsihw":"virtio-scsi-single","searchdomain":null,"serial":[{"id":0,"type":"socket"}],"skip_ipv4":false,"skip_ipv6":true,"smbios":[{"family":"","manufacturer":"","product":"","serial":"","sku":"","uuid":"5ae92cdd-a036-4602-af8c-358197f958d9","version":""}],"sockets":0,"ssh_forward_ip":null,"ssh_host":"192.168.1.228","ssh_port":"22","ssh_private_key":null,"ssh_user":null,"sshkeys":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICUP7m8jZJiclZGfSje8CeBYFhX10SrdtjYziuChmj1X plasmagoat@macbook-air\n","startup":"","tablet":true,"tags":"","target_node":"proxmox-01","target_nodes":null,"timeouts":null,"tpm_state":[],"unused_disk":[],"usb":[],"usbs":[],"vcpus":0,"vga":[],"vm_state":"running","vmid":123},"sensitive_attributes":[[{"type":"get_attr","value":"ssh_private_key"}],[{"type":"get_attr","value":"cipassword"}]],"private":"eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWZhdWx0IjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInJlYWQiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19"}]}],"check_results":null} diff --git a/machines/monitor/loki.nix b/machines/monitor/loki.nix index 8cd9cc7..63be626 100644 --- a/machines/monitor/loki.nix +++ b/machines/monitor/loki.nix @@ -1,5 +1,5 @@ { - networking.firewall.allowedTCPPorts = [ 3100 ]; + networking.firewall.allowedTCPPorts = [3100]; services.loki = { enable = true; diff --git a/modules/homelab/lib/systems/proxy.nix b/modules/homelab/lib/systems/proxy.nix index b5a6e73..c698fdd 100644 --- a/modules/homelab/lib/systems/proxy.nix +++ b/modules/homelab/lib/systems/proxy.nix @@ -24,7 +24,7 @@ with lib; let enhancer = entry: entry // { - _upstream = "http://${entry.host}:${toString entry.port}${entry.path or ""}"; + _upstream = "http://${entry.host}:${toString entry.port}"; _fqdn = "${entry.subdomain}.${entry._nodeConfig.config.homelab.externalDomain or homelabCfg.externalDomain}"; _internal = "${entry.host}:${toString entry.port}"; }; diff --git a/modules/homelab/services/alertmanager.nix b/modules/homelab/services/alertmanager.nix new file mode 100644 index 0000000..43c9636 --- /dev/null +++ b/modules/homelab/services/alertmanager.nix @@ -0,0 +1,162 @@ +{ + config, + lib, + pkgs, + ... +}: +with lib; let + serviceName = "alertmanager"; + cfg = config.homelab.services.${serviceName}; + homelabCfg = config.homelab; +in { + imports = [ + (import ../lib/features/monitoring.nix serviceName) + (import ../lib/features/logging.nix serviceName) + (import ../lib/features/proxy.nix serviceName) + ]; + + # Core service options + options.homelab.services.${serviceName} = { + enable = mkEnableOption "Vault Warden"; + + description = mkOption { + type = types.str; + default = "Vault Warden"; + }; + + port = mkOption { + type = types.port; + default = 9093; + }; + + openFirewall = mkOption { + type = types.bool; + default = true; + description = '' + Whether to open the ports specified in `port` and `webPort` in the firewall. + ''; + }; + + environmentFile = lib.mkOption { + type = with lib.types; nullOr path; + default = null; + example = "/var/lib/vaultwarden.env"; + description = '' + Additional environment file as defined in {manpage}`systemd.exec(5)`. + + Secrets like {env}`ADMIN_TOKEN` and {env}`SMTP_PASSWORD` + should be passed to the service without adding them to the world-readable Nix store. + + Note that this file needs to be available on the host on which `vaultwarden` is running. + + As a concrete example, to make the Admin UI available (from which new users can be invited initially), + the secret {env}`ADMIN_TOKEN` needs to be defined as described + [here](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page): + + ``` + # Admin secret token, see + # https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page + ADMIN_TOKEN=...copy-paste a unique generated secret token here... + ``` + ''; + }; + + systemdServices = mkOption { + type = types.listOf types.str; + default = [ + "vaultwarden.service" + "vaultwarden" + ]; + description = "Systemd services to monitor"; + }; + }; + + # Service configuration with smart defaults + config = mkIf cfg.enable (mkMerge [ + { + services.prometheus.alertmanager = { + enable = true; + openFirewall = cfg.openFirewall; + + environmentFile = alertmanagerEnv; + + webExternalUrl = "http://monitor.lab:9093"; # optional but helpful + configuration = { + route = { + receiver = "null"; + group_by = ["alertname"]; + group_wait = "10s"; + group_interval = "5m"; + repeat_interval = "4h"; + + routes = [ + { + receiver = "telegram"; + matchers = [ + "severity =~ \"warning|critical\"" + ]; + group_wait = "10s"; + continue = true; + } + ]; + }; + + receivers = [ + {name = "null";} + { + name = "telegram"; + telegram_configs = [ + { + api_url = "https://api.telegram.org"; + bot_token = "$TELEGRAM_BOT_TOKEN"; + chat_id = -1002642560007; + message_thread_id = 4; + parse_mode = "HTML"; + send_resolved = true; + message = "{{ template \"telegram.message\". }}"; + } + ]; + } + ]; + + templates = [ + (pkgs.writeText "telegram.tmpl" (builtins.readFile ./provisioning/templates/telegram.tmpl)) + # (pkgs.writeText "telegram.markdown.v2.tmpl" (builtins.readFile ./provisioning/templates/telegram.markdown.v2.tmpl)) + ]; + }; + }; + + networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [cfg.port]; + } + { + homelab.services.${serviceName}.monitoring = { + metrics.path = "/metrics"; + + healthCheck.path = "/healthz"; + healthCheck.conditions = ["[STATUS] == 200" "[RESPONSE_TIME] < 1000"]; + + extraLabels = { + component = "example"; + }; + }; + } + { + # homelab.services.${serviceName}.logging = { + # files = ["/var/log/example/log.log"]; + # # parsing = { + # # regex = "^ts=(?P[^ ]+) caller=(?P[^ ]+) level=(?P\\w+) msg=\"(?P[^\"]*)\""; + # # extractFields = ["level" "caller"]; + # # }; + # extraLabels = { + # component = "example"; + # application = "example"; + # }; + # }; + } + { + homelab.services.${serviceName}.proxy = { + enableAuth = true; + }; + } + ]); +} diff --git a/modules/homelab/services/caddy.nix b/modules/homelab/services/caddy.nix new file mode 100644 index 0000000..a3f6b6c --- /dev/null +++ b/modules/homelab/services/caddy.nix @@ -0,0 +1,96 @@ +{ + config, + lib, + ... +}: +with lib; let + serviceName = "caddy"; + cfg = config.homelab.services.${serviceName}; + homelabCfg = config.homelab; + + allProxyEntries = homelabCfg.reverseProxy.global.allEntries; + generateVirtualHosts = entries: + listToAttrs (map (entry: { + name = entry._fqdn; + value = { + extraConfig = '' + reverse_proxy ${entry._upstream} + ''; + }; + }) + entries); +in { + imports = [ + (import ../lib/features/monitoring.nix serviceName) + (import ../lib/features/logging.nix serviceName) + ]; + + # Core service options + options.homelab.services.${serviceName} = { + enable = mkEnableOption "Caddy web server"; + + description = mkOption { + type = types.str; + default = "Caddy web server"; + }; + + openFirewall = mkOption { + type = types.bool; + default = true; + description = '' + Whether to open the ports specified in `port` and `webPort` in the firewall. + ''; + }; + + systemdServices = mkOption { + type = types.listOf types.str; + default = [ + "caddy.service" + "caddy" + ]; + description = "Systemd services to monitor"; + }; + }; + + # Service configuration with smart defaults + config = mkIf cfg.enable (mkMerge [ + { + services.caddy = { + enable = true; + + virtualHosts = generateVirtualHosts allProxyEntries; + }; + networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [80 443]; + } + { + # homelab.services.${serviceName}.monitoring = { + # metrics.path = "/metrics"; + + # healthCheck.path = "/healthz"; + # healthCheck.conditions = ["[STATUS] == 200" "[RESPONSE_TIME] < 1000"]; + + # extraLabels = { + # component = "example"; + # }; + # }; + } + { + # homelab.services.${serviceName}.logging = { + # files = ["/var/log/example/log.log"]; + # # parsing = { + # # regex = "^ts=(?P[^ ]+) caller=(?P[^ ]+) level=(?P\\w+) msg=\"(?P[^\"]*)\""; + # # extractFields = ["level" "caller"]; + # # }; + # extraLabels = { + # component = "example"; + # application = "example"; + # }; + # }; + } + { + # homelab.services.${serviceName}.proxy = { + # enableAuth = true; + # }; + } + ]); +} diff --git a/modules/homelab/services/default.nix b/modules/homelab/services/default.nix index 2071dd6..e9878cc 100644 --- a/modules/homelab/services/default.nix +++ b/modules/homelab/services/default.nix @@ -4,6 +4,26 @@ ./gatus.nix ./prometheus.nix ./grafana.nix + ./example.nix + ./vaultwarden.nix # ./monitoring/loki.nix + # + # + # TODO + # + # ./alertmanager.nix + # ./dnsmasq.nix + # ./authelia.nix + # ./lldap.nix + # ./roundcube.nix + # ./mailserver.nix + ./caddy.nix + # ./traefik.nix + # ./ente-photos.nix + # ./forgejo.nix + # ./forgejo-runner.nix + # ./jellyfin.nix + # ./arr.nix + # ]; } diff --git a/modules/homelab/services/example.nix b/modules/homelab/services/example.nix new file mode 100644 index 0000000..0fdf20a --- /dev/null +++ b/modules/homelab/services/example.nix @@ -0,0 +1,86 @@ +{ + config, + lib, + pkgs, + ... +}: +with lib; let + serviceName = "example"; + cfg = config.homelab.services.${serviceName}; + homelabCfg = config.homelab; +in { + imports = [ + (import ../lib/features/monitoring.nix serviceName) + (import ../lib/features/logging.nix serviceName) + (import ../lib/features/proxy.nix serviceName) + ]; + + # Core service options + options.homelab.services.${serviceName} = { + enable = mkEnableOption "Example Homelab Service"; + + description = mkOption { + type = types.str; + default = "Example Homelab Service"; + }; + + port = mkOption { + type = types.port; + default = 1234; + }; + + openFirewall = mkOption { + type = types.bool; + default = true; + description = '' + Whether to open the ports specified in `port` and `webPort` in the firewall. + ''; + }; + + systemdServices = mkOption { + type = types.listOf types.str; + default = [ + "example.service" + "example" + ]; + description = "Systemd services to monitor"; + }; + }; + + # Service configuration with smart defaults + config = mkIf cfg.enable (mkMerge [ + { + networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [cfg.port]; + } + { + homelab.services.${serviceName}.monitoring = { + metrics.path = "/metrics"; + + healthCheck.path = "/healthz"; + healthCheck.conditions = ["[STATUS] == 200" "[RESPONSE_TIME] < 1000"]; + + extraLabels = { + component = "example"; + }; + }; + } + { + homelab.services.${serviceName}.logging = { + files = ["/var/log/example/log.log"]; + # parsing = { + # regex = "^ts=(?P[^ ]+) caller=(?P[^ ]+) level=(?P\\w+) msg=\"(?P[^\"]*)\""; + # extractFields = ["level" "caller"]; + # }; + extraLabels = { + component = "example"; + application = "example"; + }; + }; + } + { + homelab.services.${serviceName}.proxy = { + enableAuth = true; + }; + } + ]); +} diff --git a/modules/homelab/services/monitoring/monitoring-stack.nix b/modules/homelab/services/monitoring/monitoring-stack.nix deleted file mode 100644 index 5275460..0000000 --- a/modules/homelab/services/monitoring/monitoring-stack.nix +++ /dev/null @@ -1,60 +0,0 @@ -{ - config, - lib, - ... -}: -with lib; let - cfg = config.homelab.services.monitoring-stack; -in { - imports = [ - ./prometheus.nix - ./alertmanager.nix - ./grafana.nix - ]; - - options.homelab.services.monitoring-stack = { - enable = mkEnableOption "Complete monitoring stack (Prometheus + Alertmanager + Grafana)"; - - prometheus = { - enable = mkOption { - type = types.bool; - default = true; - description = "Enable Prometheus"; - }; - }; - - alertmanager = { - enable = mkOption { - type = types.bool; - default = true; - description = "Enable Alertmanager"; - }; - }; - - grafana = { - enable = mkOption { - type = types.bool; - default = true; - description = "Enable Grafana"; - }; - }; - }; - - config = mkIf cfg.enable { - # Enable services based on configuration - homelab.services.prometheus.enable = mkDefault cfg.prometheus.enable; - homelab.services.alertmanager.enable = mkDefault cfg.alertmanager.enable; - homelab.services.grafana.enable = mkDefault cfg.grafana.enable; - - # Configure Prometheus to use Alertmanager if both are enabled - homelab.services.prometheus.alertmanager = mkIf (cfg.prometheus.enable && cfg.alertmanager.enable) { - enable = true; - url = "http://localhost:${toString config.homelab.services.alertmanager.port}"; - }; - - # Configure Grafana to use Prometheus if both are enabled - homelab.services.grafana.datasources.prometheus = mkIf (cfg.prometheus.enable && cfg.grafana.enable) { - url = "http://localhost:${toString config.homelab.services.prometheus.port}"; - }; - }; -} diff --git a/modules/homelab/services/monitoring/tempo.nix b/modules/homelab/services/monitoring/tempo.nix deleted file mode 100644 index e69de29..0000000 diff --git a/modules/homelab/services/prometheus.nix b/modules/homelab/services/prometheus.nix index dabc086..55f1883 100644 --- a/modules/homelab/services/prometheus.nix +++ b/modules/homelab/services/prometheus.nix @@ -11,7 +11,6 @@ with lib; let # Generate Prometheus scrape configs from global monitoring data prometheusScrapeConfigs = let - # Get all metrics - try global first, fallback to local allMetrics = homelabCfg.monitoring.global.allMetrics; jobGroups = groupBy (m: m.jobName) allMetrics; diff --git a/modules/homelab/services/vaultwarden.nix b/modules/homelab/services/vaultwarden.nix new file mode 100644 index 0000000..9ebabad --- /dev/null +++ b/modules/homelab/services/vaultwarden.nix @@ -0,0 +1,137 @@ +{ + config, + lib, + pkgs, + ... +}: +with lib; let + serviceName = "vaultwarden"; + cfg = config.homelab.services.${serviceName}; + homelabCfg = config.homelab; +in { + imports = [ + (import ../lib/features/monitoring.nix serviceName) + (import ../lib/features/logging.nix serviceName) + (import ../lib/features/proxy.nix serviceName) + ]; + + # Core service options + options.homelab.services.${serviceName} = { + enable = mkEnableOption "Vault Warden"; + + description = mkOption { + type = types.str; + default = "Vault Warden"; + }; + + port = mkOption { + type = types.port; + default = 8222; + }; + + openFirewall = mkOption { + type = types.bool; + default = true; + description = '' + Whether to open the ports specified in `port` and `webPort` in the firewall. + ''; + }; + + environmentFile = lib.mkOption { + type = with lib.types; nullOr path; + default = null; + example = "/var/lib/vaultwarden.env"; + description = '' + Additional environment file as defined in {manpage}`systemd.exec(5)`. + + Secrets like {env}`ADMIN_TOKEN` and {env}`SMTP_PASSWORD` + should be passed to the service without adding them to the world-readable Nix store. + + Note that this file needs to be available on the host on which `vaultwarden` is running. + + As a concrete example, to make the Admin UI available (from which new users can be invited initially), + the secret {env}`ADMIN_TOKEN` needs to be defined as described + [here](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page): + + ``` + # Admin secret token, see + # https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page + ADMIN_TOKEN=...copy-paste a unique generated secret token here... + ``` + ''; + }; + + systemdServices = mkOption { + type = types.listOf types.str; + default = [ + "vaultwarden.service" + "vaultwarden" + ]; + description = "Systemd services to monitor"; + }; + }; + + # Service configuration with smart defaults + config = mkIf cfg.enable (mkMerge [ + { + services.vaultwarden = { + enable = true; + config = { + DOMAIN = "https://bitwarden.example.com"; + SIGNUPS_ALLOWED = false; + + ROCKET_ADDRESS = "0.0.0.0"; + ROCKET_PORT = cfg.port; + + ROCKET_LOG = "critical"; + + # This example assumes a mailserver running on localhost, + # thus without transport encryption. + # If you use an external mail server, follow: + # https://github.com/dani-garcia/vaultwarden/wiki/SMTP-configuration + # SMTP_HOST = "127.0.0.1"; + # SMTP_PORT = 25; + # SMTP_SSL = false; + + # SMTP_FROM = "admin@bitwarden.example.com"; + # SMTP_FROM_NAME = "example.com Bitwarden server"; + + ADMIN_TOKEN = "1234"; + }; + environmentFile = cfg.environmentFile; + }; + + networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [cfg.port]; + } + { + # homelab.services.${serviceName}.monitoring = { + # metrics.path = "/metrics"; + + # healthCheck.path = "/healthz"; + # healthCheck.conditions = ["[STATUS] == 200" "[RESPONSE_TIME] < 1000"]; + + # extraLabels = { + # component = "example"; + # }; + # }; + } + { + # homelab.services.${serviceName}.logging = { + # files = ["/var/log/example/log.log"]; + # # parsing = { + # # regex = "^ts=(?P[^ ]+) caller=(?P[^ ]+) level=(?P\\w+) msg=\"(?P[^\"]*)\""; + # # extractFields = ["level" "caller"]; + # # }; + # extraLabels = { + # component = "example"; + # application = "example"; + # }; + # }; + } + { + homelab.services.${serviceName}.proxy = { + enableAuth = true; + }; + } + ]); +} diff --git a/nixos/base.nix b/nixos/base.nix index 96a60c2..8b6959d 100644 --- a/nixos/base.nix +++ b/nixos/base.nix @@ -1,4 +1,8 @@ -{ config, pkgs, ... }: { +{ + config, + pkgs, + ... +}: { system.stateVersion = "25.05"; services.openssh.enable = true; diff --git a/nixos/flake.nix b/nixos/flake.nix index 0195467..cbd955f 100644 --- a/nixos/flake.nix +++ b/nixos/flake.nix @@ -114,9 +114,6 @@ system = "x86_64-linux"; overlays = []; }; - - defaults = {pkgs, ...}: { - }; }; host-b = { diff --git a/nixos/hosts/dns/host.nix b/nixos/hosts/dns/host.nix index d346b22..55f9c24 100644 --- a/nixos/hosts/dns/host.nix +++ b/nixos/hosts/dns/host.nix @@ -1,6 +1,10 @@ -{ config, pkgs, modulesPath, lib, ... }: - { + config, + pkgs, + modulesPath, + lib, + ... +}: { imports = [ ../../templates/base.nix ./networking.nix diff --git a/nixos/hosts/dns/networking.nix b/nixos/hosts/dns/networking.nix index 0942d99..991d682 100644 --- a/nixos/hosts/dns/networking.nix +++ b/nixos/hosts/dns/networking.nix @@ -2,18 +2,20 @@ networking.hostName = "dns"; # networking.useHostResolvConf = false; # networking.interfaces.eth0.useDHCP = true; - networking.interfaces.eth0.ipv4.addresses = [{ - address = "192.168.1.53"; - prefixLength = 24; - }]; + networking.interfaces.eth0.ipv4.addresses = [ + { + address = "192.168.1.53"; + prefixLength = 24; + } + ]; networking.defaultGateway = "192.168.1.1"; # your router - networking.nameservers = [ "8.8.8.8" ]; # fallback resolvers + networking.nameservers = ["8.8.8.8"]; # fallback resolvers - networking.firewall.allowedTCPPorts = [ 53 67 80 443 ]; - networking.firewall.allowedUDPPorts = [ 53 67 ]; + networking.firewall.allowedTCPPorts = [53 67 80 443]; + networking.firewall.allowedUDPPorts = [53 67]; networking.hosts = { - "192.168.1.53" = [ "dns" "dns.lab" ]; + "192.168.1.53" = ["dns" "dns.lab"]; }; } diff --git a/nixos/hosts/forgejo-runner/networking.nix b/nixos/hosts/forgejo-runner/networking.nix index df98995..2a38bab 100644 --- a/nixos/hosts/forgejo-runner/networking.nix +++ b/nixos/hosts/forgejo-runner/networking.nix @@ -1,4 +1,9 @@ -{ config, lib, pkgs, runnerId, ... }: { + config, + lib, + pkgs, + runnerId, + ... +}: { networking.hostName = "forgejo-runner-${runnerId}"; } diff --git a/nixos/hosts/forgejo-runner/sops.nix b/nixos/hosts/forgejo-runner/sops.nix index 1cbbeaf..fdddc2b 100644 --- a/nixos/hosts/forgejo-runner/sops.nix +++ b/nixos/hosts/forgejo-runner/sops.nix @@ -1,5 +1,8 @@ -{ config, lib, ... }: { + config, + lib, + ... +}: { sops.secrets."forgejo-runner-registration-token" = { sopsFile = ../../secrets/forgejo/runner-secrets.yml; mode = "0440"; diff --git a/nixos/hosts/forgejo/host.nix b/nixos/hosts/forgejo/host.nix index 1883cca..184e269 100644 --- a/nixos/hosts/forgejo/host.nix +++ b/nixos/hosts/forgejo/host.nix @@ -1,6 +1,10 @@ -{ config, pkgs, modulesPath, lib, ... }: - { + config, + pkgs, + modulesPath, + lib, + ... +}: { imports = [ ../../templates/base.nix ../../secrets/shared-sops.nix diff --git a/nixos/hosts/forgejo/networking.nix b/nixos/hosts/forgejo/networking.nix index 6e9eb1c..7406cb2 100644 --- a/nixos/hosts/forgejo/networking.nix +++ b/nixos/hosts/forgejo/networking.nix @@ -1,4 +1,8 @@ -{ config, lib, pkgs, ... }: { + config, + lib, + pkgs, + ... +}: { networking.hostName = "forgejo"; } diff --git a/nixos/hosts/monitoring/loki.nix b/nixos/hosts/monitoring/loki.nix index 8cd9cc7..63be626 100644 --- a/nixos/hosts/monitoring/loki.nix +++ b/nixos/hosts/monitoring/loki.nix @@ -1,5 +1,5 @@ { - networking.firewall.allowedTCPPorts = [ 3100 ]; + networking.firewall.allowedTCPPorts = [3100]; services.loki = { enable = true; diff --git a/nixos/hosts/monitoring/networking.nix b/nixos/hosts/monitoring/networking.nix index a8fd74e..4a1d647 100644 --- a/nixos/hosts/monitoring/networking.nix +++ b/nixos/hosts/monitoring/networking.nix @@ -1,4 +1,8 @@ -{ config, lib, pkgs, ... }: { + config, + lib, + pkgs, + ... +}: { networking.hostName = "monitor"; } diff --git a/nixos/hosts/traefik/configuration/infra/routers.nix b/nixos/hosts/traefik/configuration/infra/routers.nix index 3312e1a..0207f92 100644 --- a/nixos/hosts/traefik/configuration/infra/routers.nix +++ b/nixos/hosts/traefik/configuration/infra/routers.nix @@ -41,4 +41,11 @@ entryPoints = ["websecure"]; tls.certResolver = "letsencrypt"; }; + + caddy = { + rule = "PathPrefix(`/`)"; + service = "caddy"; + entryPoints = ["web"]; + priority = 15; + }; } diff --git a/nixos/hosts/traefik/configuration/infra/services.nix b/nixos/hosts/traefik/configuration/infra/services.nix index 35a49f2..0f997a7 100644 --- a/nixos/hosts/traefik/configuration/infra/services.nix +++ b/nixos/hosts/traefik/configuration/infra/services.nix @@ -9,4 +9,6 @@ proxmox.loadBalancer.serversTransport = "insecureTransport"; nas.loadBalancer.servers = [{url = "https://192.168.1.226:5001";}]; nas.loadBalancer.serversTransport = "insecureTransport"; + + caddy.loadBalancer.servers = [{url = "http://sandbox.lab:80";}]; } diff --git a/nixos/hosts/traefik/networking.nix b/nixos/hosts/traefik/networking.nix index 4c09486..ac4e9b2 100644 --- a/nixos/hosts/traefik/networking.nix +++ b/nixos/hosts/traefik/networking.nix @@ -1,13 +1,19 @@ -{ config, lib, pkgs, ... }: { - +{ + config, + lib, + pkgs, + ... +}: { networking.hostName = "traefik"; - networking.interfaces.eth0.ipv4.addresses = [{ - address = "192.168.1.80"; - prefixLength = 24; - }]; + networking.interfaces.eth0.ipv4.addresses = [ + { + address = "192.168.1.80"; + prefixLength = 24; + } + ]; - networking.firewall.allowedTCPPorts = [ 80 443 8080 8082 ]; + networking.firewall.allowedTCPPorts = [80 443 8080 8082]; - networking.nameservers = [ "192.168.1.53" ]; + networking.nameservers = ["192.168.1.53"]; networking.defaultGateway = "192.168.1.1"; } diff --git a/nixos/hosts/traefik/traefik.nix b/nixos/hosts/traefik/traefik.nix index 139161f..10b4e3e 100644 --- a/nixos/hosts/traefik/traefik.nix +++ b/nixos/hosts/traefik/traefik.nix @@ -50,14 +50,41 @@ in { staticConfigOptions = staticConfig; - dynamicConfigOptions.http = { - routers = allRouters; - services = allServices; - middlewares = middlewares; + dynamicConfigOptions = { + # HTTP configuration (your existing setup) + http = { + routers = allRouters; + services = allServices; + middlewares = middlewares; + serversTransports = { + insecureTransport = { + insecureSkipVerify = true; + }; + }; + }; - serversTransports = { - insecureTransport = { - insecureSkipVerify = true; + tcp = { + routers = { + caddy-fallback = { + rule = "HostSNI(`*`)"; # Matches any SNI + service = "caddy-tls"; + entryPoints = ["websecure"]; + priority = 1; # Lowest priority - only if no HTTP router matches + tls = { + passthrough = true; + }; + }; + }; + services = { + caddy-tls = { + loadBalancer = { + servers = [ + { + address = "sandbox.lab:443"; + } + ]; + }; + }; }; }; }; diff --git a/nixos/modules/node-exporter.nix b/nixos/modules/node-exporter.nix index b394be6..11f335e 100644 --- a/nixos/modules/node-exporter.nix +++ b/nixos/modules/node-exporter.nix @@ -1,18 +1,20 @@ -{ config, pkgs, ... }: -let - prometheus_exporter_port = 9100; -in { - networking.firewall.allowedTCPPorts = [ prometheus_exporter_port ]; + config, + pkgs, + ... +}: let + prometheus_exporter_port = 9100; +in { + networking.firewall.allowedTCPPorts = [prometheus_exporter_port]; services.prometheus = { exporters = { node = { enable = true; - enabledCollectors = [ "systemd" ]; + enabledCollectors = ["systemd"]; port = prometheus_exporter_port; # /nix/store/zgsw0yx18v10xa58psanfabmg95nl2bb-node_exporter-1.8.1/bin/node_exporter --help - extraFlags = [ "--collector.ethtool" "--collector.softirqs" "--collector.tcpstat" "--collector.wifi" ]; + extraFlags = ["--collector.ethtool" "--collector.softirqs" "--collector.tcpstat" "--collector.wifi"]; }; }; }; diff --git a/nixos/users/plasmagoat.nix b/nixos/users/plasmagoat.nix index 72685be..2ef4d70 100644 --- a/nixos/users/plasmagoat.nix +++ b/nixos/users/plasmagoat.nix @@ -1,4 +1,9 @@ -{ config, lib, pkgs, ... }: { +{ + config, + lib, + pkgs, + ... +}: { users.users.plasmagoat = { isNormalUser = true; description = "plasmagoat"; From 3cc85f34ee2985957bf4801b792c4462993c88cb Mon Sep 17 00:00:00 2001 From: Forgejo Bot Date: Wed, 19 Nov 2025 06:01:00 +0000 Subject: [PATCH 2/2] feat: automated changes --- flake.lock | 67 ++++++++++++++++++++---------------------------------- 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/flake.lock b/flake.lock index e46dbf1..ef3b99b 100644 --- a/flake.lock +++ b/flake.lock @@ -25,11 +25,11 @@ "stable": "stable" }, "locked": { - "lastModified": 1753701727, - "narHash": "sha256-tgiPAFXoSGIm3wUAuKwjk2fgTgZ0rpT90RNfhU5QKJA=", + "lastModified": 1762034856, + "narHash": "sha256-QVey3iP3UEoiFVXgypyjTvCrsIlA4ecx6Acaz5C8/PQ=", "owner": "zhaofengli", "repo": "colmena", - "rev": "342054695f53c4a27c8dce0a8c9f35ade6d963d6", + "rev": "349b035a5027f23d88eeb3bc41085d7ee29f18ed", "type": "github" }, "original": { @@ -57,11 +57,11 @@ "flake-compat_2": { "flake": false, "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "lastModified": 1761588595, + "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", "owner": "edolstra", "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", "type": "github" }, "original": { @@ -98,11 +98,11 @@ ] }, "locked": { - "lastModified": 1750779888, - "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=", + "lastModified": 1762441963, + "narHash": "sha256-j+rNQ119ffYUkYt2YYS6rnd6Jh/crMZmbqpkGLXaEt0=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d", + "rev": "8e7576e79b88c16d7ee3bbd112c8d90070832885", "type": "github" }, "original": { @@ -156,11 +156,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1753694789, - "narHash": "sha256-cKgvtz6fKuK1Xr5LQW/zOUiAC0oSQoA9nOISB0pJZqM=", + "lastModified": 1750134718, + "narHash": "sha256-v263g4GbxXv87hMXMCpjkIxd/viIF7p3JpJrwgKdNiI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "dc9637876d0dcc8c9e5e22986b857632effeb727", + "rev": "9e83b64f727c88a7711a2c463a7b16eedb69a84c", "type": "github" }, "original": { @@ -170,29 +170,13 @@ "type": "github" } }, - "nixpkgs-25_05": { - "locked": { - "lastModified": 1751741127, - "narHash": "sha256-t75Shs76NgxjZSgvvZZ9qOmz5zuBE8buUaYD28BMTxg=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "29e290002bfff26af1db6f64d070698019460302", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-25.05", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs-unstable": { "locked": { - "lastModified": 1753694789, - "narHash": "sha256-cKgvtz6fKuK1Xr5LQW/zOUiAC0oSQoA9nOISB0pJZqM=", + "lastModified": 1763421233, + "narHash": "sha256-Stk9ZYRkGrnnpyJ4eqt9eQtdFWRRIvMxpNRf4sIegnw=", "owner": "nixos", "repo": "nixpkgs", - "rev": "dc9637876d0dcc8c9e5e22986b857632effeb727", + "rev": "89c2b2330e733d6cdb5eae7b899326930c2c0648", "type": "github" }, "original": { @@ -204,11 +188,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1753795159, - "narHash": "sha256-0fOuNh5MefjES+ie0zV3mVMSs1RwXhVIxcNQuu+Q4g4=", + "lastModified": 1763530959, + "narHash": "sha256-mxs0x/Wr3jYC0u8vmVKaufitZ/jbH0zMDxa5cM9b1fM=", "owner": "nixos", "repo": "nixpkgs", - "rev": "5a012ffbe2494cb777ec3dbace5811f927bddc72", + "rev": "672ffbceb1b0d3fe866b8f838570580517643bb5", "type": "github" }, "original": { @@ -233,15 +217,14 @@ "git-hooks": "git-hooks", "nixpkgs": [ "nixpkgs" - ], - "nixpkgs-25_05": "nixpkgs-25_05" + ] }, "locked": { - "lastModified": 1753285640, - "narHash": "sha256-ofa021NeHDXAxg5J8mSnn8rHa393PAlD85ZCetP4Qa0=", + "lastModified": 1763317756, + "narHash": "sha256-7CD7BQR3RVKllDWfqIwAicgs2j4jzpaugxvkLU8cGgI=", "owner": "simple-nixos-mailserver", "repo": "nixos-mailserver", - "rev": "ce87c8a9771d1a20c3fa3b60113b9b0821627dcb", + "rev": "cbdf90f639660981a55bbf6af86e6cc5f13d2752", "type": "gitlab" }, "original": { @@ -257,11 +240,11 @@ ] }, "locked": { - "lastModified": 1752544651, - "narHash": "sha256-GllP7cmQu7zLZTs9z0J2gIL42IZHa9CBEXwBY9szT0U=", + "lastModified": 1763509310, + "narHash": "sha256-s2WzTAD3vJtPACBCZXezNUMTG/wC6SFsU9DxazB9wDI=", "owner": "Mic92", "repo": "sops-nix", - "rev": "2c8def626f54708a9c38a5861866660395bb3461", + "rev": "3ee33c0ed7c5aa61b4e10484d2ebdbdc98afb03e", "type": "github" }, "original": {