12 Commits

Author SHA1 Message Date
bab2df5d7e Use programs.ssh.askPassword
All checks were successful
Check Flake / check-flake (push) Successful in 4m56s
2026-01-11 15:24:53 -08:00
adc04d1bc7 Update nixos mailserver
All checks were successful
Check Flake / check-flake (push) Successful in 18m38s
2026-01-11 14:25:17 -08:00
da9a8f8c03 Update nixpkgs 2026-01-11 14:25:03 -08:00
415cbca33e VLAN workaround for now 2026-01-10 23:04:48 -08:00
51272a172b Add system76-keyboard-configurator to fry 2026-01-10 23:03:19 -08:00
f053c677e8 Set up openwebui + ollama 2026-01-10 23:02:43 -08:00
c130ce6edd Don't generate zed user config file for now 2026-01-10 22:55:31 -08:00
4718326cb6 Configure ssh-agent to work with keepassxc ssh keys 2026-01-10 22:53:28 -08:00
61698aa7e2 Add kde connect 2026-01-10 22:52:17 -08:00
e0af023ac9 barrier was removed from nixpkgs 2026-01-10 22:51:09 -08:00
c0088553ff jellyfin-media-player was removed from nixpkgs 2026-01-10 22:49:04 -08:00
577736fcb2 Add deploy command 2026-01-10 22:46:39 -08:00
25 changed files with 163 additions and 410 deletions

View File

@@ -35,3 +35,8 @@ update-input:
.PHONY: iso .PHONY: iso
iso: iso:
nix build .#packages.x86_64-linux.iso nix build .#packages.x86_64-linux.iso
# Deploy a host by name (ex: 's0')
.PHONY: deploy
deploy:
deploy --remote-build --boot --debug-logs --skip-checks .#$(filter-out $@,$(MAKECMDGOALS))

View File

@@ -46,7 +46,6 @@ in
# hardware accelerated video playback (on intel) # hardware accelerated video playback (on intel)
nixpkgs.config.packageOverrides = pkgs: { nixpkgs.config.packageOverrides = pkgs: {
vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
chromium = pkgs.chromium.override { chromium = pkgs.chromium.override {
enableWideVine = true; enableWideVine = true;
# ungoogled = true; # ungoogled = true;
@@ -61,12 +60,9 @@ in
enable = true; enable = true;
extraPackages = with pkgs; [ extraPackages = with pkgs; [
intel-media-driver # LIBVA_DRIVER_NAME=iHD intel-media-driver # LIBVA_DRIVER_NAME=iHD
vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
# vaapiVdpau
libvdpau-va-gl libvdpau-va-gl
nvidia-vaapi-driver nvidia-vaapi-driver
]; ];
extraPackages32 = with pkgs.pkgsi686Linux; [ vaapiIntel ];
}; };
}; };
} }

View File

@@ -46,11 +46,12 @@ in
spotify spotify
arduino arduino
yt-dlp yt-dlp
jellyfin-media-player
joplin-desktop joplin-desktop
config.inputs.deploy-rs.packages.${config.currentSystem}.deploy-rs config.inputs.deploy-rs.packages.${config.currentSystem}.deploy-rs
lxqt.pavucontrol-qt lxqt.pavucontrol-qt
barrier deskflow
file-roller
android-tools
# For Nix IDE # For Nix IDE
nixpkgs-fmt nixpkgs-fmt
@@ -71,15 +72,10 @@ in
services.avahi.enable = true; services.avahi.enable = true;
services.avahi.nssmdns4 = true; services.avahi.nssmdns4 = true;
programs.file-roller.enable = true;
# Security # Security
services.gnome.gnome-keyring.enable = true; services.gnome.gnome-keyring.enable = true;
security.pam.services.googlebot.enableGnomeKeyring = true; security.pam.services.googlebot.enableGnomeKeyring = true;
# Android dev
programs.adb.enable = true;
# Mount personal SMB stores # Mount personal SMB stores
services.mount-samba.enable = true; services.mount-samba.enable = true;
@@ -94,5 +90,9 @@ in
environment.sessionVariables.NIXOS_OZONE_WL = "1"; environment.sessionVariables.NIXOS_OZONE_WL = "1";
fonts.packages = with pkgs; [ nerd-fonts.symbols-only ]; fonts.packages = with pkgs; [ nerd-fonts.symbols-only ];
# SSH Ask pass
programs.ssh.enableAskPassword = true;
programs.ssh.askPassword = "${pkgs.kdePackages.ksshaskpass}/bin/ksshaskpass";
}; };
} }

View File

@@ -15,6 +15,7 @@ in
# kmail # kmail
# plasma5Packages.kmail-account-wizard # plasma5Packages.kmail-account-wizard
kdePackages.kate kdePackages.kate
kdePackages.kdeconnect-kde
]; ];
}; };
} }

View File

