Port to NixOS: replace Helm chart with flake-based NixOS config
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)
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
{ 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";
|
||||
}
|
||||
Reference in New Issue
Block a user