Refactor nginx.nix using generative functions; Remove bind container service; Enable CoreDNS; Open 53UDP on system firewall; rename service files; containers listen on localhost only; added SDA-EXT data volume
This commit is contained in:
		
							
								
								
									
										43
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								README
									
									
									
									
									
								
							| @ -1,19 +1,49 @@ | ||||
| # eve-psr-nix0 | ||||
|  | ||||
| This repository holds the configuration for my primary home server.  | ||||
| This README exists to document solutions used or implemented with Nix. | ||||
| This repository holds the configuration for my primary home server. | ||||
|  | ||||
| --- | ||||
| ## details | ||||
|  | ||||
| - Defines a single node host | ||||
| - Follows the latest stable nixpkgs  | ||||
| - Utilizes the nixpkgs-fmt code formatter | ||||
|   -> /flake.nix | ||||
|  | ||||
| - Provides a devShell with direnv/nix-direnv integration  | ||||
| - Common project scripts are packaged and then exposed via devShell/direnv | ||||
|   -> /shell.nix | ||||
|  | ||||
| - Allows SSH Access  | ||||
| - Enables the Hydra build server | ||||
| - Enables the nix-serve-ng binary cache server | ||||
|   -> /system/services.nix | ||||
|  | ||||
| - HTTP entrypoint is an Nginx Reverse Proxy  | ||||
| - Automatic TLS provisioning via Let's Encrypt ACME | ||||
| - Directly reference nix packages and configuration in Virtual Host definitions | ||||
|   -> /applcation/nginx.nix | ||||
|  | ||||
| - Monitoring stack consisting of Prometheus, Grafana, Loki, and Promtail | ||||
| - Complete monitoring stack and connections are defined declaratively via Nix | ||||
|   -> /monitoring/*.nix | ||||
|  | ||||
| - podman & systemd container orchestration | ||||
| - podman services are exposed only to localhost and are reverse proxied by Nginx | ||||
|   -> /application/containers.nix | ||||
|  | ||||
| - agenix for secrets encryption and management | ||||
|   -> /system/age.nix | ||||
|  | ||||
| ## cheatsheet | ||||
|  | ||||
| ### Enter the developer shell without pulling down the repository: | ||||
| ### Enter the developer shell without cloning the repository: | ||||
| ``` | ||||
| $> nix develop git+https://git.eversole.co/eve-psr-nix0 | ||||
| $nix> # Success! | ||||
| ``` | ||||
|  | ||||
| The rest of the cheatsheet assumes you have already cloned the repository and entered the developer shell:  | ||||
| The rest of the cheatsheet assumes you have entered the developer shell or are using direnv:  | ||||
| ``` | ||||
| $> git clone https://git.eversole.co/eve-psr-nix0 | ||||
| $> cd eve-psr-nix0 | ||||
| @ -23,13 +53,14 @@ $nix> # Success! Now we have our development dependencies. | ||||
|  | ||||
| ### Use the developer shell alias to remotely build and deploy the configuration to eve-psr-nix0: | ||||
| ``` | ||||
| # This is it! Check the shellHook in outputs.devShell.x86_64-linux for more details. | ||||
| # This is it! Check the package definitions in /shell.nix for more details. | ||||
| $nix> deploy  | ||||
| ``` | ||||
|  | ||||
| ### Format .nix source files: | ||||
| ``` | ||||
| $nix> nix fmt *.nix | ||||
| # This is it! Check the package definitions in /shell.nix for more details. | ||||
| $nix> format | ||||
| ``` | ||||
|  | ||||
| ### Create a new agenix secret: | ||||
|  | ||||
| @ -2,17 +2,9 @@ | ||||
|   virtualisation.oci-containers = { | ||||
|     containers = { | ||||
|  | ||||
|       bind = { | ||||
|         image = "sameersbn/bind:latest"; | ||||
|         ports = | ||||
|           [ "0.0.0.0:53:53/tcp" "0.0.0.0:53:53/udp" "0.0.0.0:5053:10000/tcp" ]; | ||||
|         volumes = [ "/home/sezycei/srv/containerdata/bind/bind:/data" ]; | ||||
|         environmentFiles = [ /home/sezycei/srv/containerdata/bind/.env ]; | ||||
|       }; | ||||
|  | ||||
|       jellyfin = { | ||||
|         image = "linuxserver/jellyfin"; | ||||
|         ports = [ "0.0.0.0:8096:8096" "0.0.0.0:8920:8920" ]; | ||||
|         ports = [ "127.0.0.1:8096:8096" "127.0.0.1:8920:8920" ]; | ||||
|         volumes = [ | ||||
|           "/home/sezycei/srv/containerdata/jellyfin/config:/config" | ||||
|           "/home/torrent/data/completed:/data/unsorted" | ||||
| @ -31,7 +23,7 @@ | ||||
|  | ||||
|       legit = { | ||||
|         image = "docker.matri.cx/legit"; | ||||
|         ports = [ "0.0.0.0:5121:8080" ]; | ||||
|         ports = [ "127.0.0.1:5121:8080" ]; | ||||
|         volumes = [ | ||||
|           "/home/sezycei/srv/containerdata/legit/static:/static" | ||||
|           "/home/sezycei/srv/containerdata/legit/templates:/templates" | ||||
| @ -43,7 +35,7 @@ | ||||
|  | ||||
|       murmur = { | ||||
|         image = "goofball222/murmur"; | ||||
|         ports = [ "0.0.0.0:64738:64738" "0.0.0.0:64738:64738/udp" ]; | ||||
|         ports = [ "127.0.0.1:64738:64738" "127.0.0.1:64738:64738/udp" ]; | ||||
|         volumes = [ | ||||
|           "/home/sezycei/srv/containerdata/registry/registry/data:/var/lib/registry" | ||||
|           "/home/sezycei/srv/containerdata/registry/registry/certs:/certs" | ||||
| @ -54,7 +46,7 @@ | ||||
|  | ||||
|       purr = { | ||||
|         image = "docker.matri.cx/purr"; | ||||
|         ports = [ "0.0.0.0:5195:3000" ]; | ||||
|         ports = [ "127.0.0.1:5195:3000" ]; | ||||
|         volumes = [ | ||||
|           "/home/sezycei/dev/purr/data/Purr.sqlite:/app/data/Purr.sqlite" | ||||
|           "/home/sezycei/dev/purr/config.dhall:/app/config.dhall" | ||||
| @ -64,7 +56,7 @@ | ||||
|  | ||||
|       registry = { | ||||
|         image = "registry:2"; | ||||
|         ports = [ "0.0.0.0:3001:5000" ]; | ||||
|         ports = [ "127.0.0.1:3001:5000" ]; | ||||
|         volumes = [ | ||||
|           "/home/sezycei/srv/containerdata/registry/registry/data:/var/lib/registry" | ||||
|           "/home/sezycei/srv/containerdata/registry/registry/certs:/certs" | ||||
| @ -75,7 +67,7 @@ | ||||
|  | ||||
|       transmission = { | ||||
|         image = "haugene/transmission-openvpn"; | ||||
|         ports = [ "0.0.0.0:9091:9091" ]; | ||||
|         ports = [ "127.0.0.1:9091:9091" ]; | ||||
|         volumes = [ | ||||
|           "/home/sezycei/srv/scripts/transmission/settings.json:/etc/transmission-daemon/settings.json" | ||||
|           "/etc/localtime:/etc/localtime:ro" | ||||
|  | ||||
| @ -1,124 +1,77 @@ | ||||
| { config, ... }: { | ||||
| { pkgs, config, ... }: | ||||
| let | ||||
|   containernix = import ./containers.nix; | ||||
|   containers = containernix.virtualisation.oci-containers.containers; | ||||
| in | ||||
| { | ||||
|   services.nginx = { | ||||
|     enable = true; | ||||
|     recommendedProxySettings = true; | ||||
|     recommendedOptimisation = true; | ||||
|     recommendedGzipSettings = true; | ||||
|  | ||||
|     virtualHosts."cache.matri.cx" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/cache.matri.cx"; | ||||
|       locations."/" = { | ||||
|         extraConfig = "allow 192.168.0.0\/24;\ndeny all;"; | ||||
|         proxyPass = "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}"; | ||||
|     virtualHosts = | ||||
|       let | ||||
|         base = locations: { | ||||
|           enableACME = true; | ||||
|           forceSSL = true; | ||||
|           inherit locations; | ||||
|         }; | ||||
|  | ||||
|         static = { dir }: base { | ||||
|           "/".root = dir; | ||||
|         }; | ||||
|  | ||||
|         proxied = { target, extra ? "" }: base { | ||||
|           "/" = { | ||||
|             proxyPass = target; | ||||
|             extraConfig = extra; | ||||
|           }; | ||||
|         }; | ||||
|  | ||||
|         proxiedAuth = { target, extra ? "", auth }: base { | ||||
|           "/" = { | ||||
|             proxyPass = target; | ||||
|             basicAuthFile = auth; | ||||
|             extraConfig = extra; | ||||
|           }; | ||||
|         }; | ||||
|         proxiedLAN = { target }: base { | ||||
|           "/" = { | ||||
|             proxyPass = target; | ||||
|             extraConfig = '' | ||||
|               allow 192.168.0.0/24; | ||||
|               deny all; | ||||
|             ''; | ||||
|           }; | ||||
|         }; | ||||
|       in | ||||
|       { | ||||
|         "cache.matri.cx" = proxiedLAN { | ||||
|           target = "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}"; | ||||
|         }; | ||||
|         "caitlynncox.com" = static { dir = "/var/www/caitlynncox.com"; }; | ||||
|         "dallasmed65.com" = static { dir = "/var/www/dallasmed65.com"; }; | ||||
|         "docker.matri.cx" = proxiedAuth { | ||||
|           auth = config.age.secrets.htpasswd-dock.path; | ||||
|           target = "http://127.0.0.1:3001"; | ||||
|         }; | ||||
|         "eversole.co" = static { dir = "/var/www/jame.su"; }; | ||||
|         "git.eversole.co" = proxied { target = "http://127.0.0.1:5121"; }; | ||||
|         "graf.eversole.co" = { root = "/var/www/graf.eversole.co"; }; # refer to /monitoring/nginx.nix | ||||
|         "hydra.matri.cx" = proxied { | ||||
|           target = "http://127.0.0.1:3034"; | ||||
|           extra = '' | ||||
|             proxy_set_header X-Request-Base "https://hydra.matri.cx"; | ||||
|           ''; | ||||
|         }; | ||||
|         "jame.su" = static { dir = "/var/www/jame.su"; }; | ||||
|         "matri.cx" = static { dir = "/var/www/matri.cx"; }; | ||||
|         "media.matri.cx" = proxied { target = "http://127.0.0.1:8096"; }; | ||||
|         "sezycei.com" = static { dir = "/var/www/sezycei.com"; }; | ||||
|         "snakebelmont.com" = static { dir = "/var/www/snakebelmont.com"; }; | ||||
|         "transmission.matri.cx" = proxiedLAN { target = "http://127.0.0.1:9001"; }; | ||||
|         "purr.eversole.co" = proxied { target = "http://127.0.0.1:5195"; }; | ||||
|       }; | ||||
|     }; | ||||
|  | ||||
|     virtualHosts."caitlynncox.com" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/caitlynncox.com"; | ||||
|     }; | ||||
|  | ||||
|     virtualHosts."dallasmed65.com" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/dallasmed65.com"; | ||||
|     }; | ||||
|  | ||||
|     virtualHosts."docker.matri.cx" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/docker.matri.cx"; | ||||
|       locations."/" = { | ||||
|         basicAuthFile = config.age.secrets.htpasswd-dock.path; | ||||
|         proxyPass = "http://192.168.0.130:3001"; | ||||
|       }; | ||||
|     }; | ||||
|  | ||||
|     virtualHosts."eversole.co" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/jame.su"; | ||||
|       locations = { | ||||
|         "/.well-known/openpgpkey/hu/".extraConfig = '' | ||||
|           default_type "application/octet-stream"; | ||||
|           add_header Access-Control-Allow-Origin * always; | ||||
|         ''; | ||||
|         "/ip".proxyPass = "http://192.168.0.130:5001"; | ||||
|         "/pw".proxyPass = "http://192.168.0.130:5002"; | ||||
|       }; | ||||
|     }; | ||||
|  | ||||
|     virtualHosts."git.eversole.co" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/git.eversole.co"; | ||||
|       locations = { | ||||
|         "/James".extraConfig = '' | ||||
|           if ($request_uri ~* "([^/]*$)" ) { | ||||
|             return 301 https://$server_name/$1; | ||||
|           } | ||||
|         ''; | ||||
|         "/".proxyPass = "http://192.168.0.130:5121"; | ||||
|       }; | ||||
|     }; | ||||
|  | ||||
|     # refer to /monitoring/nginx.nix | ||||
|     virtualHosts."graf.eversole.co" = { | ||||
|       root = "/var/www/graf.eversole.co"; | ||||
|     }; | ||||
|  | ||||
|     virtualHosts."hydra.matri.cx" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/hydra.matri.cx"; | ||||
|       locations."/" = { | ||||
|         proxyPass = "http://192.168.0.130:3034"; | ||||
|         extraConfig = '' | ||||
|           proxy_set_header X-Request-Base "https://hydra.matri.cx"; | ||||
|         ''; | ||||
|       }; | ||||
|     }; | ||||
|  | ||||
|     virtualHosts."jame.su" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/jame.su"; | ||||
|     }; | ||||
|  | ||||
|     virtualHosts."matri.cx" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/matri.cx"; | ||||
|     }; | ||||
|  | ||||
|     virtualHosts."media.matri.cx" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/media.matri.cx"; | ||||
|       locations."/".proxyPass = "http://192.168.0.130:8096"; | ||||
|     }; | ||||
|  | ||||
|     virtualHosts."sezycei.com" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/sezycei.com"; | ||||
|     }; | ||||
|  | ||||
|     virtualHosts."snakebelmont.com" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/snakebelmont.com"; | ||||
|     }; | ||||
|  | ||||
|     virtualHosts."purr.eversole.co" = { | ||||
|       enableACME = true; | ||||
|       forceSSL = true; | ||||
|       root = "/var/www/purr.eversole.co"; | ||||
|       locations."/".proxyPass = "http://192.168.0.130:5195"; | ||||
|     }; | ||||
|  | ||||
|   }; | ||||
| } | ||||
|  | ||||
| @ -47,10 +47,11 @@ | ||||
|                 ./monitoring/promtail.nix | ||||
|  | ||||
|                 ./system/age.nix | ||||
|                 ./system/dns.nix | ||||
|                 ./system/hardware.nix | ||||
|                 ./system/nix-conf.nix | ||||
|                 ./system/security.nix | ||||
|                 ./system/services.nix | ||||
|                 ./system/build-services.nix | ||||
|                 ./system/system.nix | ||||
|                 ./system/virtualisation.nix | ||||
|  | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
|   packages = { | ||||
|     x86_64-linux = { | ||||
|       deploy = pkgs.writeShellScriptBin "deploy" ''                                                                                                                                                                   | ||||
|         nixos-rebuild switch --target-host root@matri.cx --build-host root@matri.cx --flake .#eve-psr-nix0 ; | ||||
|         nixos-rebuild switch --target-host root@192.168.0.130 --build-host root@192.168.0.130 --flake .#eve-psr-nix0 ; | ||||
|       ''; | ||||
|       format = pkgs.writeShellScriptBin "format" ''                                                                                                                                                                   | ||||
|         nix fmt ./*.nix;                                                                                                                                                                                              | ||||
|  | ||||
| @ -1,11 +1,9 @@ | ||||
| { config, ... }: { | ||||
|   services = { | ||||
|     openssh = { enable = true; }; | ||||
| 
 | ||||
|     hydra = { | ||||
|       enable = true; | ||||
|       hydraURL = "https://hydra.matri.cx"; | ||||
|       listenHost = "192.168.0.130"; | ||||
|       listenHost = "127.0.0.1"; | ||||
|       port = 3034; | ||||
| 
 | ||||
|       extraConfig = '' | ||||
							
								
								
									
										17
									
								
								system/dns.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								system/dns.nix
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| { config, ... }: { | ||||
|   services = { | ||||
|     coredns.enable = true; | ||||
|     coredns.config = '' | ||||
|       		  . { | ||||
|       		    forward . 9.9.9.9 149.112.112.112 84.200.69.80 84.200.70.40 | ||||
|       		    cache | ||||
|       		  } | ||||
|       		 | ||||
|       		  matri.cx { | ||||
|       		    template IN A  { | ||||
|       		        answer "{{ .Name }} 0 IN A 192.168.0.130" | ||||
|       		    } | ||||
|       		  } | ||||
|       		''; | ||||
|   }; | ||||
| } | ||||
| @ -1,37 +1,38 @@ | ||||
| # Do not modify this file!  It was generated by ‘nixos-generate-config’ | ||||
| # and may be overwritten by future invocations.  Please make changes | ||||
| # to /etc/nixos/configuration.nix instead. | ||||
| { config, lib, pkgs, modulesPath, ... }: | ||||
|  | ||||
| { | ||||
|   imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; | ||||
|  | ||||
|   boot.initrd.availableKernelModules = | ||||
|     [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" "sdhci_pci" ]; | ||||
|   boot.initrd.kernelModules = [ ]; | ||||
|   boot.kernelModules = [ "kvm-intel" ]; | ||||
|   boot.extraModulePackages = [ ]; | ||||
|  | ||||
|   fileSystems."/" = { | ||||
|     device = "/dev/disk/by-label/NIXROOT"; | ||||
|     fsType = "ext4"; | ||||
|   boot = { | ||||
|     initrd = { | ||||
|       availableKernelModules = | ||||
|         [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" "sdhci_pci" ]; | ||||
|       kernelModules = [ ]; | ||||
|     }; | ||||
|     kernelModules = [ "kvm-intel" ]; | ||||
|     extraModulePackages = [ ]; | ||||
|   }; | ||||
|  | ||||
|   fileSystems."/boot" = { | ||||
|     device = "/dev/disk/by-label/NIXBOOT"; | ||||
|     fsType = "vfat"; | ||||
|   fileSystems = { | ||||
|     "/" = { | ||||
|       device = "/dev/disk/by-label/NIXROOT"; | ||||
|       fsType = "ext4"; | ||||
|     }; | ||||
|  | ||||
|     "/mnt/data" = { | ||||
|       device = "/dev/disk/by-label/SDA-EXT"; | ||||
|       fsType = "ext4"; | ||||
|     }; | ||||
|  | ||||
|     "/boot" = { | ||||
|       device = "/dev/disk/by-label/NIXBOOT"; | ||||
|       fsType = "vfat"; | ||||
|     }; | ||||
|   }; | ||||
|  | ||||
|   swapDevices = [ ]; | ||||
|  | ||||
|   # Enables DHCP on each ethernet and wireless interface. In case of scripted networking | ||||
|   # (the default) this is the recommended approach. When using systemd-networkd it's | ||||
|   # still possible to use this option, but it's recommended to use it in conjunction | ||||
|   # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`. | ||||
|   networking.useDHCP = lib.mkDefault true; | ||||
|   # networking.interfaces.eno1.useDHCP = lib.mkDefault true; | ||||
|   # networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true; | ||||
|  | ||||
|   nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; | ||||
|   powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; | ||||
|   hardware.cpu.intel.updateMicrocode = | ||||
|  | ||||
| @ -1,4 +1,7 @@ | ||||
| { ... }: { | ||||
|   services.openssh = { | ||||
|     enable = true; | ||||
|   }; | ||||
|   security = { | ||||
|     sudo.wheelNeedsPassword = false; | ||||
|     acme = { | ||||
|  | ||||
| @ -10,7 +10,7 @@ | ||||
|     hostName = "eve-psr-nix0"; | ||||
|     firewall = { | ||||
|       allowedTCPPorts = [ 22 80 443 ]; | ||||
|       allowedUDPPorts = [ 22 80 443 ]; | ||||
|       allowedUDPPorts = [ 22 80 443 53 ]; | ||||
|     }; | ||||
|   }; | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user