Nix-Vibe public snapshot (squashed history)
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
# /hosts/nixos/configuration.nix
|
||||
{ config
|
||||
, pkgs
|
||||
, inputs
|
||||
, lib
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
../../modules/core/common.nix
|
||||
../../modules/desktop/gui.nix
|
||||
(import ../../modules/storage/disko.nix {
|
||||
inherit inputs lib config;
|
||||
diskoConfigPath = ./disko-config.nix;
|
||||
})
|
||||
../../modules/desktop/gnome.nix
|
||||
../../modules/desktop/apps/soundux.nix
|
||||
../../modules/desktop/apps/freeshow.nix
|
||||
../../modules/core/management.nix
|
||||
../../modules/hardware/laptop.nix
|
||||
../../modules/core/dev.nix
|
||||
];
|
||||
|
||||
sops.secrets = {
|
||||
"users/petere-password" = {
|
||||
neededForUsers = true;
|
||||
};
|
||||
"users/caitlin-password" = {
|
||||
neededForUsers = true;
|
||||
};
|
||||
};
|
||||
|
||||
services.displayManager.gdm.settings = {
|
||||
"greeter" = {
|
||||
"Exclude" = "petere";
|
||||
};
|
||||
};
|
||||
|
||||
home-manager.users.caitlin.imports = [
|
||||
../../home-manager/modules/desktop-user.nix
|
||||
];
|
||||
|
||||
networking.hostName = "caitlin-x1";
|
||||
networking.modemmanager.enable = true;
|
||||
|
||||
# Laptop-specific hardware (fingerprint reader, fwupd)
|
||||
my.hardware.laptop.enable = true;
|
||||
|
||||
hardware.sensor.iio.enable = true;
|
||||
|
||||
users.users.caitlin = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "wheel" ];
|
||||
hashedPasswordFile = config.sops.secrets."users/caitlin-password".path;
|
||||
subUidRanges = [
|
||||
{
|
||||
startUid = 100000;
|
||||
count = 65536;
|
||||
}
|
||||
];
|
||||
subGidRanges = [
|
||||
{
|
||||
startGid = 100000;
|
||||
count = 65536;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.openssh.enable = true;
|
||||
|
||||
my.users.petere = {
|
||||
hashedPasswordFile = config.sops.secrets."users/petere-password".path;
|
||||
subUidStart = 165536;
|
||||
subGidStart = 165536;
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
xournalpp
|
||||
prismlauncher
|
||||
jdk21
|
||||
rclone
|
||||
steam
|
||||
];
|
||||
|
||||
hardware.graphics.enable = true;
|
||||
programs.steam.enable = true;
|
||||
|
||||
# Allow Steam to use 32-bit libraries
|
||||
programs.steam.package = pkgs.steam.override {
|
||||
extraLibraries = ps: [ ];
|
||||
};
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
# /hosts/x1carbon/disko-config.nix
|
||||
# This file will contain your disko configuration for x1carbon.
|
||||
{
|
||||
disk = {
|
||||
nixos = {
|
||||
type = "disk";
|
||||
device = "/dev/nvme0n1";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
size = "1M";
|
||||
type = "EF02"; # for grub MBR
|
||||
};
|
||||
ESP = {
|
||||
size = "512M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
swap = {
|
||||
size = "20G";
|
||||
type = "8200";
|
||||
content = {
|
||||
type = "swap";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
# /hosts/x1carbon/hardware-configuration.nix
|
||||
# This file will be generated by NixOS during installation or by 'nixos-generate-config'.
|
||||
# It contains hardware-specific settings for x1carbon.
|
||||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, modulesPath
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
#hardware.ipu6.enable = true;
|
||||
#hardware.ipu6.platform = "ipu6";
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"nvme"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
# fileSystems."/" =
|
||||
# { device = "/dev/disk/by-uuid/882a76d6-c1ac-4efd-aff8-b56d43ec7ca5";
|
||||
# fsType = "ext4";
|
||||
# };
|
||||
|
||||
# fileSystems."/boot" =
|
||||
# { device = "/dev/disk/by-uuid/EF30-EBA7";
|
||||
# fsType = "vfat";
|
||||
# options = [ "fmask=0077" "dmask=0077" ];
|
||||
# };
|
||||
|
||||
# swapDevices =
|
||||
# [ { device = "/dev/disk/by-uuid/1c488737-a2e7-4258-b0f3-bd1d14155d03"; }
|
||||
# ];
|
||||
|
||||
# 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.enp0s31f6.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
# NixOS configuration for homeserver-1
|
||||
# Headless server environment (Command Line Interface only)
|
||||
|
||||
{ config
|
||||
, pkgs
|
||||
, lib
|
||||
, inputs
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
../../modules/core/common.nix
|
||||
(import ../../modules/storage/disko.nix {
|
||||
inherit inputs lib config;
|
||||
diskoConfigPath = ./disko-config.nix;
|
||||
})
|
||||
./hardware-configuration.nix
|
||||
../../modules/core/management.nix
|
||||
../../modules/core/podman.nix
|
||||
../../modules/hardware/nvidia.nix
|
||||
../../modules/core/known-hosts.nix
|
||||
../../modules/services/immich.nix
|
||||
../../modules/services/jellyfin.nix
|
||||
../../modules/services/backrest.nix
|
||||
../../modules/services/homepage.nix
|
||||
../../modules/services/gitea.nix
|
||||
./homepage.nix
|
||||
];
|
||||
|
||||
services.backrest = {
|
||||
enable = true;
|
||||
host = "0.0.0.0";
|
||||
port = 9898;
|
||||
dataDir = "/data/backrest";
|
||||
};
|
||||
|
||||
systemd.services.backrest = {
|
||||
after = [ "restic-ssh-key-format.service" ];
|
||||
wants = [ "restic-ssh-key-format.service" ];
|
||||
};
|
||||
|
||||
# Allow backrest to read backup source directories recursively.
|
||||
# Uses ACLs with a default mask so newly created files also inherit access.
|
||||
# Runs after immich and the postgresql backup so the dirs/files exist.
|
||||
systemd.services.backrest-permissions = {
|
||||
description = "Grant backrest read access to backup source dirs";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [
|
||||
"immich-server.service"
|
||||
"postgresqlBackup-immich.service"
|
||||
];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = ''
|
||||
# Recursive read+execute ACL for backrest on immich media
|
||||
${pkgs.acl}/bin/setfacl -R -m u:backrest:rx -m m::r-x /data/immich
|
||||
# Default ACL so future immich files are readable by backrest
|
||||
${pkgs.acl}/bin/setfacl -R -m d:u:backrest:rx -m d:m::r-x /data/immich
|
||||
# Recursive read for backrest on postgresql backups
|
||||
${pkgs.acl}/bin/setfacl -R -m u:backrest:rx -m m::r-x /data/backup/postgresql
|
||||
${pkgs.acl}/bin/setfacl -R -m d:u:backrest:rx -m d:m::r-x /data/backup/postgresql
|
||||
# Recursive read for backrest on gitea (repos + dump)
|
||||
${pkgs.acl}/bin/setfacl -R -m u:backrest:rx -m m::r-x /data/gitea
|
||||
${pkgs.acl}/bin/setfacl -R -m d:u:backrest:rx -m d:m::r-x /data/gitea
|
||||
'';
|
||||
};
|
||||
|
||||
services.immich-server = {
|
||||
enable = true;
|
||||
port = 2283;
|
||||
mediaLocation = "/data/immich";
|
||||
};
|
||||
|
||||
services.jellyfin-server = {
|
||||
enable = true;
|
||||
port = 8096;
|
||||
mediaLocation = "/data/jellyfin";
|
||||
};
|
||||
|
||||
# Gitea git server. Public at https://gitea.edley.me via an external reverse
|
||||
# proxy (TLS terminator) that reaches us over Tailscale. Only that proxy's
|
||||
# Tailscale IP is allowed through the firewall (see modules/services/gitea.nix).
|
||||
services.gitea-server = {
|
||||
enable = true;
|
||||
port = 3000;
|
||||
domain = "gitea.edley.me";
|
||||
proxyIp = "100.109.85.40";
|
||||
};
|
||||
|
||||
services.postgresqlBackup = {
|
||||
enable = true;
|
||||
databases = [
|
||||
"immich"
|
||||
"gitea"
|
||||
];
|
||||
location = "/data/backup/postgresql";
|
||||
compression = "zstd";
|
||||
startAt = "weekly";
|
||||
};
|
||||
|
||||
# The services.postgresqlBackup module creates a tmpfiles `d` rule that sets
|
||||
# the backup directory to 0700 on every rebuild/switch. On a directory with
|
||||
# POSIX ACLs, `chmod 0700` resets the ACL mask to `---`, which nullifies the
|
||||
# `user:backrest` read ACL that backrest uses to back up these dumps. Override
|
||||
# the mode so rebuilds keep the directory group-traversable (mask stays rx).
|
||||
# Note: systemd-tmpfiles dedupes conflicting rules and keeps the FIRST one for
|
||||
# a path, so our override must appear before the module's rule.
|
||||
systemd.tmpfiles.rules = lib.mkBefore [
|
||||
"d /data/backup/postgresql 0750 postgres - - -"
|
||||
];
|
||||
|
||||
sops.secrets = {
|
||||
"users/petere-password" = {
|
||||
neededForUsers = true;
|
||||
};
|
||||
"pocket-id-env" = {
|
||||
neededForUsers = false;
|
||||
};
|
||||
"homeserver-1/restic-passphrase" = { };
|
||||
"homeserver-1/restic-ssh-key" = { };
|
||||
"homeserver-1/homepage-env" = { };
|
||||
"homeserver-1/samba-petere-password" = { };
|
||||
};
|
||||
|
||||
# Set petere's Samba password from SOPS at boot. Samba keeps its own password
|
||||
# database (smbpasswd/tdbsam), separate from Linux login, so this must run
|
||||
# smbpasswd. Idempotent: re-applied on every boot from the secret.
|
||||
systemd.services.samba-set-petere-password = {
|
||||
description = "Set petere's Samba password from SOPS";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "sops-nix.service" ];
|
||||
before = [ "samba-smbd.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
PASS="$(cat ${config.sops.secrets."homeserver-1/samba-petere-password".path})"
|
||||
${pkgs.samba}/bin/smbpasswd -s -a petere <<EOF
|
||||
$PASS
|
||||
$PASS
|
||||
EOF
|
||||
'';
|
||||
};
|
||||
|
||||
# Install the restic SSH key (stored multi-line in sops) and set up SSH access
|
||||
# for the backrest user so restic can reach mcf-server.
|
||||
# Writes to a persistent location (NOT /run) because sops-nix clears /run/secrets.
|
||||
systemd.services.restic-ssh-key-format = {
|
||||
description = "Install restic SSH key and configure SSH for backrest";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "sops-nix.service" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = ''
|
||||
KEY_FILE="${config.sops.secrets."homeserver-1/restic-ssh-key".path}"
|
||||
FORMATTED="/data/backrest/restic-ssh-key"
|
||||
${pkgs.coreutils}/bin/install -m 640 -o root -g backrest "$KEY_FILE" "$FORMATTED"
|
||||
|
||||
# SSH config for backrest so restic (via Backrest) uses the correct key
|
||||
mkdir -p /data/backrest/.ssh
|
||||
cat > /data/backrest/.ssh/config <<EOF
|
||||
Host mcf-server
|
||||
HostName mcf-server
|
||||
User restic-homeserver1
|
||||
IdentityFile /data/backrest/restic-ssh-key
|
||||
IdentitiesOnly yes
|
||||
Host richmond-server
|
||||
HostName richmond-server
|
||||
User restic-homeserver1
|
||||
IdentityFile /data/backrest/restic-ssh-key
|
||||
IdentitiesOnly yes
|
||||
EOF
|
||||
chown -R backrest:backrest /data/backrest/.ssh
|
||||
chmod 700 /data/backrest/.ssh
|
||||
chmod 600 /data/backrest/.ssh/config
|
||||
'';
|
||||
};
|
||||
|
||||
networking.hostName = "homeserver-1";
|
||||
|
||||
# SSH configuration
|
||||
services.openssh.enable = true;
|
||||
|
||||
# Trusted host keys for restic backup targets (via Backrest).
|
||||
my.knownHosts = {
|
||||
mcfServer = true;
|
||||
richmondServer = true;
|
||||
};
|
||||
|
||||
# Glances system monitor - exposed to the tailnet so the Homepage
|
||||
# dashboard can display real-time stats for this machine (localhost).
|
||||
services.glances = {
|
||||
enable = true;
|
||||
port = 61208;
|
||||
extraArgs = [ "--webserver" ];
|
||||
};
|
||||
|
||||
# Expose services on Tailscale only (not the LAN).
|
||||
# Immich (2283): accessed via nginx proxy on another machine over Tailscale.
|
||||
# Backrest (9898), Pocket ID (8443), Homepage (8082), Glances (61208): admin services.
|
||||
networking.firewall.interfaces.tailscale.allowedTCPPorts = lib.mkAfter [
|
||||
2283 # Immich
|
||||
8443 # Pocket ID
|
||||
9898 # Backrest
|
||||
8082 # Homepage
|
||||
61208 # Glances
|
||||
];
|
||||
|
||||
# Add Pocket ID package for tooling
|
||||
environment.systemPackages = with pkgs; [ pocket-id ];
|
||||
|
||||
# Pocket ID service configuration
|
||||
services.pocket-id = {
|
||||
enable = true;
|
||||
environmentFile = config.sops.secrets."pocket-id-env".path;
|
||||
settings = {
|
||||
APP_URL = "https://homeserver-1.gerbil-opah.ts.net:8443";
|
||||
PORT = 8443;
|
||||
TRUST_PROXY = true;
|
||||
TLS_CERT_FILE = "/etc/ssl/certs/pocket-id.crt";
|
||||
TLS_KEY_FILE = "/etc/ssl/private/pocket-id.key";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.pocket-id = {
|
||||
wants = [ "pocket-id-tailscale-cert.service" ];
|
||||
after = [ "pocket-id-tailscale-cert.service" ];
|
||||
};
|
||||
|
||||
# Systemd service to obtain TLS cert via Tailscale
|
||||
systemd.services.pocket-id-tailscale-cert = {
|
||||
description = "Obtain TLS cert for Pocket-ID via Tailscale";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [
|
||||
"network-online.target"
|
||||
"tailscaled.service"
|
||||
];
|
||||
after = [
|
||||
"network-online.target"
|
||||
"tailscaled.service"
|
||||
];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = pkgs.writeShellScript "get-tailscale-cert" ''
|
||||
set -eu
|
||||
mkdir -p /etc/ssl/certs /etc/ssl/private
|
||||
if [ ! -f /etc/ssl/certs/pocket-id.crt ] || [ ! -f /etc/ssl/private/pocket-id.key ]; then
|
||||
${pkgs.tailscale}/bin/tailscale cert --cert-file /etc/ssl/certs/pocket-id.crt --key-file /etc/ssl/private/pocket-id.key homeserver-1.gerbil-opah.ts.net
|
||||
fi
|
||||
chown root:pocket-id /etc/ssl/private/pocket-id.key
|
||||
chmod 640 /etc/ssl/private/pocket-id.key
|
||||
chmod 644 /etc/ssl/certs/pocket-id.crt
|
||||
'';
|
||||
User = "root";
|
||||
Group = "root";
|
||||
};
|
||||
};
|
||||
|
||||
# NVIDIA GPU Configuration for GeForce GTX 960 (Maxwell GM206)
|
||||
my.hardware.nvidia = {
|
||||
enable = true;
|
||||
# GTX 960 (Maxwell) needs the 580.xx legacy driver branch; the default
|
||||
# driver no longer supports it (NVRM: No NVIDIA GPU found).
|
||||
package = config.boot.kernelPackages.nvidiaPackages.legacy_580;
|
||||
};
|
||||
|
||||
boot.kernelModules = [ "sg" ];
|
||||
|
||||
# Root account is locked (no password login); access is via SSH key + sudo.
|
||||
users.users.root.hashedPassword = "!";
|
||||
|
||||
# Standard user account (shared definition in modules/core/users.nix)
|
||||
my.users.petere = {
|
||||
hashedPasswordFile = config.sops.secrets."users/petere-password".path;
|
||||
};
|
||||
|
||||
# Trusted users for Nix operations
|
||||
nix.settings.trusted-users = [
|
||||
"root"
|
||||
"petere"
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
{
|
||||
disk = {
|
||||
main = {
|
||||
type = "disk";
|
||||
device = "/dev/nvme0n1";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
size = "1M";
|
||||
type = "EF02"; # for GRUB MBR fallback
|
||||
};
|
||||
ESP = {
|
||||
size = "512M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
data1 = {
|
||||
type = "disk";
|
||||
device = "/dev/sda";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
data = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "btrfs";
|
||||
extraArgs = [ "-f" ];
|
||||
mountOptions = [
|
||||
"defaults"
|
||||
"nofail"
|
||||
];
|
||||
mountpoint = "/data";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
data2 = {
|
||||
type = "disk";
|
||||
device = "/dev/sdb";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
data = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "btrfs";
|
||||
extraArgs = [ "-f" ];
|
||||
postCreateHook = ''
|
||||
btrfs device add -f /dev/disk/by-partlabel/disk-data2-data /mnt/data || true
|
||||
btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt/data || true
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, modulesPath
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"nvme"
|
||||
"xhci_pci"
|
||||
"ahci"
|
||||
"usb_storage"
|
||||
"usbhid"
|
||||
"sd_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.supportedFilesystems = [
|
||||
"btrfs"
|
||||
"ext4"
|
||||
"vfat"
|
||||
];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -0,0 +1,524 @@
|
||||
# Homepage dashboard (gethomepage.dev) configuration for homeserver-1
|
||||
#
|
||||
# This file holds the full dashboard definition (settings, services, widgets).
|
||||
# It is imported by configuration.nix. Edit this file to change what the
|
||||
# dashboard shows, then run:
|
||||
# nixos-rebuild switch --target-host petere@homeserver-1 --flake .#homeserver-1 --use-remote-sudo
|
||||
|
||||
{ config
|
||||
, lib
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
# Build a Tailscale widget tile for the Tailnet tab. Shared so the
|
||||
# highlight rules (expiry / last-seen) are defined once.
|
||||
# Returns a service entry: { "<name>" = { icon; href; description; widget; } }
|
||||
tailscaleTile = name: deviceid: description: {
|
||||
${name} = {
|
||||
icon = "sh-tailscale";
|
||||
href = "https://login.tailscale.com/admin/machines";
|
||||
inherit description;
|
||||
widget = {
|
||||
type = "tailscale";
|
||||
inherit deviceid;
|
||||
key = "{{HOMEPAGE_VAR_TAILSCALE_API_KEY}}";
|
||||
# Highlight rules match the rendered field values (e.g. "24w", "Never",
|
||||
# "8h Ago", "2w Ago"). Warn = expiring within a week, danger = offline >24h.
|
||||
highlight = {
|
||||
expires = {
|
||||
string = [
|
||||
{
|
||||
level = "warn";
|
||||
when = "regex";
|
||||
# 1-7 days, or hours/minutes/seconds remaining (i.e. within a week)
|
||||
value = "^\\d+[dhms]$";
|
||||
}
|
||||
];
|
||||
};
|
||||
last_seen = {
|
||||
string = [
|
||||
{
|
||||
level = "danger";
|
||||
when = "regex";
|
||||
# days/weeks/years ago (i.e. not seen for more than 24 hours)
|
||||
value = "^\\d+[dwy] Ago$";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
services.homepage = {
|
||||
enable = true;
|
||||
port = 8082;
|
||||
allowedHosts = [
|
||||
"localhost"
|
||||
"127.0.0.1"
|
||||
"homeserver-1"
|
||||
"homeserver-1.gerbil-opah.ts.net"
|
||||
];
|
||||
openFirewall = false; # Exposed on Tailscale only (see firewall in configuration.nix)
|
||||
|
||||
# API keys / secrets for service widgets (HOMEPAGE_VAR_* vars)
|
||||
environmentFiles = [ config.sops.secrets."homeserver-1/homepage-env".path ];
|
||||
|
||||
settings = {
|
||||
title = "HomeServer";
|
||||
language = "en";
|
||||
theme = "dark";
|
||||
color = "slate";
|
||||
statusStyle = "dot";
|
||||
# Tabs: each layout group's `tab` value controls which tab it appears on.
|
||||
# Groups without a `tab` (or with no layout entry) show on every tab.
|
||||
layout = {
|
||||
# ---- Monitoring tab ----
|
||||
"Homeserver-1 Monitoring" = {
|
||||
tab = "Monitoring";
|
||||
style = "row";
|
||||
columns = 1;
|
||||
"HS1 System" = {
|
||||
style = "row";
|
||||
columns = 2;
|
||||
};
|
||||
"HS1 Disks" = {
|
||||
style = "row";
|
||||
columns = 2; # NVMe + SDA side by side
|
||||
};
|
||||
};
|
||||
"MCF Server Monitoring" = {
|
||||
tab = "Monitoring";
|
||||
style = "row";
|
||||
columns = 1;
|
||||
"MCF System" = {
|
||||
style = "row";
|
||||
columns = 2;
|
||||
};
|
||||
"MCF Disks" = {
|
||||
style = "row";
|
||||
columns = 2; # SDB (system) + SDA (data) side by side
|
||||
};
|
||||
};
|
||||
"Richmond Server Monitoring" = {
|
||||
tab = "Monitoring";
|
||||
style = "row";
|
||||
columns = 1;
|
||||
"Richmond System" = {
|
||||
style = "row";
|
||||
columns = 2;
|
||||
};
|
||||
"Richmond Disks" = {
|
||||
style = "row";
|
||||
columns = 2; # SDB (system) + SDA (data) side by side
|
||||
};
|
||||
};
|
||||
# ---- Homeserver-1 tab ----
|
||||
Media = {
|
||||
tab = "Homeserver-1";
|
||||
style = "row";
|
||||
columns = 2;
|
||||
};
|
||||
System = {
|
||||
tab = "Homeserver-1";
|
||||
style = "row";
|
||||
columns = 3;
|
||||
};
|
||||
# ---- MCF Server tab (populate with future mcf-server services) ----
|
||||
# "MCF Server Apps" = {
|
||||
# tab = "MCF Server";
|
||||
# style = "row";
|
||||
# columns = 4;
|
||||
# };
|
||||
# ---- Richmond Server tab ----
|
||||
"Richmond Server Apps" = {
|
||||
tab = "Richmond Server";
|
||||
style = "row";
|
||||
columns = 3;
|
||||
};
|
||||
# ---- Tailnet tab (one Tailscale widget per machine) ----
|
||||
Tailnet = {
|
||||
tab = "Tailnet";
|
||||
style = "row";
|
||||
columns = 3;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services = [
|
||||
{
|
||||
"Homeserver-1 Monitoring" = [
|
||||
{
|
||||
"HS1 System" = [
|
||||
{
|
||||
"System" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://127.0.0.1:61208";
|
||||
version = 4; # Glances v4.x
|
||||
metric = "info";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"CPU" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://127.0.0.1:61208";
|
||||
version = 4;
|
||||
metric = "cpu";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"Memory" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://127.0.0.1:61208";
|
||||
version = 4;
|
||||
metric = "memory";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"Processes" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://127.0.0.1:61208";
|
||||
version = 4;
|
||||
metric = "process";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
"HS1 Disks" = [
|
||||
{
|
||||
"NVMe - System" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://127.0.0.1:61208";
|
||||
version = 4;
|
||||
metric = "disk:nvme0n1";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"SDA - Data" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://127.0.0.1:61208";
|
||||
version = 4;
|
||||
metric = "disk:sda";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
"MCF Server Monitoring" = [
|
||||
{
|
||||
"MCF System" = [
|
||||
{
|
||||
"System" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://mcf-server.gerbil-opah.ts.net:61208";
|
||||
version = 4; # Glances v4.x
|
||||
metric = "info";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"CPU" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://mcf-server.gerbil-opah.ts.net:61208";
|
||||
version = 4;
|
||||
metric = "cpu";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"Memory" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://mcf-server.gerbil-opah.ts.net:61208";
|
||||
version = 4;
|
||||
metric = "memory";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"Processes" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://mcf-server.gerbil-opah.ts.net:61208";
|
||||
version = 4;
|
||||
metric = "process";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
"MCF Disks" = [
|
||||
{
|
||||
"SDB - System" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://mcf-server.gerbil-opah.ts.net:61208";
|
||||
version = 4;
|
||||
metric = "disk:sdb";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"SDA - Data" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://mcf-server.gerbil-opah.ts.net:61208";
|
||||
version = 4;
|
||||
metric = "disk:sda";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
"Richmond Server Monitoring" = [
|
||||
{
|
||||
"Richmond System" = [
|
||||
{
|
||||
"System" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://richmond-server.gerbil-opah.ts.net:61208";
|
||||
version = 4; # Glances v4.x
|
||||
metric = "info";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"CPU" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://richmond-server.gerbil-opah.ts.net:61208";
|
||||
version = 4;
|
||||
metric = "cpu";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"Memory" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://richmond-server.gerbil-opah.ts.net:61208";
|
||||
version = 4;
|
||||
metric = "memory";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"Processes" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://richmond-server.gerbil-opah.ts.net:61208";
|
||||
version = 4;
|
||||
metric = "process";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
"Richmond Disks" = [
|
||||
{
|
||||
"SDB - System" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://richmond-server.gerbil-opah.ts.net:61208";
|
||||
version = 4;
|
||||
metric = "disk:sdb";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"SDA - Data" = {
|
||||
widget = {
|
||||
type = "glances";
|
||||
url = "http://richmond-server.gerbil-opah.ts.net:61208";
|
||||
version = 4;
|
||||
metric = "disk:sda";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
Media = [
|
||||
{
|
||||
Jellyfin = {
|
||||
icon = "sh-jellyfin";
|
||||
href = "http://jellyfin.edley.me";
|
||||
description = "Movies & TV";
|
||||
siteMonitor = "http://127.0.0.1:8096";
|
||||
widget = {
|
||||
type = "jellyfin";
|
||||
url = "http://127.0.0.1:8096";
|
||||
key = "{{HOMEPAGE_VAR_JELLYFIN_API_KEY}}";
|
||||
enableBlocks = true;
|
||||
enableNowPlaying = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
Immich = {
|
||||
icon = "sh-immich";
|
||||
href = "http://immich.edley.me";
|
||||
description = "Photo & Video";
|
||||
siteMonitor = "http://127.0.0.1:2283";
|
||||
widget = {
|
||||
type = "immich";
|
||||
url = "http://127.0.0.1:2283";
|
||||
key = "{{HOMEPAGE_VAR_IMMICH_API_KEY}}";
|
||||
version = 2; # Immich >= 1.118
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
System = [
|
||||
{
|
||||
Backrest = {
|
||||
icon = "sh-backrest";
|
||||
href = "http://homeserver-1.gerbil-opah.ts.net:9898";
|
||||
description = "Restic backup UI";
|
||||
siteMonitor = "http://127.0.0.1:9898";
|
||||
widget = {
|
||||
type = "backrest";
|
||||
url = "http://127.0.0.1:9898";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"Pocket ID" = {
|
||||
icon = "sh-pocketbase";
|
||||
href = "https://homeserver-1.gerbil-opah.ts.net:8443";
|
||||
description = "SSO / Identity";
|
||||
};
|
||||
}
|
||||
{
|
||||
Gitea = {
|
||||
icon = "sh-gitea";
|
||||
href = "https://gitea.edley.me";
|
||||
description = "Git hosting";
|
||||
siteMonitor = "http://127.0.0.1:3000";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
# ---- MCF Server tab: add future mcf-server services here ----
|
||||
# {
|
||||
# "MCF Server Apps" = [
|
||||
# {
|
||||
# "MyApp" = {
|
||||
# icon = "sh-myservice";
|
||||
# href = "http://mcf-server.gerbil-opah.ts.net:<port>";
|
||||
# siteMonitor = "http://mcf-server.gerbil-opah.ts.net:<port>";
|
||||
# };
|
||||
# }
|
||||
# ];
|
||||
# }
|
||||
{
|
||||
"Richmond Server Apps" = [
|
||||
{
|
||||
PiHole = {
|
||||
icon = "sh-pihole";
|
||||
href = "http://richmond-server.gerbil-opah.ts.net/admin";
|
||||
description = "Network-wide ad blocking";
|
||||
siteMonitor = "http://richmond-server.gerbil-opah.ts.net";
|
||||
widget = {
|
||||
type = "pihole";
|
||||
url = "http://richmond-server.gerbil-opah.ts.net";
|
||||
version = 6; # Pi-hole v6
|
||||
key = "{{HOMEPAGE_VAR_PIHOLE_API_KEY}}";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
Castopod = {
|
||||
icon = "sh-castopod";
|
||||
href = "http://richmond-server.gerbil-opah.ts.net:8080";
|
||||
description = "Podcasting platform";
|
||||
siteMonitor = "http://richmond-server.gerbil-opah.ts.net:8080";
|
||||
};
|
||||
}
|
||||
{
|
||||
Ntfy = {
|
||||
icon = "sh-ntfy";
|
||||
href = "https://ntfy.edley.me";
|
||||
description = "Push notifications";
|
||||
siteMonitor = "http://richmond-server.gerbil-opah.ts.net:8085";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
# ---- Tailnet tab: one Tailscale widget per machine ----
|
||||
{
|
||||
Tailnet = [
|
||||
(tailscaleTile "Homeserver-1" "7629334038136604" "homeserver-1.gerbil-opah.ts.net")
|
||||
(tailscaleTile "MCF Server" "6531912398509392" "mcf-server.gerbil-opah.ts.net")
|
||||
(tailscaleTile "Richmond Server" "4591058654038528" "richmond-server.gerbil-opah.ts.net")
|
||||
(tailscaleTile "x1carbon" "3486385364789872" "x1carbon.gerbil-opah.ts.net")
|
||||
(tailscaleTile "x470" "210979648507396" "x470.gerbil-opah.ts.net")
|
||||
(tailscaleTile "caitlin-x1" "4406025993575891" "caitlin-x1.gerbil-opah.ts.net")
|
||||
(tailscaleTile "Mary Laptop" "5830538092696610" "mary-laptop.gerbil-opah.ts.net")
|
||||
(tailscaleTile "Pluto" "4170550062707667" "pluto.gerbil-opah.ts.net")
|
||||
(tailscaleTile "TheBorg" "2268885677960290" "theborg.gerbil-opah.ts.net")
|
||||
(tailscaleTile "Server" "3605859775136634" "server.gerbil-opah.ts.net")
|
||||
(tailscaleTile "Homeserver" "5665047953117744" "homeserver.gerbil-opah.ts.net")
|
||||
(tailscaleTile "MCF Projector" "5131578183597553" "mcf-projector.gerbil-opah.ts.net")
|
||||
(tailscaleTile "MCF Stream" "6804850380243723" "mcf-stream.gerbil-opah.ts.net")
|
||||
(tailscaleTile "Yoga 12" "1716848030756573" "yoga12.gerbil-opah.ts.net")
|
||||
(tailscaleTile "Pixel 9 Pro XL" "6766405315162342" "pixel-9-pro-xl.gerbil-opah.ts.net")
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
widgets = [
|
||||
{
|
||||
resources = {
|
||||
cpu = true;
|
||||
memory = true;
|
||||
disk = "/";
|
||||
};
|
||||
}
|
||||
{
|
||||
search = {
|
||||
provider = "duckduckgo";
|
||||
target = "_blank";
|
||||
};
|
||||
}
|
||||
{
|
||||
datetime = {
|
||||
text_size = "xl";
|
||||
locale = "en-GB"; # UK date format (dd/mm/yy)
|
||||
format = {
|
||||
dateStyle = "short";
|
||||
timeStyle = "short";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
# /hosts/hp-laptop/configuration.nix
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
inputs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
../../modules/core/common.nix
|
||||
../../modules/desktop/gui.nix
|
||||
(import ../../modules/storage/disko.nix {
|
||||
inherit inputs lib config;
|
||||
diskoConfigPath = ./disko-config.nix;
|
||||
})
|
||||
../../modules/desktop/hyprland.nix
|
||||
../../modules/core/management.nix
|
||||
../../modules/hardware/laptop.nix
|
||||
../../modules/hardware/hp-battery-limit.nix
|
||||
../../modules/core/dev.nix
|
||||
];
|
||||
|
||||
sops.secrets = {
|
||||
"users/petere-password" = {
|
||||
neededForUsers = true;
|
||||
};
|
||||
# Nextcloud CalDAV credentials for the QuickShell calendar popup
|
||||
# (vdirsyncer/khal sync). Values live in secrets.yaml under
|
||||
# hp-laptop/nextcloud-cal-env; sync runs as petere so it must be readable.
|
||||
"hp-laptop/nextcloud-cal-env" = {
|
||||
owner = "petere";
|
||||
group = "users";
|
||||
mode = "0440";
|
||||
};
|
||||
};
|
||||
|
||||
home-manager.users.petere.imports = [
|
||||
../../home-manager/modules/hyprland.nix
|
||||
../../home-manager/modules/quickshell-cal.nix
|
||||
../../home-manager/modules/quickshell-apps.nix
|
||||
];
|
||||
|
||||
home-manager.users.petere.services.quickshell-cal.enable = true;
|
||||
|
||||
# Autostart app pool (toggleable from the gear quick-settings panel).
|
||||
# The on/off choice is stored at runtime in
|
||||
# ~/.cache/quickshell/autostart.json - adding an app here just makes it
|
||||
# available as an (off by default) entry next time the panel loads.
|
||||
home-manager.users.petere.services.quickshell-apps = {
|
||||
enable = true;
|
||||
apps = [
|
||||
{
|
||||
name = "Element";
|
||||
cmd = "element-desktop";
|
||||
}
|
||||
{
|
||||
name = "Nextcloud";
|
||||
cmd = "nextcloud";
|
||||
}
|
||||
{
|
||||
name = "Bitwarden";
|
||||
cmd = "bitwarden";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
networking.hostName = "hp-laptop";
|
||||
|
||||
# Open legacy game-streaming ports.
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ 9756 ];
|
||||
allowedUDPPorts = [ 9999 ];
|
||||
};
|
||||
|
||||
# TeleportFling: standalone screen + audio sender for OBS Teleport.
|
||||
environment.systemPackages = [
|
||||
inputs.teleportfling.packages.${pkgs.system}.teleportfling-gui
|
||||
inputs.teleportfling.packages.${pkgs.system}.teleportfling
|
||||
];
|
||||
|
||||
# Laptop-specific hardware support (fingerprint reader, fwupd)
|
||||
my.hardware.laptop.enable = true;
|
||||
|
||||
# Charging cap at 80% (protect battery longevity). Board 81AD firmware lacks
|
||||
# a percentage threshold sysfs, so this runs SBCC/SBCO via acpi_call: a root
|
||||
# poller inhibits charge at 80% and re-enables auto below 75%. Toggleable
|
||||
# from the QuickShell gear panel (CHARGE LIMIT).
|
||||
my.hardware.hpBatteryLimit.enable = true;
|
||||
|
||||
# Intel integrated GPU (HP consumer laptops)
|
||||
hardware.graphics.enable = true;
|
||||
|
||||
my.users.petere = {
|
||||
description = "Peter Edley";
|
||||
hashedPasswordFile = config.sops.secrets."users/petere-password".path;
|
||||
subUidStart = 165536;
|
||||
subGidStart = 165536;
|
||||
};
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
# /hosts/hp-laptop/disko-config.nix
|
||||
# Two-disk layout:
|
||||
# /dev/sda -> boot + ESP (/boot) + swap + root (/)
|
||||
# /dev/sdb -> home (/home)
|
||||
{
|
||||
disk = {
|
||||
root = {
|
||||
type = "disk";
|
||||
device = "/dev/sda";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
size = "1M";
|
||||
type = "EF02";
|
||||
};
|
||||
ESP = {
|
||||
size = "512M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
swap = {
|
||||
size = "16G";
|
||||
type = "8200";
|
||||
content = {
|
||||
type = "swap";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
home = {
|
||||
type = "disk";
|
||||
device = "/dev/sdb";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
home = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/home";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# hardware-configuration.nix for hp-laptop
|
||||
# Generated placeholder — run `sudo nixos-generate-config --show-hardware-config` on the
|
||||
# target machine after the initial (disko / nixos-anywhere) install and replace this file.
|
||||
# NOTE: Do NOT copy the output of `nixos-generate-config` run from the installer ISO — it
|
||||
# reflects the live environment (tmpfs /, /iso, squashfs overlay), not the installed system.
|
||||
# NOTE: `fileSystems` and `swapDevices` are intentionally omitted here — they are
|
||||
# provided by the disko module (hosts/hp-laptop/disko-config.nix).
|
||||
# Disk layout (see disko-config.nix): /dev/sda = boot + ESP + swap + root (/);
|
||||
# /dev/sdb = home (/home).
|
||||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, modulesPath
|
||||
, ...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"nvme"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wlp2s0.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
# /hosts/mary-x270/configuration.nix
|
||||
{ config
|
||||
, pkgs
|
||||
, inputs
|
||||
, lib
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
../../modules/core/common.nix
|
||||
../../modules/desktop/gui.nix
|
||||
(import ../../modules/storage/disko.nix {
|
||||
inherit inputs lib config;
|
||||
diskoConfigPath = ./disko-config.nix;
|
||||
})
|
||||
../../modules/desktop/gnome.nix
|
||||
../../modules/core/management.nix
|
||||
../../modules/core/dev.nix
|
||||
];
|
||||
|
||||
sops.secrets = {
|
||||
"users/petere-password" = {
|
||||
neededForUsers = true;
|
||||
};
|
||||
"users/mary-password" = {
|
||||
neededForUsers = true;
|
||||
};
|
||||
"opencode-api-key" = {
|
||||
owner = "petere";
|
||||
group = "users";
|
||||
mode = "0440";
|
||||
};
|
||||
};
|
||||
|
||||
home-manager.users.mary.imports = [
|
||||
../../home-manager/modules/desktop-user.nix
|
||||
];
|
||||
|
||||
home-manager.users.petere.imports = [
|
||||
../../home-manager/modules/desktop-user.nix
|
||||
];
|
||||
|
||||
networking.hostName = "mary-x270";
|
||||
|
||||
users.users.mary = {
|
||||
isNormalUser = true;
|
||||
description = "Mary";
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
"networkmanager"
|
||||
"video"
|
||||
"audio"
|
||||
];
|
||||
hashedPasswordFile = config.sops.secrets."users/mary-password".path;
|
||||
subUidRanges = [
|
||||
{
|
||||
startUid = 200000;
|
||||
count = 65536;
|
||||
}
|
||||
];
|
||||
subGidRanges = [
|
||||
{
|
||||
startGid = 200000;
|
||||
count = 65536;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
my.users.petere = {
|
||||
description = "Peter Edley";
|
||||
hashedPasswordFile = config.sops.secrets."users/petere-password".path;
|
||||
subUidStart = 165536;
|
||||
subGidStart = 165536;
|
||||
};
|
||||
|
||||
hardware.graphics.enable = true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
# /hosts/mary-x270/disko-config.nix
|
||||
{
|
||||
disk = {
|
||||
nixos = {
|
||||
type = "disk";
|
||||
device = "/dev/sda";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
size = "1M";
|
||||
type = "EF02";
|
||||
};
|
||||
ESP = {
|
||||
size = "512M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
swap = {
|
||||
size = "16G";
|
||||
type = "8200";
|
||||
content = {
|
||||
type = "swap";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
# /hosts/mary-x270/hardware-configuration.nix
|
||||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, modulesPath
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"nvme"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
# NixOS configuration for mcf-server
|
||||
# Headless server environment (Command Line Interface only)
|
||||
|
||||
{ config
|
||||
, pkgs
|
||||
, lib
|
||||
, inputs
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
../../modules/core/common.nix
|
||||
(import ../../modules/storage/disko.nix {
|
||||
inherit inputs lib config;
|
||||
diskoConfigPath = ./disko-config.nix;
|
||||
})
|
||||
./hardware-configuration.nix
|
||||
../../modules/core/management.nix
|
||||
../../modules/core/podman.nix
|
||||
];
|
||||
|
||||
networking.hostName = "mcf-server";
|
||||
|
||||
# Create restic user for homeserver-1 backups
|
||||
users.users.restic-homeserver1 = {
|
||||
isSystemUser = true;
|
||||
group = "restic-homeserver1";
|
||||
shell = pkgs.zsh;
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICwGZFEr6OMm7SIPrYlt6wuuesvlmBIezqQVDxhXOHjD restic@homeserver-1"
|
||||
];
|
||||
};
|
||||
|
||||
users.groups.restic-homeserver1 = { };
|
||||
|
||||
# Standard user account (shared definition in modules/core/users.nix).
|
||||
# SSH-key-only access; no password on this host.
|
||||
|
||||
# SSH configuration
|
||||
services.openssh.enable = true;
|
||||
|
||||
# Glances system monitor - exposed to the tailnet so homeserver-1's
|
||||
# Homepage dashboard can display real-time stats for this machine.
|
||||
services.glances = {
|
||||
enable = true;
|
||||
port = 61208;
|
||||
# Webserver mode (default). Binds to 0.0.0.0; the firewall rule below
|
||||
# restricts access to the Tailscale interface only.
|
||||
extraArgs = [ "--webserver" ];
|
||||
};
|
||||
|
||||
# Expose Glances (61208) on Tailscale only
|
||||
networking.firewall.interfaces.tailscale.allowedTCPPorts = [ 61208 ];
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
disk = {
|
||||
main = {
|
||||
type = "disk";
|
||||
device = "/dev/sdb";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
size = "1M";
|
||||
type = "EF02"; # for grub MBR
|
||||
};
|
||||
ESP = {
|
||||
size = "512M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
data = {
|
||||
type = "disk";
|
||||
device = "/dev/sda";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
data = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "btrfs";
|
||||
mountpoint = "/data";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Hardware configuration for mcf-server
|
||||
# Generated by nixos-generate-config; live-ISO filesystem entries removed (managed by Disko)
|
||||
|
||||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, modulesPath
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"ahci"
|
||||
"usbhid"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
"sr_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
# fileSystems are managed by Disko — update disko-config.nix for disk layout
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
# /hosts/mcf-stream/configuration.nix
|
||||
{ config
|
||||
, pkgs
|
||||
, inputs
|
||||
, lib
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
../../modules/core/common.nix
|
||||
../../modules/desktop/gui.nix
|
||||
(import ../../modules/storage/disko.nix {
|
||||
inherit inputs lib config;
|
||||
diskoConfigPath = ./disko-config.nix;
|
||||
})
|
||||
../../modules/desktop/gnome.nix
|
||||
../../modules/core/management.nix
|
||||
../../modules/hardware/nvidia.nix
|
||||
../../modules/desktop/apps/obs.nix
|
||||
../../modules/desktop/apps/dvd.nix
|
||||
../../modules/desktop/apps/carla.nix
|
||||
];
|
||||
|
||||
sops.secrets = {
|
||||
"users/petere-password" = {
|
||||
neededForUsers = true;
|
||||
};
|
||||
"users/guest-password" = {
|
||||
neededForUsers = true;
|
||||
};
|
||||
};
|
||||
|
||||
# Auto-login as guest for this shared/streaming desktop
|
||||
services.displayManager.autoLogin = {
|
||||
enable = true;
|
||||
user = "guest";
|
||||
};
|
||||
|
||||
home-manager.users.petere.imports = [
|
||||
../../home-manager/modules/desktop-user.nix
|
||||
];
|
||||
|
||||
home-manager.users.guest.imports = [
|
||||
../../home-manager/modules/gnome-extensions.nix
|
||||
];
|
||||
|
||||
networking.hostName = "mcf-stream";
|
||||
|
||||
my.hardware.nvidia = {
|
||||
enable = true;
|
||||
nvidiaSettings = true;
|
||||
# GTX 1050 Ti (Pascal) needs the 580.xx legacy driver branch
|
||||
package = config.boot.kernelPackages.nvidiaPackages.legacy_580;
|
||||
};
|
||||
|
||||
my.users.petere = {
|
||||
description = "Peter Edley";
|
||||
hashedPasswordFile = config.sops.secrets."users/petere-password".path;
|
||||
};
|
||||
|
||||
users.users.guest = {
|
||||
isNormalUser = true;
|
||||
description = "Guest";
|
||||
hashedPasswordFile = config.sops.secrets."users/guest-password".path;
|
||||
extraGroups = [
|
||||
"networkmanager"
|
||||
"video"
|
||||
"audio"
|
||||
];
|
||||
};
|
||||
|
||||
# ffmpeg with NVENC encoders (h264/hevc/av1_nvenc) for GPU-accelerated
|
||||
# encoding on the NVIDIA GPU
|
||||
environment.systemPackages = with pkgs; [
|
||||
ffmpeg
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
# /hosts/mcf-stream/disko-config.nix
|
||||
# This file will contain your disko configuration for mcf-stream.
|
||||
{
|
||||
disk = {
|
||||
nixos = {
|
||||
type = "disk";
|
||||
device = "/dev/nvme0n1";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
size = "1M";
|
||||
type = "EF02"; # for grub MBR
|
||||
};
|
||||
ESP = {
|
||||
size = "512M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
swap = {
|
||||
size = "20G";
|
||||
type = "8200";
|
||||
content = {
|
||||
type = "swap";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
# Hardware configuration for mcf-stream
|
||||
# Generated for a single NVMe drive (/dev/nvme0n1)
|
||||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, modulesPath
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"ahci"
|
||||
"nvme"
|
||||
"usb_storage"
|
||||
"usbhid"
|
||||
"sd_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
# fileSystems are managed by Disko — update disko-config.nix for disk layout
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
# This is the NixOS configuration for richmond-server.
|
||||
# It is a server and does not require a GUI.
|
||||
|
||||
{ config
|
||||
, pkgs
|
||||
, lib
|
||||
, inputs
|
||||
, # Re-add inputs here
|
||||
... # specialArgs from flake.nix
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
# Import your common modules here
|
||||
../../modules/core/common.nix
|
||||
../../modules/core/management.nix
|
||||
# ../../modules/some-common-module.nix
|
||||
(import ../../modules/storage/disko.nix {
|
||||
inherit inputs lib config;
|
||||
diskoConfigPath = ./disko-config.nix;
|
||||
})
|
||||
./hardware-configuration.nix # Import hardware configuration
|
||||
../../modules/core/podman.nix
|
||||
../../modules/services/ntfy.nix
|
||||
];
|
||||
|
||||
sops.secrets = {
|
||||
"richmond-server/tailscale-authkey" = {
|
||||
mode = "0600";
|
||||
owner = "root";
|
||||
};
|
||||
"richmond-server/pihole-password" = { };
|
||||
"richmond-server/castopod-api-password" = {
|
||||
key = "richmond-server/castopod-api-password";
|
||||
};
|
||||
"richmond-server/mcf-notices-env" = { };
|
||||
"richmond-server/castopod-env" = { };
|
||||
"richmond-server/castopod-api-env" = { };
|
||||
"users/petere-password" = {
|
||||
neededForUsers = true;
|
||||
};
|
||||
};
|
||||
|
||||
# Set your hostname
|
||||
networking.hostName = "richmond-server";
|
||||
|
||||
# Set explicit nameservers for the host to ensure it can reach registries
|
||||
# regardless of local container or Tailscale DNS state.
|
||||
networking.nameservers = [
|
||||
"1.1.1.1"
|
||||
"8.8.8.8"
|
||||
];
|
||||
|
||||
# Allow rootless containers to bind to privileged ports
|
||||
boot.kernel.sysctl = {
|
||||
"net.ipv4.ip_unprivileged_port_start" = 53;
|
||||
};
|
||||
|
||||
# Enable SSH
|
||||
services.openssh.enable = true;
|
||||
|
||||
# Backup Server Configuration
|
||||
# Borg Backup removed - x1carbon migrated to Backrest on homeserver-1
|
||||
# Richmond-server now serves as backup target for Backrest (homeserver-1) only
|
||||
|
||||
# Create a dedicated system user for Backrest backups from homeserver-1
|
||||
users.users.restic-homeserver1 = {
|
||||
isSystemUser = true;
|
||||
group = "restic-homeserver1";
|
||||
shell = pkgs.zsh;
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICwGZFEr6OMm7SIPrYlt6wuuesvlmBIezqQVDxhXOHjD restic@homeserver-1"
|
||||
];
|
||||
};
|
||||
|
||||
# Admin user (shared definition in modules/core/users.nix)
|
||||
my.users.petere = {
|
||||
hashedPasswordFile = config.sops.secrets."users/petere-password".path;
|
||||
};
|
||||
|
||||
users.groups = {
|
||||
restic-homeserver1 = { };
|
||||
};
|
||||
|
||||
# Disable systemd-resolved to prevent it from binding to port 53,
|
||||
# allowing Pi-hole to take over DNS duties.
|
||||
services.resolved.enable = false;
|
||||
# The 'services.resolved.extraConfig' option is deprecated and now causes a build failure.
|
||||
# The 'services.resolved.enable = false;' line above is sufficient to free up port 53 for Pi-hole.
|
||||
# services.resolved.extraConfig = ''
|
||||
# DNSStubListener=no
|
||||
# '';
|
||||
|
||||
# Enable Tailscale (globally enabled in modules/core/settings.nix)
|
||||
services.tailscale.authKeyFile = config.sops.secrets."richmond-server/tailscale-authkey".path;
|
||||
# NOTE: no "--ssh" here. Tailscale SSH would intercept port 22 on the tailnet
|
||||
# and enforce the tailnet ACL, blocking the restic-homeserver1 user that
|
||||
# Backrest (homeserver-1) uses for backups. Regular OpenSSH handles SSH instead.
|
||||
services.tailscale.extraUpFlags = [
|
||||
"--accept-dns=false"
|
||||
];
|
||||
|
||||
# Glances system monitor - exposed to the tailnet so the Homepage
|
||||
# dashboard on homeserver-1 can display real-time stats for this machine.
|
||||
services.glances = {
|
||||
enable = true;
|
||||
port = 61208;
|
||||
extraArgs = [ "--webserver" ];
|
||||
};
|
||||
|
||||
# VLAN configuration
|
||||
networking.vlans = {
|
||||
management = {
|
||||
id = 5;
|
||||
interface = "enp1s0";
|
||||
};
|
||||
office = {
|
||||
id = 10;
|
||||
interface = "enp1s0";
|
||||
};
|
||||
tech = {
|
||||
id = 20;
|
||||
interface = "enp1s0";
|
||||
};
|
||||
advice = {
|
||||
id = 30;
|
||||
interface = "enp1s0";
|
||||
};
|
||||
words = {
|
||||
id = 40;
|
||||
interface = "enp1s0";
|
||||
};
|
||||
general = {
|
||||
id = 50;
|
||||
interface = "enp1s0";
|
||||
};
|
||||
printers = {
|
||||
id = 60;
|
||||
interface = "enp1s0";
|
||||
};
|
||||
};
|
||||
|
||||
networking.interfaces = {
|
||||
management.useDHCP = true;
|
||||
office.useDHCP = true;
|
||||
tech.useDHCP = true;
|
||||
advice.useDHCP = true;
|
||||
words.useDHCP = true;
|
||||
general.useDHCP = true;
|
||||
printers.useDHCP = true;
|
||||
};
|
||||
|
||||
# podman configuration is now in ../../modules/core/podman.nix
|
||||
|
||||
# --- Pi-hole Container Configuration ---
|
||||
virtualisation.oci-containers.containers.pihole = {
|
||||
image = "docker.io/pihole/pihole:2026.07.2";
|
||||
autoStart = true;
|
||||
|
||||
ports = [
|
||||
"53:53/tcp"
|
||||
"53:53/udp"
|
||||
"80:80/tcp" # Web UI on port 80
|
||||
];
|
||||
|
||||
volumes = [
|
||||
"/var/lib/pihole/etc-pihole:/etc/pihole"
|
||||
"/var/lib/pihole/etc-dnsmasq.d:/etc/dnsmasq.d"
|
||||
];
|
||||
|
||||
environment = {
|
||||
TZ = "Europe/London";
|
||||
DNSMASQ_LISTENING = "all";
|
||||
PIHOLE_INTERFACE = "all";
|
||||
};
|
||||
|
||||
environmentFiles = [
|
||||
"/run/pihole-env"
|
||||
];
|
||||
|
||||
extraOptions = [
|
||||
"--cap-add=NET_ADMIN" # Needed for DHCP features
|
||||
];
|
||||
};
|
||||
|
||||
# --- MCFNotices Container Configuration ---
|
||||
virtualisation.oci-containers.containers.mcf-notices = {
|
||||
image = "docker.io/pedley/slideshow-builder:2.6.0";
|
||||
autoStart = true;
|
||||
volumes = [
|
||||
# Persistent runtime config (notices-data) — app stores settings.db at
|
||||
# /data/settings.db inside the container.
|
||||
"/home/petere/mcf_data:/data"
|
||||
];
|
||||
environmentFiles = [
|
||||
config.sops.secrets."richmond-server/mcf-notices-env".path
|
||||
];
|
||||
extraOptions = [
|
||||
"--no-healthcheck"
|
||||
];
|
||||
};
|
||||
|
||||
# Improve container service resilience and ensure network is ready before starting.
|
||||
systemd.services.podman-pihole = {
|
||||
after = [
|
||||
"network-online.target"
|
||||
"pihole-data-dirs.service"
|
||||
];
|
||||
wants = [ "network-online.target" ];
|
||||
preStart = ''
|
||||
${pkgs.podman}/bin/podman rm -f pihole || true
|
||||
'';
|
||||
unitConfig = {
|
||||
StartLimitIntervalSec = 0;
|
||||
};
|
||||
serviceConfig = {
|
||||
Restart = lib.mkForce "always";
|
||||
RestartSec = "10s";
|
||||
};
|
||||
};
|
||||
|
||||
# Rendered by sops-nix from the pihole-password secret; the Pi-hole container
|
||||
# reads this file for FTLCONF_webserver_api_password.
|
||||
sops.templates."pihole-env" = {
|
||||
content = ''
|
||||
FTLCONF_webserver_api_password=${config.sops.placeholder."richmond-server/pihole-password"}
|
||||
'';
|
||||
path = "/run/pihole-env";
|
||||
mode = "0600";
|
||||
};
|
||||
|
||||
services.mysql = {
|
||||
enable = true;
|
||||
package = pkgs.mariadb;
|
||||
settings = {
|
||||
mysqld = {
|
||||
bind-address = "0.0.0.0"; # Allow container access
|
||||
character-set-server = "utf8mb4";
|
||||
collation-server = "utf8mb4_unicode_ci";
|
||||
};
|
||||
client = {
|
||||
default-character-set = "utf8mb4";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# --- Castopod Container Configuration ---
|
||||
virtualisation.oci-containers.containers.castopod = {
|
||||
image = "castopod/castopod:1.15.5";
|
||||
autoStart = true;
|
||||
volumes = [
|
||||
"/var/lib/castopod/media:/var/www/html/public/media"
|
||||
"/var/lib/castopod/writable:/var/www/html/writable"
|
||||
"/var/lib/castopod/plugins:/var/www/html/plugins"
|
||||
"/var/lib/castopod/plugins/mcf/episode-filter:/var/www/html/plugins/mcf/episode-filter"
|
||||
"/var/lib/castopod/public/plugins/mcf/episode-filter/assets:/var/www/html/public/plugins/mcf/episode-filter/assets"
|
||||
];
|
||||
environmentFiles = [
|
||||
config.sops.secrets."richmond-server/castopod-env".path
|
||||
"/run/castopod-api-env"
|
||||
];
|
||||
extraOptions = [
|
||||
"--network=host"
|
||||
];
|
||||
# We use a "configuration injection" trick here via the /run/castopod-api-env file.
|
||||
};
|
||||
|
||||
# Improve Castopod container resilience and ensure directories exist
|
||||
systemd.services.podman-castopod = {
|
||||
after = [
|
||||
"network-online.target"
|
||||
"castopod-data-dirs.service"
|
||||
];
|
||||
wants = [ "network-online.target" ];
|
||||
unitConfig = {
|
||||
StartLimitIntervalSec = 0;
|
||||
};
|
||||
serviceConfig = {
|
||||
Restart = lib.mkForce "always";
|
||||
RestartSec = "10s";
|
||||
};
|
||||
};
|
||||
|
||||
# NOTE: Castopod is an experiment. This env file is a "configuration injection"
|
||||
# used to pass restapi settings; the original preStart wrote a single line with
|
||||
# literal \n sequences. This template writes real newlines instead — review
|
||||
# Castopod's behaviour on the next pass.
|
||||
sops.templates."castopod-api-env" = {
|
||||
content = ''
|
||||
CP_DATABASE_PREFIX=cp_"
|
||||
restapi.enabled=true
|
||||
restapi.basicAuth=true
|
||||
restapi.basicAuthUsername=pedley
|
||||
restapi.basicAuthPassword=${config.sops.placeholder."richmond-server/castopod-api-password"}
|
||||
dummy="
|
||||
'';
|
||||
path = "/run/castopod-api-env";
|
||||
mode = "0600";
|
||||
};
|
||||
|
||||
# Create persistent data directories for Castopod.
|
||||
systemd.services.castopod-data-dirs = {
|
||||
description = "Create data directories for Castopod container";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "podman-castopod.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
mkdir -p /var/lib/castopod/media
|
||||
mkdir -p /var/lib/castopod/writable
|
||||
mkdir -p /var/lib/castopod/plugins
|
||||
mkdir -p /var/lib/castopod/public/plugins/mcf/episode-filter/assets
|
||||
# Ensure the container's www-data user (UID 33) can write to these
|
||||
chown -R 33:33 /var/lib/castopod/media /var/lib/castopod/writable /var/lib/castopod/plugins /var/lib/castopod/public
|
||||
chmod -R 775 /var/lib/castopod/media /var/lib/castopod/writable /var/lib/castopod/plugins /var/lib/castopod/public
|
||||
'';
|
||||
};
|
||||
|
||||
# --- ntfy Configuration ---
|
||||
services.ntfy-container = {
|
||||
enable = true;
|
||||
port = 8085;
|
||||
};
|
||||
|
||||
# Open firewall ports for Pi-hole and ntfy globally.
|
||||
networking.firewall.enable = true;
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
53
|
||||
80
|
||||
8085
|
||||
];
|
||||
networking.firewall.allowedUDPPorts = [ 53 ];
|
||||
|
||||
# Restrict Castopod (8080) to only be accessible via Tailscale
|
||||
networking.firewall.interfaces.tailscale0.allowedTCPPorts = [
|
||||
8080
|
||||
61208
|
||||
];
|
||||
|
||||
# Create persistent data directories for Pi-hole.
|
||||
systemd.services.pihole-data-dirs = {
|
||||
description = "Create data directories for Pi-hole container";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "podman-pihole.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
mkdir -p /var/lib/pihole/etc-pihole
|
||||
mkdir -p /var/lib/pihole/etc-dnsmasq.d
|
||||
'';
|
||||
};
|
||||
|
||||
# Create the persistent data directory for the MCFNotices container.
|
||||
systemd.services.mcf-notices-data-dirs = {
|
||||
description = "Create data directory for MCFNotices container";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "podman-mcf-notices.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
mkdir -p /home/petere/mcf_data
|
||||
chown petere:users /home/petere/mcf_data
|
||||
chmod 775 /home/petere/mcf_data
|
||||
'';
|
||||
};
|
||||
|
||||
# Ensure the base directory for backups exists and has correct permissions
|
||||
systemd.tmpfiles.rules = [
|
||||
# Borg backup directories removed (migrated to Backrest)
|
||||
"d /home/backup/restic/immich-backup 0700 restic-homeserver1 restic-homeserver1 -"
|
||||
];
|
||||
|
||||
nix.settings.trusted-users = [
|
||||
"root"
|
||||
"petere"
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
disk = {
|
||||
main = {
|
||||
type = "disk";
|
||||
device = "/dev/sdb";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
size = "1M";
|
||||
type = "EF02"; # for grub MBR
|
||||
};
|
||||
ESP = {
|
||||
size = "512M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
home = {
|
||||
type = "disk";
|
||||
device = "/dev/sda";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
home = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "btrfs";
|
||||
mountpoint = "/home";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
# 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"
|
||||
"usb_storage"
|
||||
"usbhid"
|
||||
"sd_mod"
|
||||
"sr_mod"
|
||||
"rtsx_usb_sdmmc"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
# fileSystems."/" =
|
||||
# { device = "/dev/disk/by-uuid/e0430ebf-8a47-44cb-aac7-77639f2184b1";
|
||||
# fsType = "ext4";
|
||||
# };
|
||||
|
||||
# fileSystems."/boot" =
|
||||
# { device = "/dev/disk/by-uuid/63DD-EA06";
|
||||
# fsType = "vfat";
|
||||
# options = [ "fmask=0077" "dmask=0077" ];
|
||||
# };
|
||||
|
||||
# fileSystems."/home" =
|
||||
# { device = "/dev/disk/by-uuid/f60ae16e-2580-452c-a9bc-f23d9a7446bc";
|
||||
# fsType = "btrfs";
|
||||
# };
|
||||
|
||||
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.enp1s0.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wlp2s0.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
# /hosts/nixos/configuration.nix
|
||||
{ config
|
||||
, pkgs
|
||||
, inputs
|
||||
, lib
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
../../modules/core/common.nix
|
||||
../../modules/desktop/gui.nix
|
||||
(import ../../modules/storage/disko.nix {
|
||||
inherit inputs lib config;
|
||||
diskoConfigPath = ./disko-config.nix;
|
||||
})
|
||||
../../modules/desktop/hyprland.nix
|
||||
../../modules/desktop/apps/soundux.nix
|
||||
../../modules/desktop/apps/freeshow.nix
|
||||
../../modules/desktop/apps/x32edit.nix
|
||||
../../modules/desktop/apps/mixing-station.nix
|
||||
../../modules/desktop/apps/opencode.nix
|
||||
../../modules/core/management.nix
|
||||
../../modules/hardware/laptop.nix
|
||||
../../modules/hardware/nvidia.nix
|
||||
../../modules/hardware/thinkpad-battery-limit.nix
|
||||
../../modules/hardware/tablet-mode.nix
|
||||
../../modules/core/known-hosts.nix
|
||||
../../modules/core/podman.nix
|
||||
../../modules/core/dev.nix
|
||||
../../modules/services/paperless.nix
|
||||
];
|
||||
|
||||
sops.secrets = {
|
||||
"x1carbon/borg-passphrase" = {
|
||||
mode = "0600";
|
||||
owner = "root";
|
||||
};
|
||||
"x1carbon/borg-ssh-key" = {
|
||||
mode = "0600";
|
||||
owner = "root";
|
||||
};
|
||||
# Nextcloud CalDAV credentials for the QuickShell calendar popup. Rendered
|
||||
# to /run/secrets/hp-laptop/nextcloud-cal-env (the default path the
|
||||
# qs-cal-sync backend expects) — reuse the same secret for both hosts.
|
||||
"hp-laptop/nextcloud-cal-env" = {
|
||||
owner = "petere";
|
||||
group = "users";
|
||||
mode = "0440";
|
||||
};
|
||||
"users/petere-password" = {
|
||||
neededForUsers = true;
|
||||
};
|
||||
"x1carbon/telegram-bot-token" = {
|
||||
owner = "petere";
|
||||
group = "users";
|
||||
mode = "0440";
|
||||
};
|
||||
"opencode-api-key" = {
|
||||
owner = "petere";
|
||||
group = "users";
|
||||
mode = "0440";
|
||||
};
|
||||
"x1carbon/gitea-mcp-token" = {
|
||||
owner = "petere";
|
||||
group = "users";
|
||||
mode = "0440";
|
||||
};
|
||||
};
|
||||
|
||||
#TEMPORARY FIX
|
||||
# nixpkgs.overlays = [
|
||||
# (final: prev: {
|
||||
# pnpm = prev.pnpm // { nodejs-slim = final.nodejs-slim; };
|
||||
# pnpm_10 = prev.pnpm_10 // { nodejs-slim = final.nodejs-slim; };
|
||||
# pnpm_11 = prev.pnpm_11 // { nodejs-slim = final.nodejs-slim; };
|
||||
# })
|
||||
# ];
|
||||
|
||||
services.paperless-service.enable = true;
|
||||
|
||||
hardware.sensor.iio.enable = true;
|
||||
|
||||
home-manager.users.petere.imports = [
|
||||
../../home-manager/modules/hyprland.nix
|
||||
../../home-manager/modules/quickshell-cal.nix
|
||||
../../home-manager/modules/quickshell-apps.nix
|
||||
../../home-manager/modules/opencode.nix
|
||||
../../home-manager/modules/nix-lsp.nix
|
||||
../../home-manager/modules/matugen.nix
|
||||
];
|
||||
|
||||
home-manager.users.petere.services.quickshell-cal.enable = true;
|
||||
|
||||
home-manager.users.petere.services.quickshell-apps = {
|
||||
enable = true;
|
||||
apps = [
|
||||
{
|
||||
name = "Element";
|
||||
cmd = "element-desktop";
|
||||
}
|
||||
{
|
||||
name = "Nextcloud";
|
||||
cmd = "nextcloud";
|
||||
}
|
||||
{
|
||||
name = "Bitwarden";
|
||||
cmd = "bitwarden";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
networking.hostName = "x1carbon";
|
||||
networking.modemmanager.enable = true;
|
||||
|
||||
# Laptop-specific hardware (fingerprint reader, fwupd)
|
||||
my.hardware.laptop.enable = true;
|
||||
|
||||
# Charging cap at 80% via the ThinkPad's native sysfs thresholds
|
||||
# (charge_control_start/end_threshold). The EC at 76% won't resume charging
|
||||
# until it drops to/below the resume threshold (75) — expect the level to
|
||||
# hover between ~76 and ~80 while "on". Despite the name, this is the
|
||||
# standard ThinkPad behaviour; the QML gear toggle drives this via
|
||||
# `battery-charge-limit on|off|status`.
|
||||
my.hardware.thinkpadBatteryLimit.enable = true;
|
||||
|
||||
my.hardware.nvidia = {
|
||||
enable = true;
|
||||
nvidiaSettings = true;
|
||||
package = config.boot.kernelPackages.nvidiaPackages.legacy_580;
|
||||
};
|
||||
|
||||
my.hardware.tabletMode.enable = true;
|
||||
|
||||
programs.steam.enable = true;
|
||||
|
||||
services.hardware.bolt.enable = true;
|
||||
|
||||
# Establish trust for SSH to richmond-server (borg backup target, now using Backrest).
|
||||
my.knownHosts.richmondServer = true;
|
||||
|
||||
# Borg Backup removed - migrated to Backrest (see hosts/homeserver-1/configuration.nix)
|
||||
my.users.petere = {
|
||||
hashedPasswordFile = config.sops.secrets."users/petere-password".path;
|
||||
subUidStart = 100000;
|
||||
subGidStart = 100000;
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [
|
||||
9756 # TeleportFling screen/audio streaming
|
||||
];
|
||||
allowedUDPPorts = [
|
||||
9999 # TeleportFling multicast discovery
|
||||
];
|
||||
allowedTCPPortRanges = [
|
||||
{
|
||||
from = 1714;
|
||||
to = 1764;
|
||||
} # KDE Connect / GSConnect
|
||||
{
|
||||
from = 5960;
|
||||
to = 6000;
|
||||
} # NDI streams
|
||||
];
|
||||
allowedUDPPortRanges = [
|
||||
{
|
||||
from = 1714;
|
||||
to = 1764;
|
||||
} # KDE Connect / GSConnect discovery
|
||||
{
|
||||
from = 5960;
|
||||
to = 6000;
|
||||
} # NDI reliable UDP
|
||||
];
|
||||
};
|
||||
|
||||
boot.kernelModules = [
|
||||
"sg"
|
||||
"v4l2loopback"
|
||||
];
|
||||
boot.extraModulePackages = [ pkgs.linuxPackages.v4l2loopback ];
|
||||
boot.extraModprobeConfig = ''
|
||||
options v4l2loopback devices=1 video_nr=1 card_label="OBS Cam" exclusive_caps=1
|
||||
'';
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
openshot-qt
|
||||
(
|
||||
(wrapOBS.override {
|
||||
obs-studio = obs-studio.override { cudaSupport = true; };
|
||||
})
|
||||
{
|
||||
plugins = with obs-studio-plugins; [
|
||||
distroav
|
||||
obs-backgroundremoval
|
||||
obs-teleport
|
||||
];
|
||||
}
|
||||
)
|
||||
vorta
|
||||
xournalpp
|
||||
winbox
|
||||
steam
|
||||
lmstudio
|
||||
lm_sensors
|
||||
gimp
|
||||
scribus
|
||||
ventoy
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
# /hosts/x1carbon/disko-config.nix
|
||||
# This file will contain your disko configuration for x1carbon.
|
||||
{
|
||||
disk = {
|
||||
nixos = {
|
||||
type = "disk";
|
||||
device = "/dev/nvme0n1";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
size = "1M";
|
||||
type = "EF02"; # for grub MBR
|
||||
};
|
||||
ESP = {
|
||||
size = "512M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
swap = {
|
||||
size = "20G";
|
||||
type = "8200";
|
||||
content = {
|
||||
type = "swap";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
# /hosts/x1carbon/hardware-configuration.nix
|
||||
# This file will be generated by NixOS during installation or by 'nixos-generate-config'.
|
||||
# It contains hardware-specific settings for x1carbon.
|
||||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, modulesPath
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
#hardware.ipu6.enable = true;
|
||||
#hardware.ipu6.platform = "ipu6";
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"nvme"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
# fileSystems."/" =
|
||||
# { device = "/dev/disk/by-uuid/882a76d6-c1ac-4efd-aff8-b56d43ec7ca5";
|
||||
# fsType = "ext4";
|
||||
# };
|
||||
|
||||
# fileSystems."/boot" =
|
||||
# { device = "/dev/disk/by-uuid/EF30-EBA7";
|
||||
# fsType = "vfat";
|
||||
# options = [ "fmask=0077" "dmask=0077" ];
|
||||
# };
|
||||
|
||||
# swapDevices =
|
||||
# [ { device = "/dev/disk/by-uuid/1c488737-a2e7-4258-b0f3-bd1d14155d03"; }
|
||||
# ];
|
||||
|
||||
# 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.enp0s31f6.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
# /hosts/nixos/configuration.nix
|
||||
{ config
|
||||
, pkgs
|
||||
, inputs
|
||||
, lib
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
../../modules/core/common.nix
|
||||
../../modules/core/management.nix
|
||||
../../modules/desktop/gui.nix
|
||||
(import ../../modules/storage/disko.nix {
|
||||
inherit inputs lib config;
|
||||
diskoConfigPath = ./disko-config.nix;
|
||||
})
|
||||
../../modules/desktop/gnome.nix
|
||||
../../modules/desktop/apps/freeshow.nix
|
||||
../../modules/desktop/apps/openlp.nix
|
||||
];
|
||||
|
||||
sops.secrets = {
|
||||
"users/petere-password" = {
|
||||
neededForUsers = true;
|
||||
};
|
||||
"users/guest-password" = {
|
||||
neededForUsers = true;
|
||||
};
|
||||
"opencode-api-key" = {
|
||||
owner = "petere";
|
||||
group = "users";
|
||||
mode = "0440";
|
||||
};
|
||||
};
|
||||
|
||||
home-manager.users.petere.imports = [ ../../home-manager/modules/desktop-user.nix ];
|
||||
|
||||
networking.hostName = "x470"; # Define your hostname
|
||||
|
||||
my.users.petere = {
|
||||
description = "Peter Edley";
|
||||
hashedPasswordFile = config.sops.secrets."users/petere-password".path;
|
||||
};
|
||||
|
||||
users.users.guest = {
|
||||
isNormalUser = true;
|
||||
hashedPasswordFile = config.sops.secrets."users/guest-password".path;
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
winbox
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
# /hosts/x470/disko-config.nix
|
||||
# This file will contain your disko configuration for x470.
|
||||
{
|
||||
disk = {
|
||||
nixos = {
|
||||
type = "disk";
|
||||
device = "/dev/nvme0n1";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
size = "1M";
|
||||
type = "EF02"; # for grub MBR
|
||||
};
|
||||
ESP = {
|
||||
size = "512M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
swap = {
|
||||
size = "20G";
|
||||
type = "8200";
|
||||
content = {
|
||||
type = "swap";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# /hosts/x470/hardware-configuration.nix
|
||||
# This file will be generated by NixOS during installation or by 'nixos-generate-config'.
|
||||
# It contains hardware-specific settings for x470.
|
||||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, modulesPath
|
||||
, ...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"nvme"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
# 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.enp0s31f6.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wlp4s0.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user