Compare commits

..

1 commit

Author SHA1 Message Date
ef43efdf53
flake: Upgrade nixpkgs to nixos-25.11 family
This commit upgrades nixpkgs to nixos-25.11, and all other management
systems (home-manager, nix-darwin, etc.) to the equivalent tag, and also
upgrades any syntax within the modules to follow new syntax.

1. Upgrades nixpkgs to nixos-25.11 2. Upgrades nixpkgs-darwin to
nixpkgs-25.11-darwin 3. Upgrades home-manger to release-25.11 4.
Upgrades nix-darwin to 25.11 5. Implements conditional to use nixpkgs on
Linux and nixpkgs-darwin on Darwin 6. Replace micromamba with mamba-cpp
and set alias, see
https://github.com/NixOS/nixpkgs/issues/456288#issuecomment-3584844923
7. Replace asitop with its new name - macpm 8. Remove ollama package and
launchd service. ollama was removed from Linux in 275270cef7, but
remained in Darwin. The build process technically did not fail, but it
did extend build time and is unused, so it was removed. 9. Switch git
program module to use new syntax
2025-12-02 09:56:36 -06:00
14 changed files with 190 additions and 305 deletions

113
flake.lock generated
View file

@ -27,6 +27,27 @@
"type": "github"
}
},
"crowdsec": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1752497357,
"narHash": "sha256-9epXn1+T6U4Kfyw8B9zMzbERxDB3VfaPXhVebtai6CE=",
"ref": "refs/heads/main",
"rev": "84db7dcea77f7f477d79e69e35fb0bb560232667",
"revCount": 42,
"type": "git",
"url": "https://codeberg.org/kampka/nix-flake-crowdsec.git"
},
"original": {
"type": "git",
"url": "https://codeberg.org/kampka/nix-flake-crowdsec.git"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
@ -48,6 +69,23 @@
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"id": "flake-utils",
"type": "indirect"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@ -90,64 +128,6 @@
"type": "github"
}
},
"nix-rosetta-builder": {
"inputs": {
"nixos-generators": "nixos-generators",
"nixpkgs": [
"nixpkgs-darwin"
]
},
"locked": {
"lastModified": 1756177999,
"narHash": "sha256-aSbB7/jrt7ujiJ55f2uGhOo+usGxVSkqbAMVgg2jDls=",
"owner": "cpick",
"repo": "nix-rosetta-builder",
"rev": "ebb7162a975074fb570a2c3ac02bc543ff2e9df4",
"type": "github"
},
"original": {
"owner": "cpick",
"repo": "nix-rosetta-builder",
"type": "github"
}
},
"nixlib": {
"locked": {
"lastModified": 1736643958,
"narHash": "sha256-tmpqTSWVRJVhpvfSN9KXBvKEXplrwKnSZNAoNPf/S/s=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "1418bc28a52126761c02dd3d89b2d8ca0f521181",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixos-generators": {
"inputs": {
"nixlib": "nixlib",
"nixpkgs": [
"nix-rosetta-builder",
"nixpkgs"
]
},
"locked": {
"lastModified": 1737057290,
"narHash": "sha256-3Pe0yKlCc7EOeq1X/aJVDH0CtNL+tIBm49vpepwL1MQ=",
"owner": "nix-community",
"repo": "nixos-generators",
"rev": "d002ce9b6e7eb467cd1c6bb9aef9c35d191b5453",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixos-generators",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1764522689,
@ -258,9 +238,9 @@
"root": {
"inputs": {
"agenix": "agenix",
"crowdsec": "crowdsec",
"home-manager": "home-manager",
"nix-darwin": "nix-darwin",
"nix-rosetta-builder": "nix-rosetta-builder",
"nixpkgs": "nixpkgs",
"nixpkgs-darwin": "nixpkgs-darwin",
"nixpkgs-unstable": "nixpkgs-unstable",
@ -306,6 +286,21 @@
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",

View file

@ -30,6 +30,10 @@
};
# Linux-specific inputs
crowdsec = {
url = "git+https://codeberg.org/kampka/nix-flake-crowdsec.git";
inputs.nixpkgs.follows = "nixpkgs";
};
plasma-manager = {
url = "github:nix-community/plasma-manager";
inputs = {
@ -44,15 +48,11 @@
url = "github:LnL7/nix-darwin/nix-darwin-25.11";
inputs.nixpkgs.follows = "nixpkgs-darwin";
};
nix-rosetta-builder = {
url = "github:cpick/nix-rosetta-builder";
inputs.nixpkgs.follows = "nixpkgs-darwin";
};
};
outputs = { self, nix-darwin, nixpkgs, nixpkgs-darwin, nixpkgs-unstable
, home-manager, agenix, rycee-nurpkgs, nur, plasma-manager, quadlet-nix
, nix-rosetta-builder, ... }:
, home-manager, agenix, rycee-nurpkgs, nur, crowdsec, plasma-manager
, quadlet-nix, ... }:
let
mkHomeConfiguration = { hostname, arch ? "x86_64", os ? "linux"
, desktop ? false, extraModules ? [ ] }:
@ -123,11 +123,8 @@
};
agenix = agenix;
};
modules = [
./systems/darwin/corianne.nix
agenix.darwinModules.default
nix-rosetta-builder.darwinModules.default
];
modules =
[ ./systems/darwin/corianne.nix agenix.darwinModules.default ];
};
nixosConfigurations = {
@ -150,6 +147,9 @@
agenix.nixosModules.default
home-manager.nixosModules.home-manager
quadlet-nix.nixosModules.quadlet
crowdsec.nixosModules.crowdsec
crowdsec.nixosModules.crowdsec-firewall-bouncer
{ nixpkgs.overlays = [ crowdsec.overlays.default ]; }
];
};
};

