Huge update. Reorganized folders. Added post-install logic. Have to do testing to check if everything works.
This commit is contained in:
@@ -1,146 +0,0 @@
|
||||
{ modulesPath, config, lib, pkgs, inputs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
inputs.sops-nix.nixosModules.sops
|
||||
./disks/disko.nix
|
||||
# ./disks/snapraid.nix
|
||||
# ./disks/pcr-check.nix
|
||||
];
|
||||
|
||||
# Hardware settings
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
hardware.cpu.intel.updateMicrocode = true;
|
||||
hardware.cpu.amd.updateMicrocode = true;
|
||||
|
||||
# Secrets management
|
||||
sops.defaultSopsFile = ./secrets/secrets.yaml;
|
||||
sops.age.sshKeyPaths = [ "/home/numbus-admin/.ssh/id_ed25519" ];
|
||||
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||
sops.age.generateKey = true;
|
||||
sops.secrets."ssh_public_keys" = { owner = "numbus-admin"; path = "/etc/ssh/authorized_keys.d/numbus-admin"; };
|
||||
sops.secrets."sender_email_address_password" = {};
|
||||
sops.secrets."docker/frigate" = { owner = "numbus-admin"; path = "/etc/docker-compose/frigate/.env"; };
|
||||
sops.secrets."docker/traefik" = { owner = "numbus-admin"; path = "/etc/docker-compose/traefik/.env"; };
|
||||
sops.secrets."docker/nextcloud" = { owner = "numbus-admin"; path = "/etc/docker-compose/nextcloud/.env"; };
|
||||
sops.secrets."docker/passbolt" = { owner = "numbus-admin"; path = "/etc/docker-compose/passbolt/.env"; };
|
||||
sops.secrets."docker/hass" = { owner = "numbus-admin"; path = "/etc/docker-compose/hass/.env"; };
|
||||
sops.secrets."docker/pihole" = { owner = "numbus-admin"; path = "/etc/docker-compose/pihole/.env"; };
|
||||
sops.secrets."docker/immich" = { owner = "numbus-admin"; path = "/etc/docker-compose/immich/.env"; };
|
||||
|
||||
# Bootloader options
|
||||
boot.initrd.systemd.enable = true;
|
||||
boot.initrd.systemd.tpm2.enable = true;
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
# TPM2 PCR check
|
||||
# systemIdentity.enable = true;
|
||||
# systemIdentity.pcr15 = "PCR_HASH";
|
||||
|
||||
# Timezone
|
||||
time.timeZone = "Europe/Paris";
|
||||
|
||||
# Internationalisation properties.
|
||||
i18n.defaultLocale = "fr_FR.UTF-8";
|
||||
i18n.extraLocaleSettings = {
|
||||
LC_ADDRESS = "fr_FR.UTF-8";
|
||||
LC_IDENTIFICATION = "fr_FR.UTF-8";
|
||||
LC_MEASUREMENT = "fr_FR.UTF-8";
|
||||
LC_MONETARY = "fr_FR.UTF-8";
|
||||
LC_NAME = "fr_FR.UTF-8";
|
||||
LC_NUMERIC = "fr_FR.UTF-8";
|
||||
LC_PAPER = "fr_FR.UTF-8";
|
||||
LC_TELEPHONE = "fr_FR.UTF-8";
|
||||
LC_TIME = "fr_FR.UTF-8";
|
||||
};
|
||||
|
||||
# Keyboard mapping
|
||||
console.keyMap = "fr";
|
||||
services.xserver.xkb = {
|
||||
layout = "fr";
|
||||
variant = "";
|
||||
};
|
||||
|
||||
# Enable SSH
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
# Allow unfree packages
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
# Install packages
|
||||
environment.systemPackages = with pkgs; [
|
||||
ncdu
|
||||
fastfetch
|
||||
tpm2-tss
|
||||
sops
|
||||
age
|
||||
powertop
|
||||
pciutils
|
||||
hdparm
|
||||
hd-idle
|
||||
hddtemp
|
||||
smartmontools
|
||||
cpufrequtils
|
||||
intel-gpu-tools
|
||||
];
|
||||
|
||||
# Power savings
|
||||
services.autoaspm.enable = true;
|
||||
powerManagement.powertop.enable = true;
|
||||
boot.kernelParams = [
|
||||
"pcie_aspm=force"
|
||||
"consoleblank=60"
|
||||
];
|
||||
|
||||
# Enable cron service
|
||||
services.cron = {
|
||||
enable = true;
|
||||
systemCronJobs = [
|
||||
];
|
||||
};
|
||||
|
||||
# Enable docker
|
||||
virtualisation.docker.enable = true;
|
||||
virtualisation.docker.daemon.settings = {
|
||||
data-root = "/mnt/config-storage/docker-volumes/";
|
||||
};
|
||||
|
||||
# User account
|
||||
users.users.numbus-admin = {
|
||||
isNormalUser = true;
|
||||
description = "Numbus Admin";
|
||||
extraGroups = [ "networkmanager" "wheel" "docker" ];
|
||||
uid = 1000;
|
||||
initialPassword = "changeMe!";
|
||||
};
|
||||
|
||||
# Login message
|
||||
environment.loginShellInit = ''
|
||||
if [ "$(id -u)" -eq 1000 ]; then
|
||||
if [ -n "$SSH_TTY" ]; then
|
||||
fastfetch
|
||||
echo -e "\n\nWelcome to numbus.eu server !\n\n- This system is managed by NixOS\n- All changes are futile\n- Please consider buying support if you can't get your server running\n- Have a nice day and enjoy !"
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
|
||||
# Enable auto updates
|
||||
system.autoUpgrade = {
|
||||
enable = true;
|
||||
allowReboot = true;
|
||||
flake = inputs.self.outPath;
|
||||
flags = [ "--print-build-logs" ];
|
||||
dates = "02:00";
|
||||
randomizedDelaySec = "45min";
|
||||
};
|
||||
|
||||
# Enable NixOS flakes
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
|
||||
system.stateVersion = "25.05";
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
let
|
||||
container_name = "traefik";
|
||||
compose-dir = "docker-compose/traefik";
|
||||
config-dir = "/mnt/config-storage/docker-data/traefik";
|
||||
in
|
||||
|
||||
{
|
||||
config = {
|
||||
environment.etc."${compose-dir}/compose.yaml".text =
|
||||
/*
|
||||
yaml
|
||||
*/
|
||||
''
|
||||
services:
|
||||
traefik:
|
||||
image: docker.io/library/traefik:latest
|
||||
container_name: traefik
|
||||
networks:
|
||||
nextcloud-aio:
|
||||
ipv4_address: 172.16.1.253
|
||||
passbolt_frontend:
|
||||
ipv4_address: 172.16.20.253
|
||||
pihole:
|
||||
ipv4_address: 172.16.3.253
|
||||
hass_frontend:
|
||||
ipv4_address: 172.16.40.253
|
||||
immich_frontend:
|
||||
ipv4_address: 172.16.50.253
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
volumes:
|
||||
- /run/docker.sock:/run/docker.sock:ro
|
||||
- ${config-dir}/config/conf/:/etc/traefik/conf/:ro
|
||||
- ${config-dir}/config/traefik.yaml:/etc/traefik/traefik.yaml:ro
|
||||
- ${config-dir}/certs/:/var/traefik/certs/:rw
|
||||
environment:
|
||||
- CF_DNS_API_TOKEN=$CF_DNS_API_TOKEN
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.services.traefik.loadbalancer.server.port=8080
|
||||
- traefik.http.services.traefik.loadbalancer.server.scheme=http
|
||||
- traefik.http.routers.traefik-https.entrypoints=websecure
|
||||
- traefik.http.routers.traefik-https.rule=Host(`reverse.$DOMAIN_NAME`)
|
||||
- traefik.http.routers.traefik-https.tls=true
|
||||
- traefik.http.routers.traefik-https.tls.certresolver=cloudflare
|
||||
restart: always
|
||||
networks:
|
||||
nextcloud-aio:
|
||||
name: nextcloud-aio
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: "172.16.1.0/24"
|
||||
gateway: "172.16.1.254"
|
||||
passbolt_backend:
|
||||
name: passbolt_backend
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: "172.16.2.0/24"
|
||||
gateway: "172.16.2.254"
|
||||
passbolt_frontend:
|
||||
name: passbolt_frontend
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: "172.16.20.0/24"
|
||||
gateway: "172.16.20.254"
|
||||
pihole:
|
||||
name: pihole
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: "172.16.3.0/24"
|
||||
gateway: "172.16.3.254"
|
||||
hass_backend:
|
||||
name: hass_backend
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: "172.16.4.0/24"
|
||||
gateway: "172.16.4.254"
|
||||
hass_frontend:
|
||||
name: hass_frontend
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: "172.16.40.0/24"
|
||||
gateway: "172.16.40.254"
|
||||
immich_backend:
|
||||
name: immich_backend
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: "172.16.5.0/24"
|
||||
gateway: "172.16.5.254"
|
||||
immich_frontend:
|
||||
name: immich_frontend
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: "172.16.50.0/24"
|
||||
gateway: "172.16.50.254"
|
||||
'';
|
||||
|
||||
systemd.services.traefik = {
|
||||
description = "Docker container : ${container_name}";
|
||||
after = [ "network.target" "docker.service" "docker.socket" ];
|
||||
requires = [ "docker.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ pkgs.docker ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "exec";
|
||||
# Pull the latest image before running
|
||||
ExecStartPre = "${pkgs.docker}/bin/docker compose -f /etc/${compose-dir}/compose.yaml pull";
|
||||
# Bring the service up
|
||||
ExecStart = "${pkgs.docker}/bin/docker compose -f /etc/${compose-dir}/compose.yaml up --remove-orphans";
|
||||
# Take it down gracefully
|
||||
ExecStop = "${pkgs.docker}/bin/docker compose -f /etc/${compose-dir}/compose.yaml down";
|
||||
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
{
|
||||
inputs = {
|
||||
# Core Nixpkgs
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
|
||||
# Disk‑partitioning helper
|
||||
disko.url = "github:nix-community/disko";
|
||||
disko.inputs.nixpkgs.follows = "nixpkgs";
|
||||
# Secrets handling
|
||||
sops-nix.url = "github:Mic92/sops-nix";
|
||||
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
# Power savings
|
||||
autoaspm.url = "github:notthebee/AutoASPM";
|
||||
autoaspm.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, disko, sops-nix, ... }@inputs: let
|
||||
# System definition
|
||||
system = "x86_64-linux";
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
|
||||
# Helper: collect every *.nix file inside ./docker as a list
|
||||
dockerModules = let
|
||||
dir = ../docker;
|
||||
entries = builtins.readDir dir;
|
||||
names = builtins.attrNames entries;
|
||||
nixNames = builtins.filter (n: builtins.match ".*\\.nix" n != null) names;
|
||||
in map (name: "${dir}/${name}") nixNames;
|
||||
in {
|
||||
nixosConfigurations = {
|
||||
numbus-server = nixpkgs.lib.nixosSystem {
|
||||
inherit system;
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [
|
||||
# Disk‑partitioning helper
|
||||
disko.nixosModules.disko
|
||||
# Secrets handling
|
||||
sops-nix.nixosModules.sops
|
||||
# Power savings
|
||||
inputs.autoaspm.nixosModules.autoaspm
|
||||
# Core host configuration
|
||||
./configuration.nix
|
||||
./hardware-configuration.nix
|
||||
# Docker services – automatically added from ./docker/*.nix
|
||||
] ++ dockerModules;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.email;
|
||||
in
|
||||
|
||||
### --> Mail notifications configuration
|
||||
{
|
||||
options.email = {
|
||||
enable = lib.mkEnableOption "Email sending functionality";
|
||||
fromAddress = lib.mkOption {
|
||||
description = "The 'from' address";
|
||||
type = lib.types.str;
|
||||
default = "no-reply@${DOMAIN_NAME}";
|
||||
};
|
||||
toAddress = lib.mkOption {
|
||||
description = "The 'to' address";
|
||||
type = lib.types.str;
|
||||
default = "${EMAIL_ADDRESS}";
|
||||
};
|
||||
smtpServer = lib.mkOption {
|
||||
description = "The SMTP server address";
|
||||
type = lib.types.str;
|
||||
default = "${SENDER_EMAIL_DOMAIN}";
|
||||
};
|
||||
smtpUsername = lib.mkOption {
|
||||
description = "The SMTP username";
|
||||
type = lib.types.str;
|
||||
default = "${SENDER_EMAIL_ADDRESS}";
|
||||
};
|
||||
smtpPasswordPath = lib.mkOption {
|
||||
description = "Path to the secret containing SMTP password";
|
||||
type = lib.types.path;
|
||||
default = config.sops.secrets.sender_email_address_password.path;
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.msmtp = {
|
||||
enable = true;
|
||||
accounts.default = {
|
||||
auth = true;
|
||||
host = config.email.smtpServer;
|
||||
from = config.email.fromAddress;
|
||||
user = config.email.smtpUsername;
|
||||
tls = true;
|
||||
passwordeval = "${pkgs.coreutils}/bin/cat ${config.email.smtpPasswordPath}";
|
||||
};
|
||||
};
|
||||
};
|
||||
### Mail notifications configuration <--
|
||||
|
||||
|
||||
|
||||
### --> SMART disk heath
|
||||
services.smartd = {
|
||||
enable = true;
|
||||
defaults.autodetected = "-a -o on -S on -s (S/../.././00|L/../../6/01) -n standby,q";
|
||||
notifications = {
|
||||
wall = {
|
||||
enable = true;
|
||||
};
|
||||
mail = {
|
||||
enable = true;
|
||||
sender = config.email.fromAddress;
|
||||
recipient = config.email.toAddress;
|
||||
};
|
||||
};
|
||||
};
|
||||
### SMART disk heath <--
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
# Hostname
|
||||
networking.hostName = "numbus-server";
|
||||
|
||||
# Enable networking and firewall
|
||||
networking.interfaces.eth0.ipv4.addresses = [
|
||||
{
|
||||
address = "HOME_SERVER_IP";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
networking.defaultGateway = "HOME_ROUTER_IP";
|
||||
networking.nameservers = [ "HOME_SERVER_IP" "9.9.9.9" ];
|
||||
networking.networkmanager.enable = true;
|
||||
networking.nftables.enable = true;
|
||||
networking.firewall.enable = true;
|
||||
# networking.firewall.extraCommands = "
|
||||
# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
|
||||
# iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443
|
||||
# ";
|
||||
|
||||
# Open ports in the firewall
|
||||
networking.firewall.allowPing = true;
|
||||
networking.firewall.allowedTCPPorts = [ 53 80 443 ];
|
||||
networking.firewall.allowedUDPPorts = [ 53 ];
|
||||
}
|
||||
Reference in New Issue
Block a user