{ lib, pkgs, ... }: # Read configuration from JSON let jsonConfig = builtins.fromJSON (builtins.readFile ./config.json); in { imports = [ ./disko-config.nix ./hardware-configuration.nix ]; # Enable flakes and nix commands nix = { settings = { experimental-features = ["nix-command" "flakes"]; # Enable automatic garbage collection auto-optimise-store = true; trusted-users = [jsonConfig.username]; }; # Automatic cleanup of old generations gc = { automatic = true; dates = "weekly"; options = "--delete-older-than 30d"; }; }; # Boot configuration boot.loader.grub = { enable = true; devices = ["/dev/sda"]; efiSupport = true; efiInstallAsRemovable = true; }; # Networking networking = { firewall = { enable = true; # Only allow necessary ports allowedTCPPorts = [80 443 2222]; # HTTP, HTTPS, and SSH }; }; environment.etc = { environment-files = { source = pkgs.copyPathToStore ./env; }; }; # System packages environment.systemPackages = with pkgs; [ # System utilities neovim git # Docker tools docker docker-compose ]; # Enable Docker with recommended settings virtualisation.docker = { enable = true; # Enable docker daemon to start on boot enableOnBoot = true; # Use overlay2 storage driver storageDriver = "overlay2"; # Enable live restore liveRestore = true; }; # Services configuration services = { # SSH server configuration openssh = { enable = true; settings = { PermitRootLogin = "no"; PasswordAuthentication = false; # Additional security settings MaxAuthTries = 3; LoginGraceTime = "30s"; }; ports = [2222]; }; # Caddy configuration with security headers caddy = { enable = true; virtualHosts = { "${jsonConfig.domains.portainer}" = { extraConfig = '' reverse_proxy localhost:9000 header { # Security headers Strict-Transport-Security "max-age=31536000; includeSubDomains" X-Content-Type-Options "nosniff" X-Frame-Options "DENY" Referrer-Policy "strict-origin-when-cross-origin" } ''; }; "${jsonConfig.domains.n8n}" = { extraConfig = '' reverse_proxy localhost:5678 header { Strict-Transport-Security "max-age=31536000; includeSubDomains" X-Content-Type-Options "nosniff" X-Frame-Options "DENY" Referrer-Policy "strict-origin-when-cross-origin" } ''; }; "${jsonConfig.domains.baserow}" = { extraConfig = '' reverse_proxy localhost:3000 header { Strict-Transport-Security "max-age=31536000; includeSubDomains" X-Content-Type-Options "nosniff" X-Frame-Options "DENY" Referrer-Policy "strict-origin-when-cross-origin" } ''; }; }; }; }; # User configuration users.users.${jsonConfig.username} = { isNormalUser = true; extraGroups = ["wheel" "docker"]; hashedPassword = jsonConfig.hashedPassword; openssh.authorizedKeys.keys = [jsonConfig.sshKey]; # Set default shell to bash shell = pkgs.bash; }; # Container configurations virtualisation.oci-containers = { backend = "docker"; containers = { "portainer" = { image = "docker.io/portainer/portainer-ce:latest"; ports = ["127.0.0.1:9000:9000"]; volumes = [ "/etc/localtime:/etc/localtime:ro" "/var/run/docker.sock:/var/run/docker.sock:ro" "portainer_data:/data" ]; extraOptions = [ "--network=web" ]; }; "n8n" = { image = "docker.io/n8nio/n8n:latest"; environmentFiles = ["/etc/environment-files/n8n.env"]; ports = ["127.0.0.1:5678:5678"]; volumes = ["n8n_data:/home/node/.n8n"]; extraOptions = ["--network=web"]; }; "baserow" = { image = "docker.io/baserow/baserow:1.30.1"; environmentFiles = ["/etc/environment-files/baserow.env"]; ports = ["127.0.0.1:3000:80"]; volumes = ["baserow_data:/baserow/data"]; extraOptions = ["--network=web"]; }; }; }; system.activationScripts.mkVPN = '' ${pkgs.docker}/bin/docker network create web ''; # System state version (do not change) system.stateVersion = "24.11"; }