Compare commits

..

10 Commits

14 changed files with 151 additions and 56 deletions

18
flake.lock generated
View File

@@ -7,11 +7,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1767280655, "lastModified": 1767910483,
"narHash": "sha256-YmaYMduV5ko8zURUT1VLGDbVC1L/bxHS0NsiPoZ6bBM=", "narHash": "sha256-MOU5YdVu4DVwuT5ztXgQpPuRRBjSjUGIdUzOQr9iQOY=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "d49d2543f02dbd789ed032188c84570d929223cb", "rev": "82fb7dedaad83e5e279127a38ef410bcfac6d77c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -23,11 +23,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1767325753, "lastModified": 1767799921,
"narHash": "sha256-yA/CuWyqm+AQo2ivGy6PlYrjZBQm7jfbe461+4HF2fo=", "narHash": "sha256-r4GVX+FToWVE2My8VVZH4V0pTIpnu2ZE8/Z4uxGEMBE=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "64049ca74d63e971b627b5f3178d95642e61cedd", "rev": "d351d0653aeb7877273920cd3e823994e7579b0b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -51,11 +51,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1766894905, "lastModified": 1767826491,
"narHash": "sha256-pn8AxxfajqyR/Dmr1wnZYdUXHgM3u6z9x0Z1Ijmz2UQ=", "narHash": "sha256-WSBENPotD2MIhZwolL6GC9npqgaS5fkM7j07V2i/Ur8=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "61b39c7b657081c2adc91b75dd3ad8a91d6f07a7", "rev": "ea3adcb6d2a000d9a69d0e23cad1f2cacb3a9fbe",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -2,9 +2,7 @@
description = "System Configuration"; description = "System Configuration";
inputs = { inputs = {
nixpkgs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-25.11";
url = "github:nixos/nixpkgs?ref=nixos-25.11";
};
home-manager = { home-manager = {
url = "github:nix-community/home-manager?ref=release-25.11"; url = "github:nix-community/home-manager?ref=release-25.11";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
@@ -16,7 +14,11 @@
}; };
outputs = outputs =
{ self, nixpkgs, ... }@inputs: {
self,
nixpkgs,
...
}@inputs:
let let
local = import ./lib; local = import ./lib;
mkNixosConfig = mkNixosConfig =
@@ -31,10 +33,12 @@
modules = [ modules = [
home-manager.nixosModules.home-manager home-manager.nixosModules.home-manager
{ {
home-manager.useGlobalPkgs = true; home-manager = {
home-manager.useUserPackages = true; useGlobalPkgs = true;
home-manager.extraSpecialArgs = { useUserPackages = true;
inherit inputs local; extraSpecialArgs = {
inherit inputs local;
};
}; };
} }
path path
@@ -57,7 +61,7 @@
}; };
}; };
features = { features = {
development = (import ./home-manager/features/development/development.nix); development = import ./home-manager/features/development/development.nix;
}; };
}; };
} }

View File

