mirror of
https://github.com/danbulant/dotfiles
synced 2026-09-17 13:23:51 +00:00
745 lines
20 KiB
Nix
745 lines
20 KiB
Nix
{
|
||
nix-index-database,
|
||
pkgs,
|
||
lib,
|
||
name ? "eisen",
|
||
...
|
||
}:
|
||
let
|
||
# these are used both in service configuration but also to
|
||
# create mappings {name}.eisen.danbulant.cloud to port in caddy
|
||
ports = {
|
||
status = 3001;
|
||
glance = 5678;
|
||
jellyfin = 8096;
|
||
qb = 8081;
|
||
sonarr = 8989;
|
||
radarr = 7878;
|
||
jackett = 9117;
|
||
prowlarr = 9696;
|
||
keep = 8100;
|
||
grafana = 3002;
|
||
tolgee = 8200;
|
||
# ntfy = 3003;
|
||
forgejo = 8300;
|
||
snaps = 8400;
|
||
matrix = 6167;
|
||
sable = 6200;
|
||
livekit = 7880;
|
||
};
|
||
internalPorts = {
|
||
prometheus-node = 9000;
|
||
prometheus-qb = 9200;
|
||
prometheus-sonarr = 9101;
|
||
prometheus-radarr = 9102;
|
||
prometheus-prowlarr = 9103;
|
||
prometheus-llama-swap = 9409;
|
||
prometheus = 9090;
|
||
livekit-jwt = 8080;
|
||
tuwunel-admin = 8009;
|
||
};
|
||
matrixServerName = "badapple.cz";
|
||
matrixHost = "matrix.badapple.cz";
|
||
livekitKeyFile = "/var/lib/livekit/keys";
|
||
in
|
||
{
|
||
deployment = {
|
||
# buildOnTarget = true;
|
||
targetHost = "eisen";
|
||
};
|
||
nixpkgs.config.permittedInsecurePackages = [
|
||
"pnpm-9.15.9"
|
||
];
|
||
programs.nix-index-database.comma.enable = true;
|
||
|
||
imports = [
|
||
nix-index-database.nixosModules.nix-index
|
||
./hardware-configuration.nix
|
||
../../modules/llama-swap-exporter.nix
|
||
../../modules/tuwunel-admin.nix
|
||
];
|
||
|
||
nix = {
|
||
daemonCPUSchedPolicy = "idle";
|
||
daemonIOSchedClass = "idle";
|
||
};
|
||
|
||
networking = {
|
||
hostName = name;
|
||
nameservers = [ "1.1.1.1" ];
|
||
networkmanager.enable = true;
|
||
};
|
||
|
||
time.timeZone = lib.mkForce "Europe/Prague";
|
||
i18n.defaultLocale = "en_US.UTF-8";
|
||
|
||
security = {
|
||
rtkit.enable = true;
|
||
polkit.enable = true;
|
||
};
|
||
|
||
services = {
|
||
logind.lidSwitchExternalPower = "ignore";
|
||
|
||
geoclue2.enable = true;
|
||
localtimed.enable = true;
|
||
openssh.enable = true;
|
||
tailscale = {
|
||
enable = true;
|
||
useRoutingFeatures = "both";
|
||
openFirewall = true;
|
||
extraUpFlags = [ "--advertise-exit-node" ];
|
||
};
|
||
avahi.enable = true;
|
||
lldpd.enable = true;
|
||
|
||
jellyfin = {
|
||
enable = true;
|
||
};
|
||
|
||
matrix-tuwunel = {
|
||
enable = true;
|
||
settings.global = {
|
||
server_name = matrixServerName;
|
||
port = [ ports.matrix ];
|
||
allow_registration = true;
|
||
oidc_native_auth = true;
|
||
ip_source = "rightmost_x_forwarded_for";
|
||
registration_token_file = "/etc/secrets/matrix-registration-token";
|
||
database_backup_path = "/var/lib/tuwunel/database-backups";
|
||
database_backups_to_keep = 2;
|
||
admin_signal_execute = [ "server backup-database" ];
|
||
|
||
well_known = {
|
||
client = "https://${matrixHost}";
|
||
livekit_url = "https://${matrixHost}/livekit/jwt";
|
||
};
|
||
};
|
||
};
|
||
|
||
tuwunel-admin = {
|
||
enable = true;
|
||
settings = {
|
||
server.bind = "127.0.0.1:${toString internalPorts.tuwunel-admin}";
|
||
matrix = {
|
||
homeservers = [ "https://${matrixHost}" ];
|
||
allow_any_server = false;
|
||
admin_bot = "@tuwunel:${matrixServerName}";
|
||
admin_room_alias = "#admins:${matrixServerName}";
|
||
device_id = "tuwunel-admin";
|
||
device_display_name = "tuwunel-admin";
|
||
};
|
||
};
|
||
};
|
||
|
||
livekit = {
|
||
enable = true;
|
||
keyFile = livekitKeyFile;
|
||
openFirewall = true;
|
||
settings = {
|
||
port = ports.livekit;
|
||
room.auto_create = false;
|
||
rtc = {
|
||
tcp_port = 7881;
|
||
use_external_ip = true;
|
||
port_range_start = 50100;
|
||
port_range_end = 50105;
|
||
};
|
||
};
|
||
};
|
||
|
||
lk-jwt-service = {
|
||
enable = true;
|
||
keyFile = livekitKeyFile;
|
||
livekitUrl = "wss://${matrixHost}/livekit/sfu";
|
||
port = internalPorts.livekit-jwt;
|
||
};
|
||
|
||
sonarr = {
|
||
enable = true;
|
||
settings.server.port = ports.sonarr;
|
||
};
|
||
|
||
radarr = {
|
||
enable = true;
|
||
settings.server.port = ports.radarr;
|
||
};
|
||
prowlarr = {
|
||
enable = true;
|
||
settings.server.port = ports.prowlarr;
|
||
};
|
||
karakeep = {
|
||
enable = true;
|
||
extraEnvironment = {
|
||
PORT = toString ports.keep;
|
||
# DISABLE_SIGNUPS = "true";
|
||
DISABLE_NEW_RELEASE_CHECK = "true";
|
||
};
|
||
environmentFile = "/etc/secrets/karakeep.env";
|
||
};
|
||
|
||
# llama-swap-exporter = {
|
||
# enable = true;
|
||
# url = "http://100.120.15.10:${toString ports.llama-swap}/api/metrics";
|
||
# port = internalPorts.prometheus-llama-swap;
|
||
# };
|
||
|
||
forgejo = {
|
||
enable = true;
|
||
settings = {
|
||
server = {
|
||
DOMAIN = "git.badapple.cz";
|
||
ROOT_URL = "https://git.badapple.cz";
|
||
HTTP_PORT = ports.forgejo;
|
||
};
|
||
service.DISABLE_REGISTRATION = true;
|
||
};
|
||
# actions = {
|
||
# ENABLED = true;
|
||
# DEFAULT_ACTIONS_URL = "github";
|
||
# };
|
||
lfs.enable = true;
|
||
dump.enable = true;
|
||
dump.age = "5d";
|
||
};
|
||
|
||
dnsmasq = {
|
||
enable = true;
|
||
};
|
||
|
||
uptime-kuma = {
|
||
enable = true;
|
||
settings = {
|
||
PORT = toString ports.status;
|
||
};
|
||
};
|
||
|
||
grafana = {
|
||
enable = true;
|
||
settings = {
|
||
server.http_port = ports.grafana;
|
||
security = {
|
||
secret_key = "$__file{/etc/secrets/gf_secret_key}";
|
||
};
|
||
};
|
||
};
|
||
prometheus = {
|
||
enable = true;
|
||
exporters = {
|
||
exportarr-radarr = {
|
||
enable = true;
|
||
url = "http://127.0.0.1:${toString ports.radarr}";
|
||
port = internalPorts.prometheus-radarr;
|
||
apiKeyFile = "/etc/secrets/radarr_api_key";
|
||
};
|
||
exportarr-sonarr = {
|
||
enable = true;
|
||
url = "http://127.0.0.1:${toString ports.sonarr}";
|
||
port = internalPorts.prometheus-sonarr;
|
||
apiKeyFile = "/etc/secrets/sonarr_api_key";
|
||
};
|
||
exportarr-prowlarr = {
|
||
enable = true;
|
||
url = "http://127.0.0.1:${toString ports.prowlarr}";
|
||
port = internalPorts.prometheus-prowlarr;
|
||
apiKeyFile = "/etc/secrets/prowlarr_api_key";
|
||
};
|
||
node = {
|
||
enable = true;
|
||
port = internalPorts.prometheus-node;
|
||
};
|
||
};
|
||
|
||
scrapeConfigs = [
|
||
{
|
||
job_name = "node";
|
||
static_configs = [
|
||
{
|
||
targets = [ "localhost:${toString internalPorts.prometheus-node}" ];
|
||
}
|
||
];
|
||
}
|
||
{
|
||
job_name = "qb";
|
||
static_configs = [
|
||
{
|
||
targets = [ "localhost:${toString internalPorts.prometheus-qb}" ];
|
||
}
|
||
];
|
||
}
|
||
{
|
||
job_name = "sonarr";
|
||
static_configs = [
|
||
{
|
||
targets = [ "localhost:${toString internalPorts.prometheus-sonarr}" ];
|
||
}
|
||
];
|
||
}
|
||
{
|
||
job_name = "radarr";
|
||
static_configs = [
|
||
{
|
||
targets = [ "localhost:${toString internalPorts.prometheus-radarr}" ];
|
||
}
|
||
];
|
||
}
|
||
{
|
||
job_name = "llama-swap";
|
||
static_configs = [
|
||
{
|
||
targets = [ "localhost:${toString internalPorts.prometheus-llama-swap}" ];
|
||
}
|
||
];
|
||
}
|
||
{
|
||
job_name = "uptime-kuma";
|
||
static_configs = [
|
||
{
|
||
targets = [ "localhost:${toString ports.status}" ];
|
||
# generated, only accessible through tailscale, not really sensitive
|
||
}
|
||
];
|
||
basic_auth = {
|
||
username = "";
|
||
password = "uk1_SAAatRz9luyFXItVnbXyOdVuU2fkMhZITrnPY27z";
|
||
};
|
||
}
|
||
];
|
||
};
|
||
|
||
# ntfy-sh = {
|
||
# enable = true;
|
||
# settings = {
|
||
# listen-http = ":${toString ports.ntfy}";
|
||
# base-url = "http://ntfy.eisen";
|
||
# };
|
||
# };
|
||
|
||
# grafana-to-ntfy = {
|
||
# enable = true;
|
||
# settings = {
|
||
# ntfyUrl = "http://ntfy.eisen/grafana";
|
||
# };
|
||
# };
|
||
|
||
glance = {
|
||
enable = true;
|
||
settings = {
|
||
server = {
|
||
port = ports.glance;
|
||
};
|
||
pages = import ./glance-pages.nix;
|
||
};
|
||
environmentFile = "/etc/secrets/glance.env";
|
||
};
|
||
|
||
caddy = {
|
||
enable = true;
|
||
|
||
extraConfig = ''
|
||
(auth) {
|
||
forward_auth unix//run/tailscale-nginx-auth/tailscale-nginx-auth.sock {
|
||
uri /auth
|
||
header_up Remote-Addr {remote_host}
|
||
header_up Remote-Port {remote_port}
|
||
header_up Original-URI {uri}
|
||
copy_headers {
|
||
Tailscale-User>X-Webauth-User
|
||
Tailscale-Name>X-Webauth-Name
|
||
Tailscale-Login>X-Webauth-Login
|
||
Tailscale-Tailnet>X-Webauth-Tailnet
|
||
Tailscale-Profile-Picture>X-Webauth-Profile-Picture
|
||
}
|
||
}
|
||
}
|
||
'';
|
||
|
||
virtualHosts =
|
||
builtins.listToAttrs (
|
||
map (k: {
|
||
name = "${k}.eisen.danbulant.cloud:80, ${k}.eisen:80";
|
||
value = {
|
||
# import auth
|
||
extraConfig = ''
|
||
reverse_proxy http://localhost:${toString ports.${k}}
|
||
'';
|
||
};
|
||
}) (builtins.attrNames ports)
|
||
)
|
||
// {
|
||
"${matrixHost}:80" = {
|
||
extraConfig = ''
|
||
@matrixClientWellKnown path /.well-known/matrix/client
|
||
handle @matrixClientWellKnown {
|
||
header Access-Control-Allow-Origin "*"
|
||
header Content-Type application/json
|
||
respond `{"m.homeserver":{"base_url":"https://${matrixHost}"},"org.matrix.msc4143.rtc_foci":[{"type":"livekit","livekit_service_url":"https://${matrixHost}/livekit/jwt"}]}` 200
|
||
}
|
||
|
||
@matrixServerWellKnown path /.well-known/matrix/server
|
||
handle @matrixServerWellKnown {
|
||
header Access-Control-Allow-Origin "*"
|
||
header Content-Type application/json
|
||
respond `{"m.server":"${matrixHost}:443"}` 200
|
||
}
|
||
|
||
@jwtService path /livekit/jwt/sfu/get* /livekit/jwt/healthz* /livekit/jwt/get_token*
|
||
handle @jwtService {
|
||
uri strip_prefix /livekit/jwt
|
||
reverse_proxy http://localhost:${toString internalPorts.livekit-jwt}
|
||
}
|
||
|
||
@livekit path /livekit/sfu*
|
||
handle @livekit {
|
||
uri strip_prefix /livekit/sfu
|
||
reverse_proxy http://localhost:${toString ports.livekit}
|
||
}
|
||
|
||
handle {
|
||
reverse_proxy http://localhost:${toString ports.matrix}
|
||
}
|
||
'';
|
||
};
|
||
"admin.${matrixHost}:80" = {
|
||
extraConfig = ''
|
||
reverse_proxy http://localhost:${toString internalPorts.tuwunel-admin}
|
||
'';
|
||
};
|
||
"sable.badapple.cz:80" = {
|
||
extraConfig = ''
|
||
reverse_proxy http://localhost:${toString ports.sable}
|
||
'';
|
||
};
|
||
"translations.danbulant.cloud:80, translations.rpi1.danbulant.cloud:80" = {
|
||
extraConfig = ''
|
||
reverse_proxy http://localhost:${toString ports.tolgee}
|
||
'';
|
||
};
|
||
"snaps.rpi1.danbulant.cloud" = {
|
||
extraConfig = ''
|
||
reverse_proxy http://localhost:${toString ports.snaps}
|
||
'';
|
||
};
|
||
};
|
||
};
|
||
tailscale.permitCertUid = "caddy";
|
||
tailscaleAuth = {
|
||
# this is what's used above in forward_auth
|
||
enable = true;
|
||
group = "caddy";
|
||
};
|
||
};
|
||
systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = matrixServerName;
|
||
|
||
systemd.services.livekit-keys = {
|
||
description = "Generate the shared LiveKit API key";
|
||
before = [
|
||
"livekit.service"
|
||
"lk-jwt-service.service"
|
||
];
|
||
serviceConfig = {
|
||
Type = "oneshot";
|
||
RemainAfterExit = true;
|
||
StateDirectory = "livekit";
|
||
StateDirectoryMode = "0700";
|
||
UMask = "0077";
|
||
};
|
||
script = ''
|
||
if [[ ! -s "$STATE_DIRECTORY/keys" ]]; then
|
||
key="$(${lib.getExe pkgs.openssl} rand -base64 48)"
|
||
printf 'lk-jwt-service: %s\n' "$key" > "$STATE_DIRECTORY/keys"
|
||
fi
|
||
'';
|
||
};
|
||
systemd.services.livekit = {
|
||
requires = [ "livekit-keys.service" ];
|
||
after = [ "livekit-keys.service" ];
|
||
};
|
||
systemd.services.lk-jwt-service = {
|
||
requires = [ "livekit-keys.service" ];
|
||
after = [ "livekit-keys.service" ];
|
||
};
|
||
|
||
services.restic.backups.matrix = {
|
||
repository = "sftp:restic-eisen@fern:/media/large/restic/eisen";
|
||
passwordFile = "/etc/secrets/restic-password";
|
||
initialize = true;
|
||
paths = [
|
||
"/var/lib/tuwunel/database-backups"
|
||
"/var/lib/tuwunel/media"
|
||
"/var/lib/livekit/keys"
|
||
"/etc/secrets/matrix-registration-token"
|
||
];
|
||
extraOptions = [
|
||
"sftp.command='${lib.getExe pkgs.tailscale} ssh restic-eisen@fern -s sftp'"
|
||
];
|
||
extraBackupArgs = [ "--tag=matrix" ];
|
||
pruneOpts = [
|
||
"--keep-hourly=24"
|
||
"--keep-daily=14"
|
||
"--keep-weekly=8"
|
||
"--keep-monthly=12"
|
||
];
|
||
timerConfig = {
|
||
OnCalendar = "*-*-* 09,12,15,18,21:00:00";
|
||
Persistent = true;
|
||
RandomizedDelaySec = "20m";
|
||
};
|
||
backupPrepareCommand = ''
|
||
#!${pkgs.runtimeShell}
|
||
set -eu
|
||
|
||
backup_meta=/var/lib/tuwunel/database-backups/meta
|
||
before="$(${pkgs.findutils}/bin/find "$backup_meta" -maxdepth 1 -type f -printf '%f\n' 2>/dev/null | ${pkgs.coreutils}/bin/sort || true)"
|
||
|
||
${lib.getExe' pkgs.systemd "systemctl"} kill --kill-whom=main --signal=SIGUSR2 tuwunel.service
|
||
|
||
# RocksDB writes the metadata file only after an online backup is complete.
|
||
for ((attempt = 0; attempt < 120; attempt++)); do
|
||
after="$(${pkgs.findutils}/bin/find "$backup_meta" -maxdepth 1 -type f -printf '%f\n' 2>/dev/null | ${pkgs.coreutils}/bin/sort || true)"
|
||
if [[ -n "$after" && "$after" != "$before" ]]; then
|
||
exit 0
|
||
fi
|
||
${pkgs.coreutils}/bin/sleep 5
|
||
done
|
||
|
||
echo "Timed out waiting for Tuwunel's online database backup" >&2
|
||
exit 1
|
||
'';
|
||
};
|
||
|
||
# A sleeping Fern is normal. Keep retrying without overlapping timer runs,
|
||
# and promptly abandon dead SSH connections if it sleeps during a backup.
|
||
systemd.services.restic-backups-matrix.serviceConfig = {
|
||
Restart = "on-failure";
|
||
RestartSec = "30m";
|
||
TimeoutStartSec = "12h";
|
||
};
|
||
|
||
# The Karakeep module still emits this option, but Meilisearch 1.51 removed it.
|
||
systemd.services.meilisearch.serviceConfig.ExecStartPre = lib.mkAfter [
|
||
"${lib.getExe pkgs.gnused} -i '/^experimental_dumpless_upgrade =/d' \${RUNTIME_DIRECTORY}/config.toml"
|
||
];
|
||
|
||
# LiveKit's TCP ICE fallback is separate from its HTTP/WebSocket port.
|
||
networking.firewall.allowedTCPPorts = [ 7881 ];
|
||
# systemd.services.syncthing.environment.STNODEFAULTFOLDER = "true";
|
||
|
||
virtualisation = {
|
||
docker = {
|
||
enable = true;
|
||
enableOnBoot = true;
|
||
};
|
||
|
||
oci-containers = {
|
||
backend = "docker";
|
||
containers = {
|
||
gluetun = {
|
||
image = "qmcgaw/gluetun";
|
||
capabilities = {
|
||
NET_ADMIN = true;
|
||
};
|
||
devices = [ "/dev/net/tun" ];
|
||
environmentFiles = [ "/etc/secrets/gluetun.env" ];
|
||
ports = [
|
||
"${toString ports.qb}:${toString ports.qb}"
|
||
"${toString ports.jackett}:${toString ports.jackett}"
|
||
];
|
||
# VPN_SERVICE_PROVIDER=protonvpn
|
||
# VPN_TYPE=wireguard
|
||
# WIREGUARD_PRIVATE_KEY=wOEI9rqqbDwnN8/Bpp22sVz48T71vJ4fYmFWujulwUU
|
||
# SERVER_COUNTRIES=Denmark
|
||
environment = {
|
||
VPN_PORT_FORWARDING = "on";
|
||
# TOR_ONLY = "on";
|
||
PORT_FORWARD_ONLY = "on";
|
||
FIREWALL_OUTBOUND_SUBNETS = "192.168.1.0/24,100.64.0.0/10";
|
||
FIREWALL_INPUT_PORTS = "41641,22,80,443,53";
|
||
|
||
VPN_PORT_FORWARDING_UP_COMMAND = ''
|
||
/bin/sh -c 'wget -O- -nv --retry-connrefused --post-data "json={\"listen_port\":{{PORT}},\"current_network_interface\":\"{{VPN_INTERFACE}}\",\"random_port\":false,\"upnp\":false}" http://127.0.0.1:${toString ports.qb}/api/v2/app/setPreferences'
|
||
'';
|
||
VPN_PORT_FORWARDING_DOWN_COMMAND = ''
|
||
/bin/sh -c 'wget -O- -nv --retry-connrefused --post-data "json={\"listen_port\":0,\"current_network_interface\":\"lo\"}" http://127.0.0.1:${toString ports.qb}/api/v2/app/setPreferences'
|
||
'';
|
||
};
|
||
# extraOptions = [ "--network=host" ];
|
||
};
|
||
qbittorrent = {
|
||
image = "lscr.io/linuxserver/qbittorrent";
|
||
|
||
environment = {
|
||
WEBUI_PORT = toString ports.qb;
|
||
};
|
||
|
||
volumes = [
|
||
"/media/large/downloads:/downloads"
|
||
"qbittorrent-config:/config"
|
||
];
|
||
|
||
extraOptions = [ "--network=container:gluetun" ];
|
||
};
|
||
jackett = {
|
||
image = "lscr.io/linuxserver/jackett";
|
||
|
||
volumes = [
|
||
"jackett-config:/config"
|
||
];
|
||
|
||
extraOptions = [ "--network=container:gluetun" ];
|
||
};
|
||
prometheus-qb = {
|
||
image = "ghcr.io/esanchezm/prometheus-qbittorrent-exporter";
|
||
environment = {
|
||
QBITTORRENT_PORT = toString ports.qb;
|
||
QBITTORRENT_HOST = "localhost";
|
||
EXPORTER_PORT = toString internalPorts.prometheus-qb;
|
||
};
|
||
extraOptions = [ "--network=host" ];
|
||
# ports = [ "8000:${toString internalPorts.prometheus-qb}" ];
|
||
};
|
||
|
||
sable = {
|
||
image = "ghcr.io/sableclient/sable:latest";
|
||
ports = [
|
||
"127.0.0.1:${toString ports.sable}:8080"
|
||
];
|
||
};
|
||
|
||
tolgee = {
|
||
image = "tolgee/tolgee";
|
||
volumes = [
|
||
"data:/data"
|
||
];
|
||
ports = [
|
||
"${toString ports.tolgee}:8080"
|
||
];
|
||
environment = {
|
||
TOLGEE_AUTHENTICATION_ENABLED = "true";
|
||
};
|
||
};
|
||
};
|
||
};
|
||
};
|
||
# hardware.nvidia-container-toolkit.enable = true;
|
||
|
||
boot = {
|
||
kernelPackages = pkgs.linuxPackages_latest;
|
||
# Shortcuts for fixing things
|
||
# alt+sysrq (prtsc) + key
|
||
# h: Print help to the system log.
|
||
# f: Trigger the kernel oom killer.
|
||
# s: Sync data to disk before triggering the reset options below.
|
||
# e: SIGTERM all processes except PID 0.
|
||
# i: SIGKILL all processes except PID 0.
|
||
# b: Reboot the system.
|
||
kernel.sysctl."kernel.sysrq" = 1;
|
||
|
||
# zfs.enabled = false;
|
||
swraid.enable = false;
|
||
|
||
initrd.systemd.enable = true;
|
||
|
||
loader = {
|
||
systemd-boot.enable = true;
|
||
efi.canTouchEfiVariables = true;
|
||
# timeout = 0;
|
||
# grub.enable = true;
|
||
# grub.device = "/dev/disk/by-id/ata-Apacer_AS350_512GB_2021012802000028";
|
||
# grub.efiSupport = true;
|
||
};
|
||
};
|
||
|
||
users.users.dan = {
|
||
isNormalUser = true;
|
||
extraGroups = [
|
||
"networkmanager"
|
||
"wheel"
|
||
"docker"
|
||
"fuse"
|
||
"video"
|
||
"wireshark"
|
||
"gamemode"
|
||
"scanner"
|
||
"lp"
|
||
"kvm"
|
||
"adbusers"
|
||
];
|
||
shell = pkgs.nushell;
|
||
};
|
||
nix.settings.trusted-users = [
|
||
"root"
|
||
"@wheel"
|
||
"dan"
|
||
];
|
||
|
||
hardware.graphics = {
|
||
enable = true;
|
||
extraPackages = with pkgs; [
|
||
intel-media-driver
|
||
intel-vaapi-driver
|
||
intel-ocl
|
||
libva-vdpau-driver
|
||
intel-compute-runtime-legacy1
|
||
];
|
||
};
|
||
|
||
environment.sessionVariables = {
|
||
LIBVA_DRIVER_NAME = "i965";
|
||
};
|
||
|
||
environment.systemPackages = with pkgs; [
|
||
bun
|
||
jellyfin-ffmpeg
|
||
intel-gpu-tools
|
||
lsof
|
||
rsync
|
||
git
|
||
nvtopPackages.full
|
||
btop
|
||
lshw
|
||
bat
|
||
lsd
|
||
fastfetch
|
||
fish
|
||
nix-output-monitor
|
||
nh
|
||
duf
|
||
dust
|
||
cachix
|
||
qemu
|
||
ffmpeg
|
||
httpie
|
||
socat
|
||
websocat
|
||
oh-my-posh
|
||
];
|
||
|
||
nixpkgs.config.allowUnfree = true;
|
||
# nixpkgs.config.cudaSupport = true;
|
||
|
||
nix.settings = {
|
||
substituters = [
|
||
"https://cache.nixos.org"
|
||
"https://nix-community.cachix.org"
|
||
];
|
||
trusted-public-keys = [
|
||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||
];
|
||
};
|
||
# This value determines the NixOS release from which the default
|
||
# settings for stateful data, like file locations and database versions
|
||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||
# this value at the release version of the first install of this system.
|
||
# Before changing this value read the documentation for this option
|
||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||
system.stateVersion = "25.05"; # Did you read the comment?
|
||
|
||
nix.settings.experimental-features = [
|
||
"nix-command"
|
||
"flakes"
|
||
];
|
||
|
||
# /etc/hosts :)
|
||
networking.extraHosts = "";
|
||
}
|