{ config, pkgs, lib, ... }: # Portable system + service config. Contains NO bootloader or filesystem # settings, so it can be reused by both the real host (configuration.nix) # and the VirtualBox test image (see flake.nix). { # ---- Networking ---- networking.hostName = "jupiter"; networking.networkmanager.enable = true; networking.firewall = { enable = true; allowedTCPPorts = [ 22 # ssh 445 139 # samba 80 443 # reverse proxy (caddy) ]; }; # ---- Locale / time ---- time.timeZone = "Europe/Berlin"; i18n.defaultLocale = "en_US.UTF-8"; # ---- Users ---- users.users.darman = { isNormalUser = true; description = "darman"; extraGroups = [ "wheel" "networkmanager" "docker" ]; # Replace with your real public key. Password login for ssh is disabled below. openssh.authorizedKeys.keys = [ # "ssh-ed25519 AAAA... darman@laptop" ]; }; security.sudo.wheelNeedsPassword = false; # ---- SSH ---- services.openssh = { enable = true; settings = { PasswordAuthentication = false; PermitRootLogin = "no"; }; }; # ---- Storage / NAS ---- services.samba = { enable = true; openFirewall = true; settings = { global = { "workgroup" = "WORKGROUP"; "server string" = "jupiter"; "security" = "user"; }; data = { "path" = "/mnt/data"; "browseable" = "yes"; "read only" = "no"; "guest ok" = "no"; "valid users" = "darman"; }; }; }; # Samba keeps its own NTLM password DB, separate from the system password. # `services.samba` never sets it, so logins fail until provisioned. # This runs AFTER samba-smbd so its state dir (/var/lib/samba/private) exists # — an activation script runs too early and smbpasswd fails to init the passdb. # The secret file must contain the password twice (new + confirm), one per line. # VM test: vm.nix writes /etc/samba/smb-password with a throwaway value. # Real host: supply it via sops-nix/agenix — do NOT commit plaintext. systemd.services.samba-smbpasswd = { description = "Provision Samba password for darman"; after = [ "samba-smbd.service" ]; requires = [ "samba-smbd.service" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; }; script = '' if [ -f /etc/samba/smb-password ]; then ${pkgs.samba}/bin/smbpasswd -a -s darman < /etc/samba/smb-password fi ''; }; services.avahi = { enable = true; nssmdns4 = true; publish = { enable = true; userServices = true; }; }; # ---- Containers ---- virtualisation.podman = { enable = true; dockerCompat = true; defaultNetwork.settings.dns_enabled = true; }; virtualisation.oci-containers = { backend = "podman"; containers = { whoami = { image = "traefik/whoami:latest"; ports = [ "8080:80" ]; autoStart = true; }; }; }; # ---- Reverse proxy ---- # Caddy binds nothing unless it has a vhost. This proxies the whoami # container so :80 actually serves. Add one block per service. # Real host: swap `http://localhost` for your domain to get automatic HTTPS, # e.g. `services.caddy.virtualHosts."jelly.example.com".extraConfig`. services.caddy = { enable = true; virtualHosts."http://localhost".extraConfig = '' reverse_proxy localhost:8080 ''; }; # ---- System packages ---- environment.systemPackages = with pkgs; [ vim git htop tmux curl ]; # ---- Nix settings ---- nix.settings.experimental-features = [ "nix-command" "flakes" ]; nix.gc = { automatic = true; dates = "weekly"; options = "--delete-older-than 30d"; }; system.stateVersion = "26.05"; }