@@ -1,14 +1,40 @@
{ pkgs, ... }: {
pkgs,
...
}:
let
freecad-wrapped = pkgs.symlinkJoin {
name = "freecad-wrapped";
paths = [ pkgs.freecad ];
buildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/freecad \
--prefix MESA_LOADER_DRIVER_OVERRIDE : zink \
--prefix __EGL_VENDOR_LIBRARY_FILENAMES : ${pkgs.mesa}/share/glvnd/egl_vendor.d/50_mesa.json
'';
};
bambu-studio-wrapped = pkgs.symlinkJoin {
name = "bambu-studio-wrapped";
paths = [ pkgs.bambu-studio ];
buildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/bambu-studio \
--prefix MESA_LOADER_DRIVER_OVERRIDE : zink \
--prefix __EGL_VENDOR_LIBRARY_FILENAMES : ${pkgs.mesa}/share/glvnd/egl_vendor.d/50_mesa.json
'';
};
in
{ {
home.packages = with pkgs; [ home.packages = with pkgs; [
bambu-studio bambu-studio-wrapped
LycheeSlicer LycheeSlicer
orca-slicer orca-slicer
blender blender
freecad freecad-wrapped
openscad openscad
]; ];

View File

@@ -36,7 +36,7 @@
"$terminal" = "foot"; "$terminal" = "foot";
"$menu" = "rofi -show combi -combi-modes drun,ssh,run -theme ~/.config/rofi/launcher/style.rasi"; "$menu" = "rofi -show combi -combi-modes drun,ssh,run -theme ~/.config/rofi/launcher/style.rasi";
"$browser" = "librewolf"; "$browser" = "firefox --new-window";
exec-once = [ exec-once = [
"nm-applet" "nm-applet"

View File

@@ -88,13 +88,13 @@
xdg.mimeApps = { xdg.mimeApps = {
enable = true; enable = true;
defaultApplications = { defaultApplications = {
"text/html" = [ "librewolf.desktop" ]; "text/html" = [ "firefox.desktop" ];
"default-web-browser" = [ "librewolf.desktop" ]; "default-web-browser" = [ "firefox.desktop" ];
"x-scheme-handler/http" = [ "librewolf.desktop" ]; "x-scheme-handler/http" = [ "firefox.desktop" ];
"x-scheme-handler/https" = [ "librewolf.desktop" ]; "x-scheme-handler/https" = [ "firefox.desktop" ];
"x-scheme-handler/about" = [ "librewolf.desktop" ]; "x-scheme-handler/about" = [ "firefox.desktop" ];
"x-scheme-handler/unknown" = [ "librewolf.desktop" ]; "x-scheme-handler/unknown" = [ "firefox.desktop" ];
}; };
}; };
home.sessionVariables.DEFAULT_BROWSER = "${pkgs.librewolf}/bin/librewolf"; home.sessionVariables.DEFAULT_BROWSER = "${pkgs.firefox}/bin/firefox";
} }

View File

@@ -1,5 +1,9 @@
{ {
"extras": [ "extras": [
"lazyvim.plugins.extras.coding.mini-comment",
"lazyvim.plugins.extras.coding.mini-surround",
"lazyvim.plugins.extras.editor.snacks_picker",
"lazyvim.plugins.extras.lang.astro",
"lazyvim.plugins.extras.lang.haskell", "lazyvim.plugins.extras.lang.haskell",
"lazyvim.plugins.extras.lang.json", "lazyvim.plugins.extras.lang.json",
"lazyvim.plugins.extras.lang.markdown", "lazyvim.plugins.extras.lang.markdown",

View File

@@ -3,9 +3,14 @@ return {
"neovim/nvim-lspconfig", "neovim/nvim-lspconfig",
opts = { opts = {
servers = { servers = {
-- Lua
lua_ls = {}, lua_ls = {},
-- Nix
nil_ls = {}, nil_ls = {},
-- Typescript
vtsls = {}, vtsls = {},
-- Haskell
hls = {},
}, },
codelens = { codelens = {
enable = true, enable = true,

View File

@@ -58,8 +58,8 @@
compression = "always"; compression = "always";
}; };
proxima = { proxima = {
id = "7FE67SC-2KQQWQD-OY5Q44O-WPIVQYG-WMWDBEH-SRABY4C-WD3L4AO-GDAYVAX"; id = "NWZL6LY-ULJQMZE-EWY3MQU-XPDAFQB-LTIBZV7-GPKIABJ-WBJE36F-SK6LVAY";
name = "Pixel 6a"; name = "Proxima";
addresses = [ addresses = [
"relay://syncthing.blazestar.net:22067" "relay://syncthing.blazestar.net:22067"
]; ];

View File

@@ -14,6 +14,8 @@ offen:
traefik: traefik:
oauth2-client-secret: ENC[AES256_GCM,data:p7/6OsN2ytBj8mQiK0YL7J6NYLtMHOXIIs/6+bIDpsU=,iv:k6jLZifJEFLYKSFMkyn/kA7iBE+EFB8O/3/3fyTh1SY=,tag:6s49O2+tdlZoXyAGEamuMQ==,type:str] oauth2-client-secret: ENC[AES256_GCM,data:p7/6OsN2ytBj8mQiK0YL7J6NYLtMHOXIIs/6+bIDpsU=,iv:k6jLZifJEFLYKSFMkyn/kA7iBE+EFB8O/3/3fyTh1SY=,tag:6s49O2+tdlZoXyAGEamuMQ==,type:str]
oauth2-plugin-secret: ENC[AES256_GCM,data:sArqwKHAdW35o5kD7DGfXSYCXFUXqvKQdoVnXutsNLw=,iv:qWf597QS3BqkVQkeAb99HbpDB0kUhdD+qKdpUPZEB0o=,tag:vXnb93npaklItWkMZ+/M9Q==,type:str] oauth2-plugin-secret: ENC[AES256_GCM,data:sArqwKHAdW35o5kD7DGfXSYCXFUXqvKQdoVnXutsNLw=,iv:qWf597QS3BqkVQkeAb99HbpDB0kUhdD+qKdpUPZEB0o=,tag:vXnb93npaklItWkMZ+/M9Q==,type:str]
protonvpn:
private_key: ENC[AES256_GCM,data:41pfbR1klj1F24v3HlCCA4ofW2sCEnyE5TH8iX4Ug8D+kmwstTaj5RG2Zz8=,iv:P6XyQnDVoOmdkP8ilBR9DyfqPZA6GsQ6VUwY/tSGhx4=,tag:Bzgdv29lbk/gYlADPZMGVA==,type:str]
deploy-key: deploy-key:
mcp: ENC[AES256_GCM,data:eQcX8xdz5qZ6nU8ISOvZo+ZtP4Z/ePd+/ZZReX1BKvTUqGQPPFxConbLMwFzvzpD6xAUbA1MLkcR/bT98QbNx6LJYlhbofuDUg2DI79RB0fcrAcj/wUV0YPhmgofUdYYDaimH5A2PSvtmKfB3CtKKuA5HNeLymoXeLEpFzbckkGhzPee/CHiUmxayogp6za6btsDJsiT8hdHbrzyD2S6fhMJrzX+PlRzT32M/6eaFuFWE8EUO1gbkRlNfKPXw/EM2GXWJfR4qXfN2YKIKigqrtlAAoxnrUbp5EBrn/hGHS2ZYZXeRUFr3avFjcI0bLX423PWRHAylfQCPxgYVEtbcRv11CAFmq4rfFl0ZdvnAKbTLNmWcrQNijBATZPaAdQzgKPDHs8pwPUFR9Tcg8pZNbzw0mK9kPolniAOL2PBKUHv6LP/uEkB1E6Pxc7yms0kGpeJyo7hrFVOiVAckCey+SI9dpbJMSB3md070I1xk6Ik7PywrWh2QDeUtOU1U28UkYgnJ/9MJelWsNlUX9SR,iv:oCNeanaV/7UZ3dhmq4ZmJUZ5hb61AnHpHCfskM2Jsm8=,tag:F2uJKN5beM/rfiBMSyUP7w==,type:str] mcp: ENC[AES256_GCM,data:eQcX8xdz5qZ6nU8ISOvZo+ZtP4Z/ePd+/ZZReX1BKvTUqGQPPFxConbLMwFzvzpD6xAUbA1MLkcR/bT98QbNx6LJYlhbofuDUg2DI79RB0fcrAcj/wUV0YPhmgofUdYYDaimH5A2PSvtmKfB3CtKKuA5HNeLymoXeLEpFzbckkGhzPee/CHiUmxayogp6za6btsDJsiT8hdHbrzyD2S6fhMJrzX+PlRzT32M/6eaFuFWE8EUO1gbkRlNfKPXw/EM2GXWJfR4qXfN2YKIKigqrtlAAoxnrUbp5EBrn/hGHS2ZYZXeRUFr3avFjcI0bLX423PWRHAylfQCPxgYVEtbcRv11CAFmq4rfFl0ZdvnAKbTLNmWcrQNijBATZPaAdQzgKPDHs8pwPUFR9Tcg8pZNbzw0mK9kPolniAOL2PBKUHv6LP/uEkB1E6Pxc7yms0kGpeJyo7hrFVOiVAckCey+SI9dpbJMSB3md070I1xk6Ik7PywrWh2QDeUtOU1U28UkYgnJ/9MJelWsNlUX9SR,iv:oCNeanaV/7UZ3dhmq4ZmJUZ5hb61AnHpHCfskM2Jsm8=,tag:F2uJKN5beM/rfiBMSyUP7w==,type:str]
matrix: matrix:
@@ -45,7 +47,7 @@ sops:
by9aNFY4dXNxaWxnTXFTQS9reHhuQWMKh5rZ93nFtBV9EpFVRp+E+GXZ6xzVy2Jw by9aNFY4dXNxaWxnTXFTQS9reHhuQWMKh5rZ93nFtBV9EpFVRp+E+GXZ6xzVy2Jw
vFh4deGcAb60q4odSaeWfk1Dr7L9Ua69oK9omjbCNUt+P7Kwlfca7Q== vFh4deGcAb60q4odSaeWfk1Dr7L9Ua69oK9omjbCNUt+P7Kwlfca7Q==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-09-25T22:21:11Z" lastmodified: "2026-02-25T00:28:13Z"
mac: ENC[AES256_GCM,data:1Ru10z/hiMNgzgbBpzuo6jNi5eF87nNMfryurO75k9PvYzsOX4iUwDQf/PppP/YP/g73HJdYaGGEzE8YxaSDtOnmf5qbQe1+5rZmHSO/iIZr/rfV3nkGfqxE4TpPlR/NXB5ktToe7GB6BF1AXwbVIbjWe6Ymsi6Dy2e56Ml1x7k=,iv:v3GV7TL2+BHWETD0mtUBpM/B6vIjNgLiNn45boBjNUg=,tag:a4MplFxRfBF10iwxVGVUOA==,type:str] mac: ENC[AES256_GCM,data:hDmqObrtfoVkQqz8JPkqlyXMbiuyBophjdZNLvTFrZw3pAVNCuzsH4zxFBOaxJttkzLc65DWDHDeEIBY5YZam1GLFFXUQ5E3Dxno7hnyzOoM2ipgDTOacI0gbKJAWgGUF3LNDdqVoREA9LC91LoNUJoNmzpTSFtuLb7ORuwCrH4=,iv:8+W3n1Cr6woEiPU9ECaMYM64HNmFHr2AIw6UohCJi00=,tag:7drkZiPAUHaEx5PagXA9JQ==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.10.2 version: 3.11.0

View File

@@ -79,7 +79,7 @@
}: }:
let let
fqn = "${hostname}.${domain}"; fqn = "${hostname}.${domain}";
serviceName = lib.strings.replaceChars [ "." ] [ "-" ] fqn; serviceName = builtins.replaceStrings [ "." ] [ "-" ] fqn;
routerRule = if public then hostRule hostname domain else localHostRule hostname domain; routerRule = if public then hostRule hostname domain else localHostRule hostname domain;
homepageLabels = homepageLabels =
if homepageOpts == { } then if homepageOpts == { } then
@@ -109,17 +109,16 @@
extraOptions extraOptions
; ;
autoStart = true; autoStart = true;
labels = labels = {
{ "traefik.enable" = "true";
"traefik.enable" = "true"; "traefik.http.routers.${serviceName}.rule" = "${routerRule}";
"traefik.http.routers.${serviceName}.rule" = "${routerRule}"; "traefik.http.routers.${serviceName}.service" = "${serviceName}";
"traefik.http.routers.${serviceName}.service" = "${serviceName}"; "traefik.http.routers.${serviceName}.entrypoints" = "web,websecure";
"traefik.http.routers.${serviceName}.entrypoints" = "web,websecure"; "traefik.http.services.${serviceName}.loadbalancer.server.port" = "${toString port}";
"traefik.http.services.${serviceName}.loadbalancer.server.port" = "${toString port}"; }
} // oauthLabels
// oauthLabels // homepageLabels
// homepageLabels // extraLabels;
// extraLabels;
}; };
in in
builtins.mapAttrs mkContainer config.virtualisation.web-containers.containers builtins.mapAttrs mkContainer config.virtualisation.web-containers.containers

View File

@@ -6,5 +6,6 @@
# ./immich.nix # ./immich.nix
./storyden.nix ./storyden.nix
./tandoor.nix ./tandoor.nix
./wallabag.nix
]; ];
} }

View File

@@ -0,0 +1,19 @@
{ config, ... }:
let
inherit (import ../lib.nix config) havenisms;
in
{
virtualisation.web-containers.containers.wallabag = {
image = "wallabag/wallabag";
hostname = "wallabag";
domain = havenisms;
port = 80;
volumes = [
"wallabag-data:/var/www/wallabag/data"
"wallabag-images:/var/www/wallabag/web/assets/images"
];
environment = {
SYMFONY__ENV__DOMAIN_NAME = "https://wallabag.${havenisms}";
};
};
}

View File

@@ -6,12 +6,45 @@ let
havenisms havenisms
mkContainer mkContainer
; ;
gluetun_env = "gluetun-proton-vpn-wireguard.env";
in in
{ {
sops.secrets = {
"protonvpn/private_key" = {
restartUnits = [ "${config.local.container-backend}-gluetun.service" ];
};
};
# Example Wireguard config file:
# # Key for MCP Wireguard
# # Bouncing = 13
# # NetShield = 1
# # Moderate NAT = off
# # NAT-PMP (Port Forwarding) = on
# # VPN Accelerator = on
# PrivateKey = ${config.sops.placeholder."protonvpn/private_key"}
# Address = 10.2.0.2/32
# DNS = 10.2.0.1
#
# [Peer]
# # US-CA#906
# PublicKey = 2xvxhMK0AalXOMq6Dh0QMVJ0Cl3WQTmWT5tdeb8SpR0=
# AllowedIPs = 0.0.0.0/0, ::/0
# Endpoint = 79.127.185.166:51820
#
# PersistentKeepalive = 25
sops.templates.${gluetun_env}.content = ''
VPN_SERVICE_PROVIDER=protonvpn
VPN_TYPE=wireguard
WIREGUARD_PRIVATE_KEY="${config.sops.placeholder."protonvpn/private_key"}"
SERVER_COUNTRIES="United States,United Kingdom,Netherlands,Switzerland,Sweden"
VPN_PORT_FORWARDING=on
'';
virtualisation.oci-containers.containers = { virtualisation.oci-containers.containers = {
jellyfin = { jellyfin = {
image = "lscr.io/linuxserver/jellyfin"; image = "lscr.io/linuxserver/jellyfin:10.11.6";
autoStart = true; autoStart = true;
extraOptions = [ extraOptions = [
"--device=/dev/dri:/dev/dri" "--device=/dev/dri:/dev/dri"
@@ -110,12 +143,8 @@ in
"127.0.0.1:8083:8000" "127.0.0.1:8083:8000"
]; ];
environmentFiles = [ environmentFiles = [
"/tank/config/gluetun/vpn.env" config.sops.templates.${gluetun_env}.path
]; ];
environment = {
VPN_SERVICE_PROVIDER = "protonvpn";
UMASK = "002";
};
}; };
prowlarr = { prowlarr = {
image = "lscr.io/linuxserver/prowlarr"; image = "lscr.io/linuxserver/prowlarr";

View File

@@ -107,10 +107,16 @@
}; };
# Enable flakes # Enable flakes
nix.settings.experimental-features = [ nix = {
"nix-command" # Binary caches for Reflex FRP
"flakes" binaryCaches = [ "https://nixcache.reflex-frp.org" ];
]; binaryCachePublicKeys = [ "ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI=" ];
settings.experimental-features = [
"nix-command"
"flakes"
];
};
services.openssh.enable = true; services.openssh.enable = true;