2f0d0b5e4c
Replaces the Helm/k3s setup with a declarative NixOS configuration targeting
a Raspberry Pi 4. Services run as podman containers under systemd, with data
on an external HD at /mnt/data. Key components:
- flake.nix: multi-host flake with pi-main (aarch64) and a placeholder for a
second machine
- modules/common.nix: shared system config (nix, podman, sops, SSH)
- modules/storage.nix: external HD mount with per-service subdirs
- modules/caddy.nix: Caddy with cloudflare DNS-01 ACME + authelia forward_auth
- modules/cloudflared.nix: Cloudflare tunnel for remote access
- modules/backup.nix: restic daily backups with NC maintenance mode pre-hook
- modules/services/{openldap,authelia,gitea,nextcloud,phpldapadmin}.nix: core services
- modules/services/{jellyfin,transmission}.nix: media services (disabled by default)
- secrets/: sops-nix scaffold with .sops.yaml age key config
- hosts/pi-main/: hardware config + service selection for the Pi
- PORTING.md: step-by-step migration guide (SD card → data restore → verify)
118 lines
4.3 KiB
Nix
118 lines
4.3 KiB
Nix
{ config, lib, pkgs, homeyConfig, ... }:
|
|
|
|
# Common configuration shared by every host in the homey ecosystem.
|
|
# Hardware-specific settings (disk layout, device trees, etc.) go in
|
|
# hosts/<name>/hardware.nix instead.
|
|
|
|
{
|
|
# -------------------------------------------------------------------------
|
|
# Nix / flakes
|
|
# -------------------------------------------------------------------------
|
|
nix = {
|
|
settings = {
|
|
experimental-features = [ "nix-command" "flakes" ];
|
|
# Save disk space on Pi
|
|
auto-optimise-store = true;
|
|
};
|
|
# Weekly garbage collection — keeps the system from filling the SD card
|
|
gc = {
|
|
automatic = true;
|
|
dates = "weekly";
|
|
options = "--delete-older-than 14d";
|
|
};
|
|
};
|
|
|
|
# Allow unfree packages (e.g. cloudflared binary)
|
|
nixpkgs.config.allowUnfree = true;
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Boot — set in hardware.nix; this is just a safe default
|
|
# -------------------------------------------------------------------------
|
|
# boot.loader is intentionally left to hardware.nix
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Locale / timezone
|
|
# -------------------------------------------------------------------------
|
|
time.timeZone = homeyConfig.timezone;
|
|
i18n.defaultLocale = "en_US.UTF-8";
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Networking
|
|
# -------------------------------------------------------------------------
|
|
networking = {
|
|
# hostname is set per-host in default.nix
|
|
firewall = {
|
|
enable = true;
|
|
allowedTCPPorts = [
|
|
22 # SSH
|
|
80 # Caddy HTTP (redirect to HTTPS or ACME challenge)
|
|
443 # Caddy HTTPS
|
|
];
|
|
};
|
|
# Use systemd-resolved for DNS — supports mDNS and local overrides
|
|
nameservers = [ "1.1.1.1" "8.8.8.8" ];
|
|
};
|
|
|
|
# -------------------------------------------------------------------------
|
|
# SSH
|
|
# -------------------------------------------------------------------------
|
|
services.openssh = {
|
|
enable = true;
|
|
settings = {
|
|
PasswordAuthentication = false;
|
|
PermitRootLogin = "no";
|
|
};
|
|
};
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Container runtime — podman (rootless-capable, no daemon needed)
|
|
# -------------------------------------------------------------------------
|
|
virtualisation.podman = {
|
|
enable = true;
|
|
dockerCompat = true; # allow `docker` CLI commands against podman
|
|
defaultNetwork.settings.dns_enabled = true;
|
|
};
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Core packages available on every host
|
|
# -------------------------------------------------------------------------
|
|
environment.systemPackages = with pkgs; [
|
|
git
|
|
vim
|
|
htop
|
|
curl
|
|
wget
|
|
rsync
|
|
lsof
|
|
sops # secret editing
|
|
age # key generation for sops
|
|
restic # backup (CLI, also used by services.restic)
|
|
podman-compose
|
|
];
|
|
|
|
# -------------------------------------------------------------------------
|
|
# sops-nix global config — point at the secrets file and the host's age key
|
|
# -------------------------------------------------------------------------
|
|
sops = {
|
|
defaultSopsFile = ../secrets/secrets.yaml;
|
|
# The age private key must be present on the host at this path.
|
|
# Generate on the Pi with: age-keygen -o /var/lib/sops-nix/key.txt
|
|
# Then add the PUBLIC key to secrets/.sops.yaml before encrypting.
|
|
age.keyFile = "/var/lib/sops-nix/key.txt";
|
|
};
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Admin user — adjust username / SSH key in hosts/<name>/default.nix
|
|
# -------------------------------------------------------------------------
|
|
users.mutableUsers = false; # all user config must be declared here
|
|
|
|
# The actual admin user is declared in hosts/<name>/default.nix so the
|
|
# SSH authorized key can be host-specific.
|
|
|
|
# -------------------------------------------------------------------------
|
|
# System state version — do not change after first install
|
|
# (tracks NixOS backwards-compat markers)
|
|
# -------------------------------------------------------------------------
|
|
system.stateVersion = "24.11";
|
|
}
|