View file

@ -22,7 +22,6 @@
nil
nixd
nixfmt-classic
nixos-rebuild
quarto
roboto-slab
shellcheck

View file

@ -1,4 +1,4 @@
{ pkgs, ... }: {
{ ... }: {
programs.zed-editor = {
enable = true;
extensions = [
@ -58,22 +58,6 @@
initialization_options.formatting.command = [ "nixfmt" ];
settings.nix.flake.autoArchive = true;
};
texlab = {
settings = {
build = {
onSave = false;
forwardSearchAfter = true;
};
forwardSearch = if pkgs.stdenv.hostPlatform.isDarwin then {
executable =
"/Applications/Skim.app/Contents/SharedSupport/displayline";
args = [ "-r" "%l" "%p" "%f" "-g" ];
} else {
executable = "/usr/bin/okular";
args = [ "--unique" "file:%p#src:%l%f" ];
};
};
};
tinymist = {
settings = {
exportPdf = "onSave";
@ -97,12 +81,5 @@
ui_font_size = 16;
wrap_guides = [ 80 92 120 ];
};
userTasks = [{
label = "latexmk (project)";
command = "latexmk";
args = [ "-synctex=1" "-pdf" "-recorder" ];
cwd = "$ZED_DIRNAME";
tags = [ "latex-build" ];
}];
};
}

View file

@ -34,8 +34,7 @@ in {
++ [ mcentire-host ];
"secrets/darwin-policies-json.age".publicKeys = system-administrators
++ [ corianne-host ];
"secrets/freshrss.toml.age".publicKeys = system-administrators
++ [ mcentire-host ];
"secrets/network-information.age".publicKeys = system-administrators
++ [ bosephus-host ];
"secrets/pihole.age".publicKeys = system-administrators ++ [ bosephus-host ];
}

Binary file not shown.

BIN
secrets/pihole.age Normal file

Binary file not shown.

View file

@ -1,49 +1,101 @@
{ pkgs, config, ... }: {
{ pkgs, config, ... }:
let
crowdsec-port = "2763";
firewall-bouncer-name = "fw-bouncer";
# Although this key can be reproduced by anyone who actually cares to, the
# Crowdsec API will not be exposed to the outside world, so keeping this key
# super secret really isn't that important to me. Still make it look random
# so that hungry botnets can't just slurp up the password in plaintext.
firewall-bouncer-key = builtins.hashString "sha256"
"${config.networking.hostName}-crowdsec-bouncer-salt";
toMultiYAML = items:
pkgs.lib.concatMapStrings (item:
''
---
'' + (pkgs.lib.generators.toYAML { } item) + "\n") items;
in {
services = {
crowdsec = {
enable = true;
localConfig = {
acquisitions = [
{
source = "journalctl";
journalctl_filter = [ "_SYSTEMD_UNIT=sshd.service" ];
labels.type = "syslog";
}
{
filenames = [ "/var/log/auth.log" ];
labels.type = "syslog";
}
{
filenames = [ "/var/log/syslog" "/var/log/kern.log" ];
labels.type = "syslog";
}
];
};
hub = {
collections = [
"crowdsecurity/base-http-scenarios"
"crowdsecurity/http-cve"
"crowdsecurity/http-dos"
"crowdsecurity/iptables"
"crowdsecurity/linux"
"crowdsecurity/sshd"
"crowdsecurity/whitelist-good-actors"
];
};
allowLocalJournalAccess = true;
settings = {
general = { api.server.enable = true; };
# See https://github.com/NixOS/nixpkgs/issues/445342
lapi.credentialsFile = "/var/lib/crowdsec/lapi-credentials.yaml";
api.server = { listen_uri = "127.0.0.1:${crowdsec-port}"; };
crowdsec_service.acquisition_path = pkgs.writeText "acquisitions.yaml"
(toMultiYAML [
{
source = "journalctl";
journalctl_filter = [ "_SYSTEMD_UNIT=sshd.service" ];
labels.type = "syslog";
}
{
filenames = [ "/var/log/auth.log" ];
labels.type = "syslog";
}
{
filenames = [ "/var/log/syslog" "/var/log/kern.log" ];
labels.type = "syslog";
}
]);
};
autoUpdateService = true;
};
crowdsec-firewall-bouncer = {
enable = true;
registerBouncer.enable = true;
settings = {
api_url = "http://localhost:${crowdsec-port}";
api_key = firewall-bouncer-key;
};
};
};
systemd.tmpfiles.rules = let cfg = config.services.crowdsec;
in [ "d /var/lib/crowdsec 0755 ${cfg.user} ${cfg.group}" ];
systemd.services.crowdsec.serviceConfig = {
ExecStartPre = let
bouncer-script = pkgs.writeScriptBin "register-bouncer" ''
#!${pkgs.runtimeShell}
set -eu
set -o pipefail
if ! cscli bouncers list | grep -q "${firewall-bouncer-name}"; then
cscli bouncers add "${firewall-bouncer-name}" --key "${firewall-bouncer-key}"
fi
'';
collection-check = collection: ''
if ! cscli collections list | grep -q "${collection}"; then
cscli collections --trace install "${collection}"
sleep 1
fi
'';
collections = [
"crowdsecurity/base-http-scenarios"
"crowdsecurity/http-cve"
"crowdsecurity/http-dos"
"crowdsecurity/iptables"
"crowdsecurity/linux"
"crowdsecurity/sshd"
"crowdsecurity/whitelist-good-actors"
];
collection-script = pkgs.writeScriptBin "install-collections" ''
#!${pkgs.runtimeShell}
set -eu
set -o pipefail
# I had to run these commands in order to manually install collections
# using cscli.
# Not sure how often they should actually be run, but I would rather
# include this here.
# https://discourse.crowdsec.net/t/solved-cant-find-collections-appsec/1830
cscli capi register
sleep 1
cscli hub update
sleep 1
${pkgs.lib.concatMapStrings collection-check collections}
'';
in [
"${bouncer-script}/bin/register-bouncer"
"${collection-script}/bin/install-collections"
];
};
}

View file

@ -1,146 +0,0 @@
{ config, pkgs, home-manager-quadlet-nix, ... }:
let
user = "freshrss";
port = "37374";
stateDirectory = "/var/lib/freshrss";
serviceContainer = "freshrss";
stateSubDir = subDir: "${stateDirectory}/${subDir}";
createTmpfilesRule = subDir: "d ${stateSubDir subDir} 1755 ${user} ${user}";
dbDirectories = [ "database" ];
serviceDirectories = [ "data" "extensions" ];
in {
age.secrets = {
"freshrss.toml" = {
file = ./../secrets/freshrss.toml.age;
owner = "${user}";
};
};
millironx.podman-secrets.freshrss = {
user = "${user}";
secrets-files = [ config.age.secrets."freshrss.toml".path ];
};
services.caddy.virtualHosts."feeds.millironx.com".extraConfig = ''
reverse_proxy http://127.0.0.1:${port} {
header_up X-Forwarded-Port 443
}
'';
systemd.tmpfiles.rules = builtins.map createTmpfilesRule
([ stateDirectory ] ++ dbDirectories ++ serviceDirectories);
services.borgmatic.configurations."${config.networking.hostName}" = {
source_directories = builtins.map stateSubDir dbDirectories;
postgresql_databases = [{
name = serviceContainer;
psql_command =
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${serviceContainer}-db psql --username=${user}";
pg_dump_command =
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${serviceContainer}-db pg_dump --username=${user}";
pg_restore_command =
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${serviceContainer}-db pg_restore --username=${user}";
}];
};
users.users."${user}" = {
group = "${user}";
isNormalUser = true;
home = "${stateDirectory}";
createHome = true;
linger = true;
autoSubUidGidRange = true;
};
users.groups."${user}" = { };
home-manager.users."${user}" = { config, osConfig, ... }: {
imports = [ home-manager-quadlet-nix ];
home.stateVersion = "25.05";
virtualisation.quadlet = let
inherit (config.virtualisation.quadlet) containers;
inherit (config.virtualisation.quadlet) networks;
secrets = osConfig.millironx.podman-secrets.freshrss;
in {
containers = {
"${serviceContainer}-db" = {
autoStart = true;
containerConfig = {
image = "docker.io/library/postgres:16";
environments = {
POSTGRES_DB = "${user}";
POSTGRES_USER = "${user}";
};
secrets = [
"POSTGRES_PASSWORD,type=env"
"POSTGRES_PASSWORD,type=env,target=PGPASSWORD"
];
healthCmd = "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}";
healthInterval = "30s";
healthRetries = 5;
healthStartPeriod = "20s";
volumes =
[ "${stateDirectory}/database:/var/lib/postgresql/data:U" ];
networks = [ networks."${serviceContainer}".ref ];
};
unitConfig.Requires = [ secrets.ref ];
unitConfig.After = [ secrets.ref ];
};
"${serviceContainer}" = {
autoStart = true;
containerConfig = {
image = "docker.io/freshrss/freshrss:1";
# Required to allow the container to talk to the host ports, in
# other words, to resolve Authentik correctly
addHosts = [ "auth.millironx.com:host-gateway" ];
environments = {
TZ = osConfig.time.timeZone;
CRON_MIN = "2,32";
LISTEN = "0.0.0.0:${port}";
TRUSTED_PROXY = "172.16.0.1/12 192.168.0.1/16";
OIDC_ENABLED = "1";
OIDC_PROVIDER_METADATA_URL =
"https://auth.millironx.com/application/o/freshrss/.well-known/openid-configuration";
OIDC_REMOTE_USER_CLAIM = "preferred_username";
OIDC_SCOPES = "openid email profile";
OIDC_X_FORWARDED_HEADERS =
"X-Forwarded-Host X-Forwarded-Port X-Forwarded-Proto";
};
secrets = [
"OIDC_CLIENT_ID,type=env"
"OIDC_CLIENT_SECRET,type=env"
"OIDC_CLIENT_CRYPTO_KEY,type=env"
];
healthCmd = "cli/health.php";
healthTimeout = "10s";
healthStartPeriod = "60s";
healthStartupInterval = "11s";
healthInterval = "75s";
healthRetries = 3;
networks = [ networks."${serviceContainer}".ref ];
publishPorts = [ "127.0.0.1:${port}:${port}" ];
volumes = [
"${stateDirectory}/data:/var/www/FreshRSS/data:U"
"${stateDirectory}/extensions:/var/www/FreshRSS/extensions:U"
];
};
unitConfig.Requires =
[ secrets.ref containers."${serviceContainer}-db".ref ];
unitConfig.After =
[ secrets.ref containers."${serviceContainer}-db".ref ];
};
};
networks."${serviceContainer}" = { };
autoUpdate.enable = true;
autoEscape = true;
};
};
}

27
services/pihole.nix Normal file
View file

@ -0,0 +1,27 @@
{ config, ... }:
{
age.secrets = {
pihole-credentials = {
file = ./../secrets/pihole.age;
owner = "root";
group = "root";
};
};
virtualisation = {
quadlet = {
containers = {
pihole = {
containerConfig = {
image = "docker.io/pihole/pihole:2025.06.2";
publishPorts =
[ "53:53/tcp" "53:53/udp" "80:80/tcp" "443:443/tcp" ];
environmentFiles = [ config.age.secrets.pihole-credentials.path ];
networks = [ "bridge" ];
dns = [ "127.0.0.1" "194.242.2.9" "9.9.9.9" ];
};
};
};
};
};
}

View file

@ -2,6 +2,7 @@
services.samba = {
enable = true;
package = pkgs.sambaFull;
securityType = "user";
openFirewall = true;
settings = {
global = {

View file

@ -26,27 +26,9 @@ in {
};
# Auto upgrade nix package and the daemon service.
nix = {
enable = true;
gc = {
automatic = true;
interval = { Weekday = 1; };
options = ''
--delete-older-than 14d
'';
};
# Needed for rosetta-builder, see
# <https://github.com/cpick/nix-rosetta-builder/issues/40#issuecomment-3368602687>
# <https://github.com/cpick/nix-rosetta-builder/issues/37>
linux-builder = {
enable = true;
ephemeral = true;
};
extraOptions = ''
extra-platforms = x86_64-darwin
'';
};
nix-rosetta-builder.onDemand = true;
nix.enable = true;
#services.nix-daemon.tempDir = "/nix/tmp";
nix.package = pkgs.nix;
# Create /etc/zshrc that loads the nix-darwin environment.
programs.zsh.enable = true; # default shell on catalina
@ -224,7 +206,6 @@ in {
"rig"
"rstudio"
"signal"
"skim"
"slack"
"stats"
"steam"

View file

@ -9,6 +9,7 @@
./hardware-configuration/bosephus.nix
./hardware-configuration/bosephus-external-drives.nix
./../../services/samba.nix
./../../services/pihole.nix
];
# Bootloader.
@ -16,8 +17,8 @@
boot.loader.efi.canTouchEfiVariables = true;
# Ignore lid - so I can close without having the system go into sleep mode
services.logind.settings.Login.HandleLidSwitch = "ignore";
services.logind.settings.Login.HandleLidSwitchDocked = "ignore";
services.logind.lidSwitch = "ignore";
services.logind.lidSwitchDocked = "ignore";
# Secrets
age.secrets = {

View file

@ -7,7 +7,6 @@
./../../services/borgmatic.nix
./../../services/crowdsec.nix
./../../services/authentik.nix
./../../services/freshrss.nix
];
# Use the GRUB 2 boot loader.