.
This commit is contained in:
parent
faf14881a3
commit
f4760f39da
20 changed files with 305 additions and 869 deletions
|
|
@ -40,6 +40,7 @@ in
|
|||
};
|
||||
|
||||
Service = {
|
||||
WorkingDirectory = workDir;
|
||||
ExecStartPre = pkgs.writeShellScript "antigravity2api-init" ''
|
||||
export PATH="${pkgs.coreutils}/bin:$PATH"
|
||||
mkdir -p "${workDir}"
|
||||
|
|
@ -54,7 +55,7 @@ in
|
|||
|
||||
ExecStart = ''
|
||||
${pkgs.podman}/bin/podman run --replace --rm --name antigravity2api \
|
||||
-p 8045:8045 \
|
||||
-p 127.0.0.1:8045:8045 \
|
||||
-v ${workDir}/data:/app/data \
|
||||
-v ${workDir}/public/images:/app/public/images \
|
||||
-v ${workDir}/.env:/app/.env \
|
||||
|
|
|
|||
|
|
@ -9,11 +9,9 @@
|
|||
}:
|
||||
|
||||
let
|
||||
# Apply the bwrapper overlay to get mkBwrapper
|
||||
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
|
||||
in
|
||||
{
|
||||
# Provide the sandboxed Lutris package
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
lutris-sandboxed = bwrapperPkgs.mkBwrapper {
|
||||
|
|
@ -34,13 +32,12 @@ in
|
|||
pkgs.vulkan-tools
|
||||
pkgs.unzip
|
||||
pkgs.cabextract
|
||||
pkgs.xorg.xrandr
|
||||
pkgs.pciutils
|
||||
pkgs.gamemode.lib
|
||||
pkgs.xdg-utils
|
||||
];
|
||||
};
|
||||
isFhsenv = true; # Lutris uses buildFHSEnv
|
||||
isFhsenv = true;
|
||||
id = "net.lutris.Lutris";
|
||||
env = {
|
||||
WEBKIT_DISABLE_DMABUF_RENDERER = 1;
|
||||
|
|
@ -51,7 +48,6 @@ in
|
|||
XDG_CURRENT_DESKTOP = "niri";
|
||||
XDG_SESSION_TYPE = "wayland";
|
||||
DBUS_SESSION_BUS_ADDRESS = "unix:path=$XDG_RUNTIME_DIR/bus";
|
||||
# Ensure Vulkan loader finds the drivers
|
||||
VK_ICD_FILENAMES = "/run/opengl-driver/share/vulkan/icd.d/radeon_icd.x86_64.json:/run/opengl-driver-32/share/vulkan/icd.d/radeon_icd.i686.json";
|
||||
};
|
||||
};
|
||||
|
|
@ -69,10 +65,10 @@ in
|
|||
"$HOME/.config/kdedefaults"
|
||||
"$HOME/.local/share/color-schemes"
|
||||
"$HOME/.local/share/Steam/compatibilitytools.d"
|
||||
# GTK Theming
|
||||
"$HOME/.config/gtk-3.0"
|
||||
"$HOME/.config/gtk-4.0"
|
||||
"$HOME/.icons"
|
||||
"/data/Torrents/Games" # Repack installers
|
||||
];
|
||||
|
||||
readWrite = [
|
||||
|
|
|
|||
|
|
@ -5,294 +5,69 @@
|
|||
...
|
||||
}:
|
||||
|
||||
let
|
||||
# Define the user and group consistently
|
||||
user = "ashie";
|
||||
group = "users";
|
||||
puid = "1000";
|
||||
pgid = "100";
|
||||
|
||||
# Common env vars to avoid repetition
|
||||
commonEnv = {
|
||||
PUID = puid;
|
||||
PGID = pgid;
|
||||
TZ = "Europe/Berlin";
|
||||
};
|
||||
in
|
||||
{
|
||||
|
||||
# Nixarr Configuration
|
||||
# Replaces OCI containers with native NixOS services
|
||||
# Nixflix Configuration
|
||||
nixflix = {
|
||||
enable = false; # Disabled to revert to Podman
|
||||
stateDir = "/var/lib/nixflix";
|
||||
mediaDir = "/data";
|
||||
|
||||
sonarr.enable = false;
|
||||
radarr.enable = false;
|
||||
prowlarr.enable = false;
|
||||
jellyfin.enable = false;
|
||||
jellyseerr.enable = false;
|
||||
|
||||
# We use external OCI containers for these
|
||||
sabnzbd.enable = false;
|
||||
mullvad.enable = false;
|
||||
|
||||
# Jellyseerr defaults to VPN=true, but we disabled Mullvad, so we must disable VPN here too.
|
||||
jellyseerr.vpn.enable = false;
|
||||
};
|
||||
|
||||
# Homepage Dashboard
|
||||
services.homepage-dashboard = {
|
||||
enable = true;
|
||||
listenPort = 8082;
|
||||
|
||||
# Custom settings for better visual appearance
|
||||
settings = {
|
||||
title = "Media Dashboard";
|
||||
theme = "dark";
|
||||
color = "slate";
|
||||
headerStyle = "boxed";
|
||||
layout = {
|
||||
"Media" = {
|
||||
style = "row";
|
||||
columns = 2;
|
||||
};
|
||||
"Automation" = {
|
||||
style = "row";
|
||||
columns = 3;
|
||||
};
|
||||
"Downloads" = {
|
||||
style = "row";
|
||||
columns = 2;
|
||||
};
|
||||
};
|
||||
# 1. Enable Podman (required backend)
|
||||
virtualisation = {
|
||||
podman = {
|
||||
enable = true;
|
||||
autoPrune.enable = true;
|
||||
};
|
||||
|
||||
services = [
|
||||
{
|
||||
"Media" = [
|
||||
{
|
||||
"Jellyfin" = {
|
||||
icon = "jellyfin.png";
|
||||
href = "http://localhost:8096";
|
||||
description = "Media Server";
|
||||
widget = {
|
||||
type = "jellyfin";
|
||||
url = "http://localhost:8096";
|
||||
key = "{{HOMEPAGE_VAR_JELLYFIN_API_KEY}}";
|
||||
enableBlocks = true;
|
||||
enableNowPlaying = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"Jellyseerr" = {
|
||||
icon = "jellyseerr.png";
|
||||
href = "http://localhost:5055";
|
||||
description = "Media Requests";
|
||||
widget = {
|
||||
type = "jellyseerr";
|
||||
url = "http://localhost:5055";
|
||||
key = "{{HOMEPAGE_VAR_JELLYSEERR_API_KEY}}";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
{
|
||||
"Automation" = [
|
||||
{
|
||||
"Sonarr" = {
|
||||
icon = "sonarr.png";
|
||||
href = "http://localhost:8989";
|
||||
description = "TV Series";
|
||||
widget = {
|
||||
type = "sonarr";
|
||||
url = "http://localhost:8989";
|
||||
key = "{{HOMEPAGE_VAR_SONARR_API_KEY}}";
|
||||
enableQueue = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"Radarr" = {
|
||||
icon = "radarr.png";
|
||||
href = "http://localhost:7878";
|
||||
description = "Movies";
|
||||
widget = {
|
||||
type = "radarr";
|
||||
url = "http://localhost:7878";
|
||||
key = "{{HOMEPAGE_VAR_RADARR_API_KEY}}";
|
||||
enableQueue = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
"Prowlarr" = {
|
||||
icon = "prowlarr.png";
|
||||
href = "http://localhost:9696";
|
||||
description = "Indexer Manager";
|
||||
widget = {
|
||||
type = "prowlarr";
|
||||
url = "http://localhost:9696";
|
||||
key = "{{HOMEPAGE_VAR_PROWLARR_API_KEY}}";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
"Downloads" = [
|
||||
{
|
||||
"qBittorrent" = {
|
||||
icon = "qbittorrent.png";
|
||||
href = "http://localhost:8080";
|
||||
description = "Torrent Client";
|
||||
widget = {
|
||||
type = "qbittorrent";
|
||||
url = "http://localhost:8080";
|
||||
username = "{{HOMEPAGE_VAR_QBITTORRENT_USERNAME}}";
|
||||
password = "{{HOMEPAGE_VAR_QBITTORRENT_PASSWORD}}";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
bookmarks = [
|
||||
{
|
||||
"Dev" = [
|
||||
{
|
||||
"GitHub" = [
|
||||
{
|
||||
abbr = "GH";
|
||||
href = "https://github.com";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
"NixOS Search" = [
|
||||
{
|
||||
abbr = "NO";
|
||||
href = "https://search.nixos.org";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
"Home Manager" = [
|
||||
{
|
||||
abbr = "HM";
|
||||
href = "https://nix-community.github.io/home-manager/options.xhtml";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
"Media" = [
|
||||
{
|
||||
"Trakt" = [
|
||||
{
|
||||
abbr = "TR";
|
||||
href = "https://trakt.tv";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
"IMDb" = [
|
||||
{
|
||||
abbr = "IM";
|
||||
href = "https://imdb.com";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
widgets = [
|
||||
{
|
||||
resources = {
|
||||
cpu = true;
|
||||
disk = "/";
|
||||
memory = true;
|
||||
uptime = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
search = {
|
||||
provider = "duckduckgo";
|
||||
target = "_blank";
|
||||
};
|
||||
}
|
||||
{
|
||||
datetime = {
|
||||
text_size = "xl";
|
||||
format = {
|
||||
dateStyle = "long";
|
||||
timeStyle = "short";
|
||||
hour12 = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
openmeteo = {
|
||||
label = "Berlin";
|
||||
latitude = 52.52;
|
||||
longitude = 13.405;
|
||||
units = "metric";
|
||||
cache = 5;
|
||||
};
|
||||
}
|
||||
];
|
||||
oci-containers.backend = "podman";
|
||||
};
|
||||
|
||||
# SOPS Secrets for Homepage
|
||||
sops.templates."homepage.env" = {
|
||||
content = ''
|
||||
HOMEPAGE_VAR_JELLYFIN_API_KEY=
|
||||
HOMEPAGE_VAR_JELLYSEERR_API_KEY=
|
||||
HOMEPAGE_VAR_SONARR_API_KEY=${config.sops.placeholder.sonarr_api_key}
|
||||
HOMEPAGE_VAR_RADARR_API_KEY=${config.sops.placeholder.radarr_api_key}
|
||||
HOMEPAGE_VAR_PROWLARR_API_KEY=${config.sops.placeholder.prowlarr_api_key}
|
||||
HOMEPAGE_VAR_QBITTORRENT_USERNAME=
|
||||
HOMEPAGE_VAR_QBITTORRENT_PASSWORD=
|
||||
'';
|
||||
};
|
||||
|
||||
# Inject secrets into Homepage service
|
||||
systemd.services.homepage-dashboard = {
|
||||
serviceConfig = {
|
||||
EnvironmentFile = lib.mkForce config.sops.templates."homepage.env".path;
|
||||
};
|
||||
};
|
||||
|
||||
# OCI Containers for Media Stack
|
||||
# 2. Container Definitions
|
||||
virtualisation.oci-containers.containers = {
|
||||
# VPN (Gluetun)
|
||||
|
||||
# --- VPN Gateway ---
|
||||
vpn = {
|
||||
image = "docker.io/qmcgaw/gluetun";
|
||||
# The VPN manages the ports for the attached containers
|
||||
ports = [
|
||||
"8080:8080" # qBittorrent WebUI
|
||||
"36630:36630" # Torrent Port TCP
|
||||
"36630:36630/udp" # Torrent Port UDP
|
||||
"36630:36630/udp"
|
||||
"9696:9696" # Prowlarr
|
||||
"8191:8191" # Flaresolverr
|
||||
];
|
||||
environmentFiles = [ config.sops.templates."gluetun.env".path ];
|
||||
environment = {
|
||||
TZ = "Europe/Berlin";
|
||||
DOT = "off";
|
||||
# DNS_ADDRESS = "1.1.1.1";
|
||||
WIREGUARD_MTU = "1420";
|
||||
# Allow access to local Podman network (for Prowlarr/Jellyseerr)
|
||||
FIREWALL_OUTBOUND_SUBNETS = "10.88.0.0/16";
|
||||
DOT = "off"; # DNS over TLS off (optional)
|
||||
FIREWALL_OUTBOUND_SUBNETS = "10.89.0.0/24"; # Allow access to local docker network
|
||||
};
|
||||
extraOptions = [
|
||||
"--cap-add=NET_ADMIN"
|
||||
"--cap-add=NET_RAW"
|
||||
"--device=/dev/net/tun:/dev/net/tun"
|
||||
"--network=media" # Join the shared media network
|
||||
"--network=media" # It joins the bridge so others can talk to it
|
||||
"--network-alias=prowlarr" # Allow other containers to reach Prowlarr via VPN
|
||||
"--network-alias=flaresolverr" # Allow other containers to reach Flaresolverr via VPN
|
||||
"--add-host=sonarr:10.89.0.50" # Allow Prowlarr to reach Sonarr
|
||||
"--add-host=radarr:10.89.0.51" # Allow Prowlarr to reach Radarr
|
||||
];
|
||||
};
|
||||
|
||||
# qBittorrent (Networked via VPN)
|
||||
# --- Torrent Client (Routed via VPN) ---
|
||||
torrent = {
|
||||
image = "lscr.io/linuxserver/qbittorrent:latest";
|
||||
# VITAL: Reuse the VPN container's network stack
|
||||
extraOptions = [ "--network=container:vpn" ];
|
||||
dependsOn = [ "vpn" ];
|
||||
environment = {
|
||||
PUID = "1000"; # ashie
|
||||
PGID = "100"; # users
|
||||
TZ = "Europe/Berlin";
|
||||
environment = commonEnv // {
|
||||
WEBUI_PORT = "8080";
|
||||
};
|
||||
volumes = [
|
||||
|
|
@ -301,97 +76,80 @@
|
|||
];
|
||||
};
|
||||
|
||||
# Flaresolverr (Direct connection)
|
||||
flaresolverr = {
|
||||
image = "ghcr.io/flaresolverr/flaresolverr:latest";
|
||||
extraOptions = [ "--network=media" ];
|
||||
ports = [ "8191:8191" ];
|
||||
environment = {
|
||||
TZ = "Europe/Berlin";
|
||||
};
|
||||
};
|
||||
|
||||
# Prowlarr (Direct connection)
|
||||
# --- The Arr Stack ---
|
||||
prowlarr = {
|
||||
image = "lscr.io/linuxserver/prowlarr:latest";
|
||||
extraOptions = [ "--network=media" ];
|
||||
ports = [ "9696:9696" ];
|
||||
environment = {
|
||||
PUID = "1000";
|
||||
PGID = "100";
|
||||
TZ = "Europe/Berlin";
|
||||
};
|
||||
volumes = [
|
||||
"/var/lib/nixarr/prowlarr:/config"
|
||||
extraOptions = [
|
||||
"--network=container:vpn"
|
||||
];
|
||||
dependsOn = [ "vpn" ];
|
||||
environment = commonEnv;
|
||||
volumes = [ "/var/lib/nixarr/prowlarr:/config" ];
|
||||
};
|
||||
|
||||
# Sonarr (Direct connection)
|
||||
sonarr = {
|
||||
image = "lscr.io/linuxserver/sonarr:latest";
|
||||
extraOptions = [ "--network=media" ];
|
||||
extraOptions = [
|
||||
"--network=media"
|
||||
"--ip=10.89.0.50"
|
||||
];
|
||||
ports = [ "8989:8989" ];
|
||||
environment = {
|
||||
PUID = "1000";
|
||||
PGID = "100";
|
||||
TZ = "Europe/Berlin";
|
||||
};
|
||||
environment = commonEnv;
|
||||
volumes = [
|
||||
"/var/lib/nixarr/sonarr:/config"
|
||||
"/data:/data"
|
||||
];
|
||||
};
|
||||
|
||||
# Radarr (Direct connection)
|
||||
radarr = {
|
||||
image = "lscr.io/linuxserver/radarr:latest";
|
||||
extraOptions = [ "--network=media" ];
|
||||
extraOptions = [
|
||||
"--network=media"
|
||||
"--ip=10.89.0.51"
|
||||
];
|
||||
ports = [ "7878:7878" ];
|
||||
environment = {
|
||||
PUID = "1000";
|
||||
PGID = "100";
|
||||
TZ = "Europe/Berlin";
|
||||
};
|
||||
environment = commonEnv;
|
||||
volumes = [
|
||||
"/var/lib/nixarr/radarr:/config"
|
||||
"/data:/data"
|
||||
];
|
||||
};
|
||||
|
||||
# Jellyfin (Direct connection)
|
||||
# --- Media Server ---
|
||||
jellyfin = {
|
||||
image = "lscr.io/linuxserver/jellyfin:latest";
|
||||
extraOptions = [ "--network=media" ];
|
||||
extraOptions = [
|
||||
"--network=media"
|
||||
"--device=/dev/dri:/dev/dri"
|
||||
];
|
||||
ports = [ "8096:8096" ];
|
||||
environment = {
|
||||
PUID = "1000";
|
||||
PGID = "100";
|
||||
TZ = "Europe/Berlin";
|
||||
};
|
||||
environment = commonEnv;
|
||||
volumes = [
|
||||
"/var/lib/nixarr/jellyfin:/config"
|
||||
"/data:/data"
|
||||
];
|
||||
};
|
||||
|
||||
# Jellyseerr (Direct connection)
|
||||
jellyseerr = {
|
||||
image = "ghcr.io/fallenbagel/jellyseerr:latest";
|
||||
extraOptions = [ "--network=media" ];
|
||||
ports = [ "5055:5055" ];
|
||||
environment = {
|
||||
PUID = "1000";
|
||||
PGID = "100";
|
||||
TZ = "Europe/Berlin";
|
||||
};
|
||||
volumes = [
|
||||
"/var/lib/nixarr/jellyseerr:/app/config"
|
||||
];
|
||||
environment = commonEnv;
|
||||
volumes = [ "/var/lib/nixarr/jellyseerr:/app/config" ];
|
||||
};
|
||||
|
||||
flaresolverr = {
|
||||
image = "ghcr.io/flaresolverr/flaresolverr:latest";
|
||||
extraOptions = [ "--network=container:vpn" ];
|
||||
dependsOn = [ "vpn" ];
|
||||
environment = {
|
||||
TZ = "Europe/Berlin";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Define the dedicated media network
|
||||
# 3. Network Setup (Fixed)
|
||||
# Ensure the network is created before ANY container starts
|
||||
systemd.services.create-media-network = {
|
||||
script = ''
|
||||
${pkgs.podman}/bin/podman network exists media || ${pkgs.podman}/bin/podman network create media
|
||||
|
|
@ -400,113 +158,44 @@
|
|||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
User = "ashie";
|
||||
# Removed 'User = ashie' -> Networks created by root are visible to root services
|
||||
};
|
||||
};
|
||||
|
||||
# Ensure the /data directory exists (Nixarr uses it)
|
||||
# Ensure containers wait for the network
|
||||
systemd.services."podman-vpn".requires = [ "create-media-network.service" ];
|
||||
systemd.services."podman-vpn".after = [ "create-media-network.service" ];
|
||||
# (Repeat for others if they don't depend on VPN, but usually unnecessary if they all join 'media')
|
||||
|
||||
# 4. Permissions
|
||||
systemd.tmpfiles.rules = [
|
||||
# Data directory: owned by ashie:media so both qBittorrent (ashie) and others can access
|
||||
"d /data 0775 ashie media - -"
|
||||
|
||||
# Ensure config directories exist with correct permissions
|
||||
"d /var/lib/nixarr/prowlarr 0755 ashie users - -"
|
||||
"d /var/lib/nixarr/sonarr 0755 ashie users - -"
|
||||
"d /var/lib/nixarr/radarr 0755 ashie users - -"
|
||||
"d /var/lib/nixarr/jellyfin 0755 ashie users - -"
|
||||
"d /var/lib/nixarr/jellyseerr 0755 ashie users - -"
|
||||
|
||||
# qBittorrent directory
|
||||
"d /var/lib/qbittorrent 0755 ashie users - -"
|
||||
|
||||
"d /data 0775 ${user} media - -"
|
||||
"d /var/lib/nixarr/prowlarr 0755 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/sonarr 0755 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/radarr 0755 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/jellyfin 0755 ${user} ${group} - -"
|
||||
"d /var/lib/nixarr/jellyseerr 0755 ${user} ${group} - -"
|
||||
"d /var/lib/qbittorrent 0755 ${user} ${group} - -"
|
||||
];
|
||||
|
||||
# Add ashie to media group to ensure access to /data
|
||||
users.users.ashie.extraGroups = [ "media" ];
|
||||
users.users.${user}.extraGroups = [ "media" ];
|
||||
|
||||
# Firewall rules
|
||||
# 5. Firewall
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80 # HTTP
|
||||
443 # HTTPS
|
||||
9696 # Prowlarr
|
||||
8989 # Sonarr
|
||||
7878 # Radarr
|
||||
8096 # Jellyfin
|
||||
5055 # Jellyseerr
|
||||
8080 # qBittorrent WebUI
|
||||
36630 # Torrent
|
||||
|
||||
8082 # Homepage
|
||||
|
||||
80
|
||||
443
|
||||
9696
|
||||
8989
|
||||
7878
|
||||
8096
|
||||
5055
|
||||
8080
|
||||
36630
|
||||
8082
|
||||
8191
|
||||
];
|
||||
networking.firewall.allowedUDPPorts = [
|
||||
36630
|
||||
443
|
||||
];
|
||||
|
||||
# Rootless Container Overrides
|
||||
# Force these containers to run as user 'ashie'
|
||||
systemd.services."podman-vpn".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-vpn".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
};
|
||||
systemd.services."podman-vpn".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-vpn".serviceConfig.Delegate = true;
|
||||
|
||||
systemd.services."podman-torrent".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-torrent".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
};
|
||||
systemd.services."podman-torrent".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-torrent".serviceConfig.Delegate = true;
|
||||
|
||||
systemd.services."podman-flaresolverr".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-flaresolverr".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
};
|
||||
systemd.services."podman-flaresolverr".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-flaresolverr".serviceConfig.Delegate = true;
|
||||
|
||||
systemd.services."podman-prowlarr".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-prowlarr".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
};
|
||||
systemd.services."podman-prowlarr".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-prowlarr".serviceConfig.Delegate = true;
|
||||
|
||||
systemd.services."podman-sonarr".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-sonarr".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
};
|
||||
systemd.services."podman-sonarr".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-sonarr".serviceConfig.Delegate = true;
|
||||
|
||||
systemd.services."podman-radarr".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-radarr".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
};
|
||||
systemd.services."podman-radarr".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-radarr".serviceConfig.Delegate = true;
|
||||
|
||||
systemd.services."podman-jellyfin".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-jellyfin".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
};
|
||||
systemd.services."podman-jellyfin".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-jellyfin".serviceConfig.Delegate = true;
|
||||
|
||||
systemd.services."podman-jellyseerr".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-jellyseerr".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
};
|
||||
systemd.services."podman-jellyseerr".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-jellyseerr".serviceConfig.Delegate = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ in
|
|||
recommendedTlsSettings = true;
|
||||
|
||||
# SSL Hardening
|
||||
sslProtocols = "TLSv1.2 TLSv1.3";
|
||||
sslCiphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
|
||||
# sslProtocols = "TLSv1.2 TLSv1.3";
|
||||
# sslCiphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
|
||||
|
||||
# Use the wildcard cert by default for these domains
|
||||
commonHttpConfig = ''
|
||||
|
|
|
|||
|
|
@ -215,32 +215,59 @@ in
|
|||
default = "search.ashisgreat.xyz";
|
||||
description = "Public domain name for SearXNG";
|
||||
};
|
||||
|
||||
donations = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
default = { };
|
||||
description = "Map of donation platform names to URLs (e.g. { patreon = '...'; })";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# Ensure Podman is enabled
|
||||
myModules.podman.enable = true;
|
||||
|
||||
# 1. Redis Container (Cache/Limiter)
|
||||
virtualisation.oci-containers.containers."searxng-redis" = {
|
||||
image = "docker.io/library/redis:alpine";
|
||||
# ... (rest of config) ...
|
||||
|
||||
# 1. Create Bridge Network
|
||||
systemd.services."create-searxng-network" = {
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.User = "ashie";
|
||||
serviceConfig.RemainAfterExit = true;
|
||||
after = [ "user-runtime-dir@1000.service" ];
|
||||
requires = [ "user-runtime-dir@1000.service" ];
|
||||
path = [ pkgs.podman ];
|
||||
script = ''
|
||||
export XDG_RUNTIME_DIR="/run/user/1000"
|
||||
export HOME="/home/ashie"
|
||||
podman network create searxng-net --ignore
|
||||
'';
|
||||
};
|
||||
|
||||
# 2. Valkey Container (Cache/Limiter)
|
||||
virtualisation.oci-containers.containers."searxng-valkey" = {
|
||||
image = "docker.io/valkey/valkey:alpine";
|
||||
cmd = [
|
||||
"redis-server"
|
||||
"valkey-server"
|
||||
"--save"
|
||||
""
|
||||
"--appendonly"
|
||||
"no"
|
||||
]; # Ephemeral cache, no persistence needed
|
||||
ports = [ "127.0.0.1:6379:6379" ];
|
||||
extraOptions = [
|
||||
"--network=searxng-net"
|
||||
"--network-alias=valkey"
|
||||
];
|
||||
# No ports published to host for security
|
||||
};
|
||||
|
||||
# 2. SearXNG Container
|
||||
# 3. SearXNG Container
|
||||
virtualisation.oci-containers.containers."searxng" = {
|
||||
image = "ghcr.io/searxng/searxng:latest";
|
||||
ports = [ "127.0.0.1:${toString cfg.port}:8080" ];
|
||||
environment = {
|
||||
"SEARXNG_BASE_URL" = "https://${cfg.domain}";
|
||||
"SEARXNG_REDIS_URL" = "redis://searxng-redis:6379"; # Talk to Redis directly via container DNS
|
||||
"SEARXNG_REDIS_URL" = "valkey://valkey:6379"; # Talk to Valkey via alias
|
||||
"SEARXNG_URL_BASE" = "https://${cfg.domain}";
|
||||
};
|
||||
environmentFiles = [
|
||||
|
|
@ -248,60 +275,67 @@ in
|
|||
config.sops.templates."searxng.env".path
|
||||
];
|
||||
extraOptions = [
|
||||
"--network=searxng-net"
|
||||
"--cap-drop=ALL"
|
||||
"--cap-add=CHOWN"
|
||||
"--cap-add=SETGID"
|
||||
"--cap-add=SETUID"
|
||||
"--cap-add=DAC_OVERRIDE"
|
||||
"--add-host=host.containers.internal:host-gateway"
|
||||
];
|
||||
volumes = [
|
||||
"${config.sops.templates."searxng_settings.yml".path}:/etc/searxng/settings.yml:ro"
|
||||
"${catppuccinCss}:/etc/searxng/custom.css:ro"
|
||||
];
|
||||
dependsOn = [ "searxng-valkey" ];
|
||||
};
|
||||
|
||||
# 3. Secrets Configuration
|
||||
# We generate the settings.yml dynamically using sops templates to inject secrets if needed,
|
||||
# or just to manage the config declaratively.
|
||||
sops.templates."searxng.env".content = ''
|
||||
SEARXNG_SECRET_KEY=${config.sops.placeholder.searxng_secret_key}
|
||||
'';
|
||||
sops.templates."searxng.env" = {
|
||||
owner = "ashie";
|
||||
content = ''
|
||||
SEARXNG_SECRET_KEY=${config.sops.placeholder.searxng_secret_key}
|
||||
'';
|
||||
};
|
||||
|
||||
sops.templates."searxng_settings.yml".content = ''
|
||||
use_default_settings: true
|
||||
sops.templates."searxng_settings.yml" = {
|
||||
owner = "ashie";
|
||||
content = ''
|
||||
use_default_settings: true
|
||||
|
||||
general:
|
||||
debug: false
|
||||
instance_name: "Ashie Search"
|
||||
donations:
|
||||
patreon: false
|
||||
buymeacoffee: false
|
||||
general:
|
||||
debug: false
|
||||
instance_name: "Ashie Search"
|
||||
donation_url: ${if cfg.donations ? "Monero" then "\"${cfg.donations.Monero}\"" else "false"}
|
||||
donations:
|
||||
${lib.concatStringsSep "\n " (
|
||||
lib.mapAttrsToList (name: url: "${name}: \"${url}\"") cfg.donations
|
||||
)}
|
||||
|
||||
search:
|
||||
safe_search: 0
|
||||
autocomplete: "google"
|
||||
default_lang: "en-US"
|
||||
formats:
|
||||
- html
|
||||
- json
|
||||
|
||||
server:
|
||||
port: 8080
|
||||
bind_address: "0.0.0.0"
|
||||
secret_key: "${config.sops.placeholder.searxng_secret_key}"
|
||||
limiter: true
|
||||
image_proxy: true
|
||||
search:
|
||||
safe_search: 0
|
||||
autocomplete: "google"
|
||||
default_lang: "en-US"
|
||||
formats:
|
||||
- html
|
||||
- json
|
||||
|
||||
ui:
|
||||
static_use_hash: true
|
||||
custom_css: custom.css
|
||||
theme_args:
|
||||
simple_style: "auto"
|
||||
server:
|
||||
port: 8080
|
||||
bind_address: "0.0.0.0"
|
||||
secret_key: "${config.sops.placeholder.searxng_secret_key}"
|
||||
limiter: true
|
||||
image_proxy: true
|
||||
|
||||
redis:
|
||||
url: redis://searxng-redis:6379/0
|
||||
'';
|
||||
ui:
|
||||
static_use_hash: true
|
||||
custom_css: custom.css
|
||||
theme_args:
|
||||
simple_style: "auto"
|
||||
|
||||
redis:
|
||||
url: valkey://valkey:6379/0
|
||||
'';
|
||||
};
|
||||
|
||||
# Placeholder secret definition (User must add this to secrets.yaml!)
|
||||
sops.secrets.searxng_secret_key = { };
|
||||
|
|
@ -314,13 +348,29 @@ in
|
|||
};
|
||||
systemd.services."podman-searxng".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-searxng".serviceConfig.Delegate = true;
|
||||
systemd.services."podman-searxng".after = [
|
||||
"create-searxng-network.service"
|
||||
"user-runtime-dir@1000.service"
|
||||
];
|
||||
systemd.services."podman-searxng".requires = [
|
||||
"create-searxng-network.service"
|
||||
"user-runtime-dir@1000.service"
|
||||
];
|
||||
|
||||
systemd.services."podman-searxng-redis".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-searxng-redis".environment = {
|
||||
systemd.services."podman-searxng-valkey".serviceConfig.User = lib.mkForce "ashie";
|
||||
systemd.services."podman-searxng-valkey".environment = {
|
||||
HOME = "/home/ashie";
|
||||
XDG_RUNTIME_DIR = "/run/user/1000";
|
||||
};
|
||||
systemd.services."podman-searxng-redis".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-searxng-redis".serviceConfig.Delegate = true;
|
||||
systemd.services."podman-searxng-valkey".serviceConfig.Type = lib.mkForce "simple";
|
||||
systemd.services."podman-searxng-valkey".serviceConfig.Delegate = true;
|
||||
systemd.services."podman-searxng-valkey".after = [
|
||||
"create-searxng-network.service"
|
||||
"user-runtime-dir@1000.service"
|
||||
];
|
||||
systemd.services."podman-searxng-valkey".requires = [
|
||||
"create-searxng-network.service"
|
||||
"user-runtime-dir@1000.service"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
50
modules/nixos/steam-gamemode.nix
Normal file
50
modules/nixos/steam-gamemode.nix
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
programs.gamescope = {
|
||||
enable = true;
|
||||
capSysNice = true;
|
||||
};
|
||||
|
||||
services.displayManager.sessionPackages = [
|
||||
(pkgs.writeTextFile {
|
||||
name = "steam-gamemode-session";
|
||||
destination = "/share/wayland-sessions/steam-gamemode.desktop";
|
||||
text = ''
|
||||
[Desktop Entry]
|
||||
Name=Steam GameMode
|
||||
Comment=Launch Steam in GameMode with Gamescope
|
||||
Exec=${pkgs.writeShellScript "steam-gamemode-start" ''
|
||||
# Load system environment
|
||||
. /etc/profile
|
||||
|
||||
# Ensure we are in the user's home directory
|
||||
cd "$HOME" || exit 1
|
||||
|
||||
exec >/tmp/steam-gamemode.log 2>&1
|
||||
echo "Starting Steam GameMode Session at $(date)"
|
||||
echo "User: $(whoami)"
|
||||
echo "PATH: $PATH"
|
||||
echo "Gamescope path: ${pkgs.gamescope}/bin/gamescope"
|
||||
|
||||
# Check for steam binary
|
||||
if ! command -v steam >/dev/null; then
|
||||
echo "ERROR: steam command not found in PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Launching gamescope..."
|
||||
exec ${pkgs.gamescope}/bin/gamescope -f -e -- steam -gamepadui
|
||||
''}
|
||||
Type=Application
|
||||
'';
|
||||
derivationArgs = {
|
||||
passthru = {
|
||||
providedSessions = [ "steam-gamemode" ];
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -128,6 +128,7 @@ in
|
|||
''--talk="org.freedesktop.portal.*"''
|
||||
''--own="com.valvesoftware.Steam"''
|
||||
''--own="com.valvesoftware.Steam.*"''
|
||||
''--own="com.steampowered.PressureVessel.*"''
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue