Files
homey/modules/common.nix
T
2026-05-10 11:30:43 +03:00

150 lines
5.7 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" ];
auto-optimise-store = true;
# Extra binary caches — speeds up aarch64-linux builds significantly
substituters = [
"https://cache.nixos.org"
"https://nix-community.cachix.org"
];
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nix-community.cachix.org-1:mB9FkXj6Q3Q4ohOcbM4FJ9Z1X2kCrVK4vZOqsDqqNqk="
];
# Trigger GC automatically when free space drops below 2 GB;
# stop once 5 GB is free. Prevents CI builds from filling the disk
# between weekly GC runs.
min-free = 2147483648; # 2 GiB
max-free = 5368709120; # 5 GiB
};
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;
};
# Create the shared "homey" podman network that all service containers join.
# DNS is enabled by default on netavark-backed networks, so containers can
# reach each other by container name (e.g. "openldap", "nextcloud-postgres").
systemd.services.podman-homey-network = {
description = "Create homey podman network";
wantedBy = [ "multi-user.target" ];
before = [ "podman-openldap.service" "podman-authelia.service"
"podman-gitea.service" "podman-nextcloud-postgres.service"
"podman-nextcloud.service" "podman-phpldapadmin.service"
"podman-jellyfin.service" "podman-transmission.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = pkgs.writeShellScript "create-homey-network" ''
${pkgs.podman}/bin/podman network exists homey \
|| ${pkgs.podman}/bin/podman network create homey
'';
};
};
# -------------------------------------------------------------------------
# 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 = "25.05";
}