@@ -3,10 +3,10 @@
with lib; with lib;
let let
cfg = config.services.librechat; cfg = config.services.librechat-container;
in in
{ {
options.services.librechat = { options.services.librechat-container = {
enable = mkEnableOption "librechat"; enable = mkEnableOption "librechat";
port = mkOption { port = mkOption {
type = types.int; type = types.int;
@@ -21,7 +21,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
virtualisation.oci-containers.containers = { virtualisation.oci-containers.containers = {
librechat = { librechat = {
image = "ghcr.io/danny-avila/librechat:v0.7.7"; image = "ghcr.io/danny-avila/librechat:v0.8.1";
environment = { environment = {
HOST = "0.0.0.0"; HOST = "0.0.0.0";
MONGO_URI = "mongodb://host.containers.internal:27017/LibreChat"; MONGO_URI = "mongodb://host.containers.internal:27017/LibreChat";

View File

@@ -63,18 +63,28 @@ in
"cris@runyan.org" "cris@runyan.org"
]; ];
}; };
certificateScheme = "acme-nginx"; # use let's encrypt for certs x509.useACMEHost = config.mailserver.fqdn; # use let's encrypt for certs
stateVersion = 3;
}; };
age.secrets.hashed-email-pw.file = ../../secrets/hashed-email-pw.age; age.secrets.hashed-email-pw.file = ../../secrets/hashed-email-pw.age;
age.secrets.cris-hashed-email-pw.file = ../../secrets/cris-hashed-email-pw.age; age.secrets.cris-hashed-email-pw.file = ../../secrets/cris-hashed-email-pw.age;
age.secrets.hashed-robots-email-pw.file = ../../secrets/hashed-robots-email-pw.age; age.secrets.hashed-robots-email-pw.file = ../../secrets/hashed-robots-email-pw.age;
# Get let's encrypt cert
services.nginx = {
enable = true;
virtualHosts."${config.mailserver.fqdn}" = {
forceSSL = true;
enableACME = true;
};
};
# sendmail to use xxx@domain instead of xxx@mail.domain # sendmail to use xxx@domain instead of xxx@mail.domain
services.postfix.origin = "$mydomain"; services.postfix.settings.main.myorigin = "$mydomain";
# relay sent mail through mailgun # relay sent mail through mailgun
# https://www.howtoforge.com/community/threads/different-smtp-relays-for-different-domains-in-postfix.82711/#post-392620 # https://www.howtoforge.com/community/threads/different-smtp-relays-for-different-domains-in-postfix.82711/#post-392620
services.postfix.config = { services.postfix.settings.main = {
smtp_sasl_auth_enable = "yes"; smtp_sasl_auth_enable = "yes";
smtp_sasl_security_options = "noanonymous"; smtp_sasl_security_options = "noanonymous";
smtp_sasl_password_maps = "hash:/var/lib/postfix/conf/sasl_relay_passwd"; smtp_sasl_password_maps = "hash:/var/lib/postfix/conf/sasl_relay_passwd";
@@ -92,7 +102,6 @@ in
age.secrets.sasl_relay_passwd.file = ../../secrets/sasl_relay_passwd.age; age.secrets.sasl_relay_passwd.file = ../../secrets/sasl_relay_passwd.age;
# webmail # webmail
services.nginx.enable = true;
services.roundcube = { services.roundcube = {
enable = true; enable = true;
hostName = config.mailserver.fqdn; hostName = config.mailserver.fqdn;

View File

@@ -16,7 +16,7 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
services.nextcloud = { services.nextcloud = {
https = true; https = true;
package = pkgs.nextcloud31; package = pkgs.nextcloud32;
hostName = nextcloudHostname; hostName = nextcloudHostname;
config.dbtype = "sqlite"; config.dbtype = "sqlite";
config.adminuser = "jeremy"; config.adminuser = "jeremy";

89
flake.lock generated
View File

@@ -14,11 +14,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1754433428, "lastModified": 1762618334,
"narHash": "sha256-NA/FT2hVhKDftbHSwVnoRTFhes62+7dxZbxj5Gxvghs=", "narHash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ=",
"owner": "ryantm", "owner": "ryantm",
"repo": "agenix", "repo": "agenix",
"rev": "9edb1787864c4f59ae5074ad498b6272b3ec308d", "rev": "fcdea223397448d35d9b31f798479227e80183f6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -101,11 +101,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1756719547, "lastModified": 1766051518,
"narHash": "sha256-N9gBKUmjwRKPxAafXEk1EGadfk2qDZPBQp4vXWPHINQ=", "narHash": "sha256-znKOwPXQnt3o7lDb3hdf19oDo0BLP4MfBOYiWkEHoik=",
"owner": "serokell", "owner": "serokell",
"repo": "deploy-rs", "repo": "deploy-rs",
"rev": "125ae9e3ecf62fb2c0fd4f2d894eb971f1ecaed2", "rev": "d5eff7f948535b9c723d60cd8239f8f11ddc90fa",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -117,11 +117,11 @@
"flake-compat": { "flake-compat": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1747046372, "lastModified": 1767039857,
"narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "edolstra", "owner": "edolstra",
"repo": "flake-compat", "repo": "flake-compat",
"rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -163,11 +163,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1742649964, "lastModified": 1763988335,
"narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=", "narHash": "sha256-QlcnByMc8KBjpU37rbq5iP7Cp97HvjRP0ucfdh+M4Qc=",
"owner": "cachix", "owner": "cachix",
"repo": "git-hooks.nix", "repo": "git-hooks.nix",
"rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82", "rev": "50b9238891e388c9fdc6a5c49e49c42533a1b5ce",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -205,16 +205,16 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1758463745, "lastModified": 1768068402,
"narHash": "sha256-uhzsV0Q0I9j2y/rfweWeGif5AWe0MGrgZ/3TjpDYdGA=", "narHash": "sha256-bAXnnJZKJiF7Xr6eNW6+PhBf1lg2P1aFUO9+xgWkXfA=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "3b955f5f0a942f9f60cdc9cacb7844335d0f21c3", "rev": "8bc5473b6bc2b6e1529a9c4040411e1199c43b4c",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "nix-community",
"ref": "release-25.05", "ref": "master",
"repo": "home-manager", "repo": "home-manager",
"type": "github" "type": "github"
} }
@@ -226,11 +226,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1760241904, "lastModified": 1765267181,
"narHash": "sha256-OD7QnaGEVNdukYEbJbUNWPsvnDrpbZOZxVIk6Pt9Jhw=", "narHash": "sha256-d3NBA9zEtBu2JFMnTBqWj7Tmi7R5OikoU2ycrdhQEws=",
"owner": "Mic92", "owner": "Mic92",
"repo": "nix-index-database", "repo": "nix-index-database",
"rev": "c9f5ea45f25652ec2f771f9426ccacb21cbbaeaa", "rev": "82befcf7dc77c909b0f2a09f5da910ec95c5b78f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -241,11 +241,11 @@
}, },
"nixos-hardware": { "nixos-hardware": {
"locked": { "locked": {
"lastModified": 1759582739, "lastModified": 1767185284,
"narHash": "sha256-spZegilADH0q5OngM86u6NmXxduCNv5eX9vCiUPhOYc=", "narHash": "sha256-ljDBUDpD1Cg5n3mJI81Hz5qeZAwCGxon4kQW3Ho3+6Q=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "3441b5242af7577230a78ffb03542add264179ab", "rev": "40b1a28dce561bea34858287fbb23052c3ee63fe",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -257,44 +257,20 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1759884237, "lastModified": 1768105724,
"narHash": "sha256-tfTIIUVKUG1pRahjhQEdp3N9PJ7+ca10HJoHF31ezxE=", "narHash": "sha256-0edMCoDc1VpuqDjy0oz8cDa4kjRuhXE3040sac2iZW4=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "ebea684a18162e8a4210f739fcd459a74bc8d7ff", "rev": "4c41b0361812441bf3b4427195e57ab271d5167f",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "release-25.05", "ref": "master",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs-linkwarden": {
"flake": false,
"locked": {
"narHash": "sha256-wW3F+iRM/ATWkyq8+Romal8oFmsM/p98V96d5G0tasA=",
"type": "file",
"url": "https://github.com/NixOS/nixpkgs/pull/347353.diff"
},
"original": {
"type": "file",
"url": "https://github.com/NixOS/nixpkgs/pull/347353.diff"
}
},
"nixpkgs-memos": {
"flake": false,
"locked": {
"narHash": "sha256-UidUaQY+9vo90rNCVInX1E+JbJ1xKFVSTMNRYKQEKpQ=",
"type": "file",
"url": "https://github.com/NixOS/nixpkgs/pull/426687.diff"
},
"original": {
"type": "file",
"url": "https://github.com/NixOS/nixpkgs/pull/426687.diff"
}
},
"root": { "root": {
"inputs": { "inputs": {
"agenix": "agenix", "agenix": "agenix",
@@ -306,8 +282,6 @@
"nix-index-database": "nix-index-database", "nix-index-database": "nix-index-database",
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"nixpkgs-linkwarden": "nixpkgs-linkwarden",
"nixpkgs-memos": "nixpkgs-memos",
"simple-nixos-mailserver": "simple-nixos-mailserver", "simple-nixos-mailserver": "simple-nixos-mailserver",
"systems": "systems" "systems": "systems"
} }
@@ -321,22 +295,19 @@
"git-hooks": "git-hooks", "git-hooks": "git-hooks",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
],
"nixpkgs-25_05": [
"nixpkgs"
] ]
}, },
"locked": { "locked": {
"lastModified": 1755110674, "lastModified": 1766321686,
"narHash": "sha256-PigqTAGkdBYXVFWsJnqcirrLeFqRFN4PFigLA8FzxeI=", "narHash": "sha256-icOWbnD977HXhveirqA10zoqvErczVs3NKx8Bj+ikHY=",
"owner": "simple-nixos-mailserver", "owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver", "repo": "nixos-mailserver",
"rev": "f5936247dbdb8501221978562ab0b302dd75456c", "rev": "7d433bf89882f61621f95082e90a4ab91eb0bdd3",
"type": "gitlab" "type": "gitlab"
}, },
"original": { "original": {
"owner": "simple-nixos-mailserver", "owner": "simple-nixos-mailserver",
"ref": "nixos-25.05", "ref": "master",
"repo": "nixos-mailserver", "repo": "nixos-mailserver",
"type": "gitlab" "type": "gitlab"
} }

View File

@@ -1,15 +1,7 @@
{ {
inputs = { inputs = {
# nixpkgs # nixpkgs
nixpkgs.url = "github:NixOS/nixpkgs/release-25.05"; nixpkgs.url = "github:NixOS/nixpkgs/master";
nixpkgs-linkwarden = {
url = "https://github.com/NixOS/nixpkgs/pull/347353.diff";
flake = false;
};
nixpkgs-memos = {
url = "https://github.com/NixOS/nixpkgs/pull/426687.diff";
flake = false;
};
# Common Utils Among flake inputs # Common Utils Among flake inputs
systems.url = "github:nix-systems/default"; systems.url = "github:nix-systems/default";
@@ -27,16 +19,15 @@
# Home Manager # Home Manager
home-manager = { home-manager = {
url = "github:nix-community/home-manager/release-25.05"; url = "github:nix-community/home-manager/master";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
# Mail Server # Mail Server
simple-nixos-mailserver = { simple-nixos-mailserver = {
url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-25.05"; url = "gitlab:simple-nixos-mailserver/nixos-mailserver/master";
inputs = { inputs = {
nixpkgs.follows = "nixpkgs"; nixpkgs.follows = "nixpkgs";
nixpkgs-25_05.follows = "nixpkgs";
flake-compat.follows = "flake-compat"; flake-compat.follows = "flake-compat";
}; };
}; };
@@ -126,14 +117,7 @@
name = "nixpkgs-patched"; name = "nixpkgs-patched";
src = nixpkgs; src = nixpkgs;
patches = [ patches = [
# ./patches/gamepadui.patch
./patches/dont-break-nix-serve.patch ./patches/dont-break-nix-serve.patch
# music-assistant needs a specific custom version of librespot
# I tried to use an overlay but my attempts to override the rust package did not work out
# despite me following guides and examples specific to rust packages.
./patches/librespot-pin.patch
inputs.nixpkgs-linkwarden
inputs.nixpkgs-memos
]; ];
}; };
patchedNixpkgs = nixpkgs.lib.fix (self: (import "${patchedNixpkgsSrc}/flake.nix").outputs { self = nixpkgs; }); patchedNixpkgs = nixpkgs.lib.fix (self: (import "${patchedNixpkgsSrc}/flake.nix").outputs { self = nixpkgs; });

View File

@@ -54,70 +54,5 @@ in
programs.zed-editor = { programs.zed-editor = {
enable = thisMachineIsPersonal; enable = thisMachineIsPersonal;
extensions = [
"nix"
"toml"
"html"
"make"
"git-firefly"
"vue"
"scss"
];
userSettings = {
assistant = {
enabled = true;
version = "2";
default_model = {
provider = "openai";
model = "gpt-4-turbo";
};
};
features = {
edit_prediction_provider = "zed";
};
node = {
path = lib.getExe pkgs.nodejs;
npm_path = lib.getExe' pkgs.nodejs "npm";
};
auto_update = false;
terminal = {
blinking = "off";
copy_on_select = false;
};
lsp = {
rust-analyzer = {
# binary = {
# path = lib.getExe pkgs.rust-analyzer;
# };
binary = {
path = "/run/current-system/sw/bin/nix";
arguments = [ "develop" "--command" "rust-analyzer" ];
};
initialization_options = {
cargo = {
features = "all";
};
};
};
};
# tell zed to use direnv and direnv can use a flake.nix enviroment.
load_direnv = "shell_hook";
base_keymap = "VSCode";
theme = {
mode = "system";
light = "One Light";
dark = "Andrometa";
};
ui_font_size = 12;
buffer_font_size = 12;
};
}; };
} }

View File

@@ -9,4 +9,62 @@
nix.distributedBuilds = lib.mkForce false; nix.distributedBuilds = lib.mkForce false;
nix.gc.automatic = lib.mkForce false; nix.gc.automatic = lib.mkForce false;
environment.systemPackages = with pkgs; [
system76-keyboard-configurator
];
services.ollama = {
enable = true;
package = pkgs.ollama-vulkan;
host = "127.0.0.1";
};
services.open-webui = {
enable = true;
host = "127.0.0.1"; # nginx proxy
port = 12831;
environment = {
ANONYMIZED_TELEMETRY = "False";
DO_NOT_TRACK = "True";
SCARF_NO_ANALYTICS = "True";
OLLAMA_API_BASE_URL = "http://localhost:${toString config.services.ollama.port}";
};
};
# nginx
services.nginx = {
enable = true;
openFirewall = false; # All nginx services are internal
virtualHosts =
let
mkHost = external: config:
{
${external} = {
useACMEHost = "fry.neet.dev"; # Use wildcard cert
forceSSL = true;
locations."/" = config;
};
};
mkVirtualHost = external: internal:
mkHost external {
proxyPass = internal;
proxyWebsockets = true;
};
in
lib.mkMerge [
(mkVirtualHost "chat.fry.neet.dev" "http://localhost:${toString config.services.open-webui.port}")
];
};
# Get wildcard cert
security.acme.certs."fry.neet.dev" = {
dnsProvider = "digitalocean";
credentialsFile = "/run/agenix/digitalocean-dns-credentials";
extraDomainNames = [ "*.fry.neet.dev" ];
group = "nginx";
dnsResolver = "1.1.1.1:53";
dnsPropagationCheck = false; # sadly this erroneously fails
};
age.secrets.digitalocean-dns-credentials.file = ../../secrets/digitalocean-dns-credentials.age;
} }

View File

@@ -7,6 +7,7 @@
systemRoles = [ systemRoles = [
"personal" "personal"
"dns-challenge"
]; ];
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID/Df5lG07Il7fizEgZR/T9bMlR0joESRJ7cqM9BkOyP"; hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID/Df5lG07Il7fizEgZR/T9bMlR0joESRJ7cqM9BkOyP";

View File

@@ -109,6 +109,6 @@
services.owncast.hostname = "live.neet.dev"; services.owncast.hostname = "live.neet.dev";
# librechat # librechat
services.librechat.enable = true; services.librechat-container.enable = true;
services.librechat.host = "chat.neet.dev"; services.librechat-container.host = "chat.neet.dev";
} }

View File

@@ -104,6 +104,7 @@
services.transmission = { services.transmission = {
enable = true; enable = true;
package = pkgs.transmission_4;
performanceNetParameters = true; performanceNetParameters = true;
user = "public_data"; user = "public_data";
group = "public_data"; group = "public_data";
@@ -179,15 +180,10 @@
# I could not figure out how to allow the container to access the encoder # I could not figure out how to allow the container to access the encoder
services.jellyfin.enable = true; services.jellyfin.enable = true;
users.users.${config.services.jellyfin.user}.extraGroups = [ "public_data" ]; users.users.${config.services.jellyfin.user}.extraGroups = [ "public_data" ];
nixpkgs.config.packageOverrides = pkgs: {
vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
};
hardware.graphics = { hardware.graphics = {
enable = true; enable = true;
extraPackages = with pkgs; [ extraPackages = with pkgs; [
intel-media-driver intel-media-driver
vaapiIntel
vaapiVdpau
libvdpau-va-gl libvdpau-va-gl
intel-compute-runtime # OpenCL filter support (hardware tonemapping and subtitle burn-in) intel-compute-runtime # OpenCL filter support (hardware tonemapping and subtitle burn-in)
]; ];
@@ -252,7 +248,7 @@
(mkVirtualHost "todo.s0.neet.dev" "http://localhost:${toString config.services.vikunja.port}") (mkVirtualHost "todo.s0.neet.dev" "http://localhost:${toString config.services.vikunja.port}")
(mkVirtualHost "budget.s0.neet.dev" "http://localhost:${toString config.services.actual.settings.port}") # actual budget (mkVirtualHost "budget.s0.neet.dev" "http://localhost:${toString config.services.actual.settings.port}") # actual budget
(mkVirtualHost "linkwarden.s0.neet.dev" "http://localhost:${toString config.services.linkwarden.port}") (mkVirtualHost "linkwarden.s0.neet.dev" "http://localhost:${toString config.services.linkwarden.port}")
(mkVirtualHost "memos.s0.neet.dev" "http://localhost:${toString config.services.memos.port}") (mkVirtualHost "memos.s0.neet.dev" "http://localhost:${toString config.services.memos.settings.MEMOS_PORT}")
(mkVirtualHost "outline.s0.neet.dev" "http://localhost:${toString config.services.outline.port}") (mkVirtualHost "outline.s0.neet.dev" "http://localhost:${toString config.services.outline.port}")
(mkVirtualHost "languagetool.s0.neet.dev" "http://localhost:${toString config.services.languagetool.port}") (mkVirtualHost "languagetool.s0.neet.dev" "http://localhost:${toString config.services.languagetool.port}")
]; ];
@@ -328,15 +324,7 @@
enableRegistration = true; enableRegistration = true;
port = 41709; port = 41709;
environment.NEXTAUTH_URL = "https://linkwarden.s0.neet.dev/api/v1/auth"; environment.NEXTAUTH_URL = "https://linkwarden.s0.neet.dev/api/v1/auth";
environment.FLARESOLVERR_URL = "http://localhost:${toString config.services.flaresolverr.port}/v1";
environmentFile = "/run/agenix/linkwarden-environment"; environmentFile = "/run/agenix/linkwarden-environment";
package = pkgs.linkwarden.overrideAttrs (oldAttrs: {
# Add patch that adds support for flaresolverr
patches = oldAttrs.patches or [ ] ++ [
# https://github.com/linkwarden/linkwarden/pull/1251
../../../patches/linkwarden-flaresolverr.patch
];
});
}; };
age.secrets.linkwarden-environment.file = ../../../secrets/linkwarden-environment.age; age.secrets.linkwarden-environment.file = ../../../secrets/linkwarden-environment.age;
services.meilisearch = { services.meilisearch = {
@@ -351,8 +339,7 @@
services.memos = { services.memos = {
enable = true; enable = true;
address = "127.0.0.1"; settings.MEMOS_PORT = "57643";
port = 57643;
}; };
services.outline = { services.outline = {

View File

@@ -84,6 +84,11 @@ lib.mkMerge [
services.frigate = { services.frigate = {
enable = true; enable = true;
hostname = frigateHostname; hostname = frigateHostname;
# Sadly this fails because it doesn't support frigate's var substition format
# which is critical... so what's even the point of it then?
checkConfig = false;
settings = { settings = {
mqtt = { mqtt = {
enabled = true; enabled = true;

View File

@@ -63,29 +63,42 @@
# systemd.network.enable = true; # systemd.network.enable = true;
networking = { networking = {
# useNetworkd = true; # useNetworkd = true;
dhcpcd.enable = false; dhcpcd.enable = true;
interfaces."eth0".useDHCP = true;
interfaces."eth1".useDHCP = false;
interfaces."main@eth1".useDHCP = true;
interfaces."iot@eth1".useDHCP = true;
interfaces."management@eth1".useDHCP = true;
vlans = { vlans = {
main = {
id = 5;
interface = "eth1";
};
iot = { iot = {
id = 2; id = 2;
interface = "eth1"; interface = "eth1";
}; };
management = {
id = 4;
interface = "eth1";
};
}; };
interfaces.eth1.ipv4.addresses = [{ # interfaces.eth1.ipv4.addresses = [{
address = "192.168.1.2"; # address = "192.168.1.2";
prefixLength = 21; # prefixLength = 21;
}]; # }];
interfaces.iot.ipv4.addresses = [{ # interfaces.iot.ipv4.addresses = [{
address = "192.168.9.8"; # address = "192.168.9.8";
prefixLength = 22; # prefixLength = 22;
}]; # }];
defaultGateway = { defaultGateway = {
interface = "eth1"; # interface = "eth1";
address = "192.168.1.1"; address = "192.168.1.1";
}; };
nameservers = [ "1.1.1.1" "8.8.8.8" ]; # nameservers = [ "1.1.1.1" "8.8.8.8" ];
}; };
powerManagement.cpuFreqGovernor = "powersave"; powerManagement.cpuFreqGovernor = "powersave";

View File

@@ -29,7 +29,6 @@
services.zigbee2mqtt = { services.zigbee2mqtt = {
enable = true; enable = true;
settings = { settings = {
homeassistant = true;
permit_join = false; permit_join = false;
serial = { serial = {
adapter = "ember"; adapter = "ember";

View File

@@ -17,6 +17,7 @@
"media-server" "media-server"
"linkwarden" "linkwarden"
"outline" "outline"
"dns-challenge"
]; ];
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAwiXcUFtAvZCayhu4+AIcF+Ktrdgv9ee/mXSIhJbp4q"; hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAwiXcUFtAvZCayhu4+AIcF+Ktrdgv9ee/mXSIhJbp4q";

View File

@@ -20,10 +20,6 @@
); );
services.mount-samba.enable = true; services.mount-samba.enable = true;
# Login DE Option: RetroArch
services.xserver.desktopManager.retroarch.enable = true;
services.xserver.desktopManager.retroarch.package = pkgs.retroarchFull;
# wireless xbox controller support # wireless xbox controller support
hardware.xone.enable = true; hardware.xone.enable = true;
boot.kernelModules = [ "xone-wired" "xone-dongle" ]; boot.kernelModules = [ "xone-wired" "xone-dongle" ];
@@ -39,28 +35,6 @@
"L+ /opt/rocm/hip - - - - ${pkgs.rocmPackages.clr}" "L+ /opt/rocm/hip - - - - ${pkgs.rocmPackages.clr}"
]; ];
# System wide barrier instance
# systemd.services.barrier-sddm = {
# description = "Barrier mouse/keyboard share";
# requires = [ "display-manager.service" ];
# after = [ "network.target" "display-manager.service" ];
# wantedBy = [ "multi-user.target" ];
# serviceConfig = {
# Restart = "always";
# RestartSec = 10;
# # todo use user/group
# };
# path = with pkgs; [ barrier doas ];
# script = ''
# # Wait for file to show up. "display-manager.service" finishes a bit too soon
# while ! [ -e /run/sddm/* ]; do sleep 1; done;
# export XAUTHORITY=$(ls /run/sddm/*)
# # Disable crypto is fine because tailscale is E2E encrypting better than barrier could anyway
# barrierc -f --disable-crypto --name zoidberg ray.koi-bebop.ts.net
# '';
# };
# Login into X11 plasma so barrier works well
services.displayManager.defaultSession = "plasma"; services.displayManager.defaultSession = "plasma";
users.users.cris = { users.users.cris = {
@@ -89,19 +63,17 @@
}; };
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
jellyfin-media-player
config.services.xserver.desktopManager.kodi.package config.services.xserver.desktopManager.kodi.package
spotify spotify
retroarchFull
]; ];
# Command and Conquer Ports # Command and Conquer Ports
networking.firewall.allowedUDPPorts = [ 4321 27900 ]; networking.firewall.allowedUDPPorts = [ 4321 27900 ];
networking.firewall.allowedTCPPorts = [ 6667 28910 29900 29920 ]; networking.firewall.allowedTCPPorts = [ 6667 28910 29900 29920 ];
nixpkgs.config.rocmSupport = true;
services.ollama = { services.ollama = {
enable = true; enable = true;
acceleration = "rocm"; package = pkgs.ollama-vulkan;
host = "127.0.0.1";
}; };
} }

View File

@@ -1,8 +1,8 @@
diff --git a/nixos/modules/services/video/frigate.nix b/nixos/modules/services/video/frigate.nix diff --git a/nixos/modules/services/video/frigate.nix b/nixos/modules/services/video/frigate.nix
index 49f8ed673816..643b59d68dde 100644 index f8d8f64e55da..39326d094118 100644
--- a/nixos/modules/services/video/frigate.nix --- a/nixos/modules/services/video/frigate.nix
+++ b/nixos/modules/services/video/frigate.nix +++ b/nixos/modules/services/video/frigate.nix
@@ -482,10 +482,6 @@ in @@ -609,10 +609,6 @@ in
}; };
}; };
extraConfig = '' extraConfig = ''

View File

@@ -1,13 +0,0 @@
diff --git a/nixos/modules/programs/steam.nix b/nixos/modules/programs/steam.nix
index 29c449c16946..f6c728eb7f0c 100644
--- a/nixos/modules/programs/steam.nix
+++ b/nixos/modules/programs/steam.nix
@@ -11,7 +11,7 @@ let
in
pkgs.writeShellScriptBin "steam-gamescope" ''
${builtins.concatStringsSep "\n" exports}
- gamescope --steam ${builtins.toString cfg.gamescopeSession.args} -- steam -tenfoot -pipewire-dmabuf
+ gamescope --steam ${builtins.toString cfg.gamescopeSession.args} -- steam -gamepadui -steamdeck -pipewire-dmabuf &> /tmp/steamlog
'';
gamescopeSessionFile =

View File

@@ -1,27 +0,0 @@
diff --git a/pkgs/applications/audio/librespot/default.nix b/pkgs/applications/audio/librespot/default.nix
index f5ff221e1bfe..b85f6b53af1d 100644
--- a/pkgs/applications/audio/librespot/default.nix
+++ b/pkgs/applications/audio/librespot/default.nix
@@ -25,13 +25,18 @@ rustPlatform.buildRustPackage rec {
version = "0.6.0";
src = fetchFromGitHub {
- owner = "librespot-org";
+ owner = "googlebot42";
repo = "librespot";
- rev = "v${version}";
- sha256 = "sha256-dGQDRb7fgIkXelZKa+PdodIs9DxbgEMlVGJjK/hU3Mo=";
+ rev = "ab9ecb6d936edf24b18258be981966692e705a02";
+ sha256 = "sha256-7Wx7+2OYAczNKzqRH2v8fwNAfll27Bdr3Fo23uDtQ4Y=";
};
- cargoHash = "sha256-SqvJSHkyd1IicT6c4pE96dBJNNodULhpyG14HRGVWCk=";
+ cargoHash = "sha256-s6qUI+pDyfBRhuPuBsi2eVxH9DLXEgISf/N4ZY3zDgc=";
+
+ cargoBuildFlags = [
+ "--features"
+ "passthrough-decoder"
+ ];
nativeBuildInputs = [
pkg-config

View File

@@ -1,144 +0,0 @@
commit 3dac9f081f267e4a528decbd9d50e1f45ea7c2ba
Author: SteveImmanuel <steve@telepix.net>
Date: Fri Jun 27 13:07:38 2025 +0900
Add flaresolverr support into linkwarden
diff --git a/.env.sample b/.env.sample
index bd3abcb0..0ca96d92 100644
--- a/.env.sample
+++ b/.env.sample
@@ -43,6 +43,7 @@ TEXT_CONTENT_LIMIT=
SEARCH_FILTER_LIMIT=
INDEX_TAKE_COUNT=
MEILI_TIMEOUT=
+FLARESOLVERR_URL=
# AI Settings
NEXT_PUBLIC_OLLAMA_ENDPOINT_URL=
diff --git a/apps/worker/lib/archiveHandler.ts b/apps/worker/lib/archiveHandler.ts
index 8ae19e2c..6c8656b2 100644
--- a/apps/worker/lib/archiveHandler.ts
+++ b/apps/worker/lib/archiveHandler.ts
@@ -6,6 +6,7 @@ import {
chromium,
devices,
} from "playwright";
+import axios from 'axios';
import { prisma } from "@linkwarden/prisma";
import sendToWayback from "./preservationScheme/sendToWayback";
import { AiTaggingMethod } from "@linkwarden/prisma/client";
@@ -75,6 +76,22 @@ export default async function archiveHandler(
});
const { browser, context } = await getBrowser();
+
+ const captchaSolve = await solveCaptcha(link.url);
+
+ if (captchaSolve.status === 'error') {
+ console.error('Error solving captcha');
+ } else if (captchaSolve.status === 'fail') {
+ console.warn('Failed solving captcha');
+ } else if (captchaSolve.status === 'skip') {
+ console.info('Skip solving captcha');
+ } else {
+ if (captchaSolve.solution) {
+ console.info('Solving captcha');
+ await context.addCookies(captchaSolve.solution.cookies);
+ }
+ }
+
const page = await context.newPage();
createFolder({ filePath: `archives/preview/${link.collectionId}` });
@@ -105,6 +122,7 @@ export default async function archiveHandler(
aiTag: user.aiTaggingMethod !== AiTaggingMethod.DISABLED,
};
+ let newLinkName = '';
try {
await Promise.race([
(async () => {
@@ -127,6 +145,7 @@ export default async function archiveHandler(
// archive url
await page.goto(link.url, { waitUntil: "domcontentloaded" });
+ newLinkName = await page.title();
const metaDescription = await page.evaluate(() => {
const description = document.querySelector(
@@ -186,10 +205,16 @@ export default async function archiveHandler(
where: { id: link.id },
});
- if (finalLink)
+ if (finalLink) {
+ // Replace the captcha-blocked link name if it has not been updated by user, else keep the same name
+ if (newLinkName === '' || finalLink.name === newLinkName || finalLink.name !== 'Just a moment...') {
+ newLinkName = finalLink.name;
+ }
+
await prisma.link.update({
where: { id: link.id },
data: {
+ name: newLinkName,
lastPreserved: new Date().toISOString(),
readable: !finalLink.readable ? "unavailable" : undefined,
image: !finalLink.image ? "unavailable" : undefined,
@@ -203,6 +228,7 @@ export default async function archiveHandler(
: undefined,
},
});
+ }
else {
await removeFiles(link.id, link.collectionId);
}
@@ -271,6 +297,48 @@ export function getBrowserOptions(): LaunchOptions {
return browserOptions;
}
+async function solveCaptcha(url: string, maxTimeout: number = 60000): Promise<{
+ status: string,
+ solution?: {
+ cookies: {
+ name: string,
+ value: string,
+ domain: string,
+ path: string,
+ secure: boolean,
+ expires?: number,
+ httpOnly?: boolean,
+ sameSite?: "Strict" | "Lax" | "None"
+ }[],
+ }
+}> {
+ if (process.env.FLARESOLVERR_URL) {
+ try {
+ const response = await axios.post(process.env.FLARESOLVERR_URL,
+ {
+ cmd: 'request.get',
+ url,
+ maxTimeout
+ },
+ {
+ headers: { 'Content-Type': 'application/json' }
+ }
+ )
+
+ if (response.status !== 200) {
+ return { status: 'fail' };
+ }
+
+ return { status: response.data.status, solution: response.data.solution };
+ } catch (error) {
+ console.error('Error during captcha solving:', error);
+ return { status: 'error' };
+ }
+ }
+
+ return { status: 'skip' };
+}
+
async function getBrowser(): Promise<{
browser: Browser;
context: BrowserContext;

View File

@@ -55,7 +55,7 @@ with roles;
"librechat-env-file.age".publicKeys = librechat; "librechat-env-file.age".publicKeys = librechat;
# For ACME DNS Challenge # For ACME DNS Challenge
"digitalocean-dns-credentials.age".publicKeys = server; "digitalocean-dns-credentials.age".publicKeys = dns-challenge;
# Frigate (DVR) # Frigate (DVR)
"frigate-credentials.age".publicKeys = frigate; "frigate-credentials.age".publicKeys = frigate;