enforce new flake schema. formatting.
This commit is contained in:
parent
4b0a90e00d
commit
ecf5132cbb
121 changed files with 1606 additions and 1554 deletions
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
# change directory with fzf
|
||||
# Usage: cdf [optional_relative_path]
|
||||
# - If no argument, searches from $HOME.
|
||||
|
|
@ -67,7 +68,8 @@ function cdf() {
|
|||
"--preview=tree -C {} | head -50"
|
||||
"--preview-window=right:50%:wrap"
|
||||
)
|
||||
local selected=$(find "${find_args[@]}" 2>/dev/null | fzf "${fzf_args[@]}")
|
||||
local selected
|
||||
selected=$(find "${find_args[@]}" 2>/dev/null | fzf "${fzf_args[@]}")
|
||||
|
||||
if [[ -n "$selected" ]]; then
|
||||
cd "$selected" || echo "Failed to cd into '$selected'"
|
||||
|
|
|
|||
|
|
@ -16,31 +16,33 @@ in
|
|||
imports = [ ../../../rofi-rbw ];
|
||||
|
||||
config = mkIf (cfg.enable && app == "rofi-rbw") {
|
||||
programs.rbw = {
|
||||
enable = true;
|
||||
settings = {
|
||||
# email = "you@example.tld"; # You have to set this in your config
|
||||
pinentry = mkDefault pkgs.pinentry-gnome3;
|
||||
lock_timeout = mkDefault 3600;
|
||||
programs = {
|
||||
rbw = {
|
||||
enable = true;
|
||||
settings = {
|
||||
# email = "you@example.tld"; # You have to set this in your config
|
||||
pinentry = mkDefault pkgs.pinentry-gnome3;
|
||||
lock_timeout = mkDefault 3600;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs.rofi-rbw = {
|
||||
enable = true;
|
||||
package = mkDefault pkgs.rofi-rbw-wayland;
|
||||
settings = {
|
||||
selector = mkDefault "bemenu";
|
||||
selector-args = mkDefault "-i -l 20";
|
||||
action = mkDefault "copy";
|
||||
typing-key-delay = mkDefault 0;
|
||||
rofi-rbw = {
|
||||
enable = true;
|
||||
package = mkDefault pkgs.rofi-rbw-wayland;
|
||||
settings = {
|
||||
selector = mkDefault "bemenu";
|
||||
selector-args = mkDefault "-i -l 20";
|
||||
action = mkDefault "copy";
|
||||
typing-key-delay = mkDefault 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs.librewolf = mkIf config.programs.librewolf.enable {
|
||||
profiles.default.extensions.packages =
|
||||
with inputs.nur.legacyPackages."${pkgs.stdenv.hostPlatform.system}".repos.rycee.firefox-addons; [
|
||||
bitwarden
|
||||
];
|
||||
librewolf = mkIf config.programs.librewolf.enable {
|
||||
profiles.default.extensions.packages =
|
||||
with inputs.nur.legacyPackages."${pkgs.stdenv.hostPlatform.system}".repos.rycee.firefox-addons; [
|
||||
bitwarden
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ let
|
|||
{
|
||||
default = mkOption {
|
||||
type = types.str;
|
||||
default = default;
|
||||
inherit default;
|
||||
description = "The default application to use for the ${default}.";
|
||||
};
|
||||
bind = mkOption {
|
||||
|
|
@ -38,12 +38,8 @@ let
|
|||
};
|
||||
|
||||
# generate lists of all binds and window rules and remove empty strings
|
||||
binds = filter (s: s != "") (
|
||||
builtins.concatLists (map (app: app.bind or [ "" ]) (attrValues apps))
|
||||
);
|
||||
windowrules = filter (s: s != "") (
|
||||
builtins.concatLists (map (app: app.windowrule or [ "" ]) (attrValues apps))
|
||||
);
|
||||
binds = filter (s: s != "") (builtins.concatLists (map (app: app.bind or [ "" ]) (attrValues apps)));
|
||||
windowrules = filter (s: s != "") (builtins.concatLists (map (app: app.windowrule or [ "" ]) (attrValues apps)));
|
||||
|
||||
inherit (lib)
|
||||
attrValues
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ let
|
|||
pkill = "${pkgs.procps}/bin/pkill";
|
||||
signal = "${toString config.programs.waybar.settings.mainBar."custom/notifications".signal}";
|
||||
in
|
||||
(pkgs.writeShellScriptBin "dunst-toggle" ''
|
||||
pkgs.writeShellScriptBin "dunst-toggle" ''
|
||||
${dunst} set-paused toggle
|
||||
${pkill} -RTMIN+${signal} waybar
|
||||
'')
|
||||
''
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ let
|
|||
cfg = config.wayland.windowManager.hyprland;
|
||||
app = cfg.applications.rssreader.default;
|
||||
reloadTime = "${toString config.programs.newsboat.reloadTime}";
|
||||
newsboat-reload = (import ./newsboat-reload.nix { inherit config pkgs; });
|
||||
newsboat-reload = import ./newsboat-reload.nix { inherit config pkgs; };
|
||||
|
||||
inherit (lib) mkIf;
|
||||
in
|
||||
|
|
@ -27,9 +27,11 @@ in
|
|||
timers.newsboat-reload = {
|
||||
Unit.Description = "Reload newsboat every ${reloadTime} minutes";
|
||||
|
||||
Timer.OnBootSec = "10sec";
|
||||
Timer.OnUnitActiveSec = "${reloadTime}min";
|
||||
Timer.Unit = "newsboat-reload.service";
|
||||
Timer = {
|
||||
OnBootSec = "10sec";
|
||||
OnUnitActiveSec = "${reloadTime}min";
|
||||
Unit = "newsboat-reload.service";
|
||||
};
|
||||
|
||||
Install.WantedBy = [ "timers.target" ];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@ let
|
|||
notify = "${pkgs.libnotify}/bin/notify-send";
|
||||
signal = "${toString config.programs.waybar.settings.mainBar."custom/newsboat".signal}";
|
||||
in
|
||||
(pkgs.writeShellScriptBin "newsboat-reload" ''
|
||||
pkgs.writeShellScriptBin "newsboat-reload" ''
|
||||
${notify} -u low 'Newsboat' 'Reloading RSS feeds...' && ${newsboat} -x reload && ${notify} -u low 'Newsboat' 'RSS feeds reloaded.' && pkill -RTMIN+${signal} waybar
|
||||
'')
|
||||
''
|
||||
|
|
|
|||
|
|
@ -14,9 +14,7 @@ in
|
|||
{
|
||||
config = mkIf (cfg.enable && app == "presentation-mode-bemenu") {
|
||||
home.packages = [
|
||||
(pkgs.writeShellScriptBin "presentation-mode-bemenu" (
|
||||
builtins.readFile ./presentation-mode-bemenu.sh
|
||||
))
|
||||
(pkgs.writeShellScriptBin "presentation-mode-bemenu" (builtins.readFile ./presentation-mode-bemenu.sh))
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
# Variables
|
||||
DISPLAYS=( $(hyprctl monitors | grep -E '^Monitor' | awk '{print $2}') )
|
||||
mapfile -t DISPLAYS < <(hyprctl monitors | grep -E '^Monitor' | awk '{print $2}')
|
||||
EXTEND_RIGHT="Extend to right of main"
|
||||
EXTEND_LEFT="Extend to left of main"
|
||||
MIRROR="Mirror main"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
let
|
||||
screenshotDir = "${config.xdg.userDirs.pictures}/screenshots";
|
||||
in
|
||||
(pkgs.writeShellScriptBin "screenshot" ''
|
||||
pkgs.writeShellScriptBin "screenshot" ''
|
||||
mkdir -p ${screenshotDir}
|
||||
${pkgs.hyprshot}/bin/hyprshot --mode $1 --output-folder ${screenshotDir} --filename screenshot_$(date +"%Y-%m-%d_%H-%M-%S").png
|
||||
'')
|
||||
''
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ in
|
|||
wayland.windowManager.hyprland = {
|
||||
settings = {
|
||||
bind = binds;
|
||||
bindm = (import ./mouse.nix);
|
||||
bindm = import ./mouse.nix;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,17 +9,19 @@ let
|
|||
inherit (lib) mkForce;
|
||||
in
|
||||
{
|
||||
home.pointerCursor = {
|
||||
name = mkForce "Bibata-Original-Ice";
|
||||
size = mkForce 24;
|
||||
package = mkForce pkgs.bibata-cursors;
|
||||
};
|
||||
home = {
|
||||
pointerCursor = {
|
||||
name = mkForce "Bibata-Original-Ice";
|
||||
size = mkForce 24;
|
||||
package = mkForce pkgs.bibata-cursors;
|
||||
};
|
||||
|
||||
home.packages = [ pkgs.hyprcursor ];
|
||||
packages = [ pkgs.hyprcursor ];
|
||||
|
||||
home.sessionVariables = {
|
||||
HYPRCURSOR_THEME = config.home.pointerCursor.name;
|
||||
HYPRCURSOR_SIZE = toString config.home.pointerCursor.size;
|
||||
sessionVariables = {
|
||||
HYPRCURSOR_THEME = config.home.pointerCursor.name;
|
||||
HYPRCURSOR_SIZE = toString config.home.pointerCursor.size;
|
||||
};
|
||||
};
|
||||
|
||||
# wayland.windowManager.hyprland.cursor.no_hardware_cursors = true;
|
||||
|
|
|
|||
|
|
@ -78,12 +78,6 @@ in
|
|||
# auto discover fonts in `home.packages`
|
||||
fonts.fontconfig.enable = true;
|
||||
|
||||
# notifications
|
||||
services.dunst = {
|
||||
enable = mkDefault true;
|
||||
waylandDisplay = config.home.sessionVariables.WAYLAND_DISPLAY;
|
||||
};
|
||||
|
||||
# install some applications
|
||||
home.packages = import ./packages.nix { inherit pkgs; }; # use programs.PACKAGE or services.SERVICE when possible
|
||||
|
||||
|
|
@ -94,11 +88,19 @@ in
|
|||
fi
|
||||
'';
|
||||
|
||||
services.udiskie = {
|
||||
enable = mkDefault true;
|
||||
tray = mkDefault "never";
|
||||
};
|
||||
# notifications
|
||||
services = {
|
||||
dunst = {
|
||||
enable = mkDefault true;
|
||||
waylandDisplay = config.home.sessionVariables.WAYLAND_DISPLAY;
|
||||
};
|
||||
|
||||
services.network-manager-applet.enable = mkDefault true;
|
||||
udiskie = {
|
||||
enable = mkDefault true;
|
||||
tray = mkDefault "never";
|
||||
};
|
||||
|
||||
network-manager-applet.enable = mkDefault true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@ in
|
|||
enable = mkDefault true;
|
||||
createDirectories = mkDefault true;
|
||||
};
|
||||
portal.enable = mkDefault true;
|
||||
portal.extraPortals = [ portal ];
|
||||
portal.configPackages = [ portal ];
|
||||
portal = {
|
||||
enable = mkDefault true;
|
||||
extraPortals = [ portal ];
|
||||
configPackages = [ portal ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@ let
|
|||
in
|
||||
{
|
||||
urls = [ { template = engine.url; } ];
|
||||
icon = engine.icon;
|
||||
inherit (engine) icon;
|
||||
updateInterval = if (isUrl engine.icon) then every_day else null;
|
||||
definedAliases = optional (engine ? alias) engine.alias;
|
||||
};
|
||||
|
||||
transformedEngines = mapAttrs' (name: engine: {
|
||||
name = name;
|
||||
inherit name;
|
||||
value = transformEngine engine;
|
||||
}) engines;
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ in
|
|||
profiles.default.search.engines = mapAttrs (_: name: transformedEngines.${name}) (
|
||||
listToAttrs (
|
||||
map (name: {
|
||||
name = name;
|
||||
inherit name;
|
||||
value = name;
|
||||
}) cfg.searchEngines
|
||||
)
|
||||
|
|
|
|||
|
|
@ -16,17 +16,19 @@ in
|
|||
{
|
||||
config = {
|
||||
programs.nixvim = {
|
||||
plugins.treesitter = {
|
||||
enable = mkDefault true;
|
||||
nixvimInjections = mkDefault true;
|
||||
settings = {
|
||||
folding.enable = mkDefault true;
|
||||
highlight.enable = mkDefault true;
|
||||
indent.enable = mkDefault true;
|
||||
plugins = {
|
||||
treesitter = {
|
||||
enable = mkDefault true;
|
||||
nixvimInjections = mkDefault true;
|
||||
settings = {
|
||||
folding.enable = mkDefault true;
|
||||
highlight.enable = mkDefault true;
|
||||
indent.enable = mkDefault true;
|
||||
};
|
||||
};
|
||||
treesitter-context = mkIf plugin.enable { enable = mkDefault true; };
|
||||
treesitter-textobjects = mkIf plugin.enable { enable = mkDefault true; };
|
||||
};
|
||||
plugins.treesitter-context = mkIf plugin.enable { enable = mkDefault true; };
|
||||
plugins.treesitter-textobjects = mkIf plugin.enable { enable = mkDefault true; };
|
||||
};
|
||||
|
||||
# Fix for: ERROR `cc` executable not found.
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
let
|
||||
cfg = config.programs.passwordManager;
|
||||
passmenuScript = pkgs.writeShellScriptBin "passmenu-bemenu" (builtins.readFile ./passmenu); # TODO: override original passmenu script coming from pass itself
|
||||
passff-host = pkgs.passff-host;
|
||||
inherit (pkgs) passff-host;
|
||||
|
||||
inherit (lib)
|
||||
mkDefault
|
||||
|
|
|
|||
|
|
@ -29,8 +29,7 @@ let
|
|||
"moonfly"
|
||||
"oxocarbon"
|
||||
];
|
||||
schemeName =
|
||||
if builtins.elem cfg.scheme needsSuffix then "${cfg.scheme}-${cfg.polarity}" else cfg.scheme;
|
||||
schemeName = if builtins.elem cfg.scheme needsSuffix then "${cfg.scheme}-${cfg.polarity}" else cfg.scheme;
|
||||
|
||||
inherit (lib)
|
||||
mkDefault
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
---
|
||||
system: "base16"
|
||||
name: "Moonfly"
|
||||
description: "A dark theme inspired by the Moonfly color scheme."
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
---
|
||||
system: "base16"
|
||||
name: "Oxocarbon"
|
||||
description: "A dark theme inspired by the Oxocarbon Dark color scheme."
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ let
|
|||
let
|
||||
newsboat = "${pkgs.newsboat}/bin/newsboat";
|
||||
in
|
||||
(pkgs.writeShellScriptBin "newsboat-print-unread" ''
|
||||
pkgs.writeShellScriptBin "newsboat-print-unread" ''
|
||||
UNREAD=$(${newsboat} -x print-unread | awk '{print $1}')
|
||||
|
||||
if [[ $UNREAD -gt 0 ]]; then
|
||||
printf " %i" "$UNREAD"
|
||||
fi
|
||||
'');
|
||||
'';
|
||||
|
||||
inherit (lib) mkDefault;
|
||||
in
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
TIMER_FILE="/tmp/timer" # file to store the current time
|
||||
SIGNAL=11 # signal number to send to status bar
|
||||
STATUS_BAR="waybar" # Support for more status bars?
|
||||
|
|
@ -16,7 +17,7 @@ start_timer() {
|
|||
notify-send "Timer Started" "Your countdown timer has been started."
|
||||
|
||||
trap "exit" INT TERM
|
||||
trap "rm -f -- '$TIMER_FILE'" EXIT
|
||||
trap 'rm -f -- "$TIMER_FILE"' EXIT
|
||||
|
||||
while [ $total_seconds -gt 0 ]; do
|
||||
hours=$(( total_seconds / 3600 ))
|
||||
|
|
@ -62,7 +63,7 @@ if [ "$1" = "start" ]; then
|
|||
MINUTES=${MINUTES:-0}
|
||||
SECONDS=${SECONDS:-0}
|
||||
|
||||
start_timer $HOURS $MINUTES $SECONDS
|
||||
start_timer "$HOURS" "$MINUTES" "$SECONDS"
|
||||
|
||||
elif [ "$1" = "stop" ]; then
|
||||
notify-send "Timer Stopped" "Your countdown timer has been stopped."
|
||||
|
|
|
|||
|
|
@ -4,10 +4,16 @@ let
|
|||
inherit (lib) mkDefault;
|
||||
in
|
||||
{
|
||||
hardware.bluetooth.enable = mkDefault true;
|
||||
hardware.bluetooth.powerOnBoot = mkDefault false;
|
||||
hardware.bluetooth.settings.General.Enable = mkDefault "Source,Sink,Media,Socket";
|
||||
hardware.bluetooth.settings.General.Experimental = mkDefault true;
|
||||
hardware = {
|
||||
bluetooth = {
|
||||
enable = mkDefault true;
|
||||
powerOnBoot = mkDefault false;
|
||||
settings.General = {
|
||||
Enable = mkDefault "Source,Sink,Media,Socket";
|
||||
Experimental = mkDefault true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
blueman
|
||||
|
|
|
|||
|
|
@ -84,8 +84,6 @@ in
|
|||
) { } cfg.remotes;
|
||||
|
||||
# Ensure that all cifs-mount services are started with the graphical session
|
||||
systemd.user.targets.graphical-session.wants = map (
|
||||
remote: "cifs-mount-${remote.shareName}.service"
|
||||
) cfg.remotes;
|
||||
systemd.user.targets.graphical-session.wants = map (remote: "cifs-mount-${remote.shareName}.service") cfg.remotes;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
{ lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
# fix CVE-2026-31431
|
||||
boot.kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.18.22") (
|
||||
lib.mkDefault pkgs.linuxPackages_6_18
|
||||
);
|
||||
boot = {
|
||||
# fix CVE-2026-31431
|
||||
kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.18.22") (lib.mkDefault pkgs.linuxPackages_6_18);
|
||||
|
||||
# fix CVE-2026-43500
|
||||
boot.extraModprobeConfig = ''
|
||||
install esp4 ${pkgs.coreutils}/bin/false
|
||||
install esp6 ${pkgs.coreutils}/bin/false
|
||||
install rxrpc ${pkgs.coreutils}/bin/false
|
||||
'';
|
||||
boot.blacklistedKernelModules = [
|
||||
"esp4"
|
||||
"esp6"
|
||||
"rxrpc"
|
||||
];
|
||||
# fix CVE-2026-43500
|
||||
extraModprobeConfig = ''
|
||||
install esp4 ${pkgs.coreutils}/bin/false
|
||||
install esp6 ${pkgs.coreutils}/bin/false
|
||||
install rxrpc ${pkgs.coreutils}/bin/false
|
||||
'';
|
||||
blacklistedKernelModules = [
|
||||
"esp4"
|
||||
"esp6"
|
||||
"rxrpc"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,55 +9,59 @@ let
|
|||
inherit (lib) mkDefault optionals;
|
||||
in
|
||||
{
|
||||
environment.systemPackages =
|
||||
with pkgs;
|
||||
[
|
||||
cryptsetup
|
||||
curl
|
||||
dig
|
||||
dnsutils
|
||||
fzf
|
||||
gptfdisk
|
||||
iproute2
|
||||
jq
|
||||
lm_sensors
|
||||
lsof
|
||||
netcat-openbsd
|
||||
nettools
|
||||
nixos-container
|
||||
nmap
|
||||
nurl
|
||||
p7zip
|
||||
pciutils
|
||||
psmisc
|
||||
rclone
|
||||
rsync
|
||||
tcpdump
|
||||
tmux
|
||||
tree
|
||||
unzip
|
||||
usbutils
|
||||
wget
|
||||
xxd
|
||||
zip
|
||||
environment = {
|
||||
systemPackages =
|
||||
with pkgs;
|
||||
[
|
||||
cryptsetup
|
||||
curl
|
||||
dig
|
||||
dnsutils
|
||||
fzf
|
||||
gptfdisk
|
||||
iproute2
|
||||
jq
|
||||
lm_sensors
|
||||
lsof
|
||||
netcat-openbsd
|
||||
nettools
|
||||
nixos-container
|
||||
nmap
|
||||
nurl
|
||||
p7zip
|
||||
pciutils
|
||||
psmisc
|
||||
rclone
|
||||
rsync
|
||||
tcpdump
|
||||
tmux
|
||||
tree
|
||||
unzip
|
||||
usbutils
|
||||
wget
|
||||
xxd
|
||||
zip
|
||||
|
||||
(callPackage ../../../apps/rebuild { })
|
||||
]
|
||||
++ optionals (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) [
|
||||
pkgs.kitty.terminfo
|
||||
];
|
||||
(callPackage ../../../apps/rebuild { })
|
||||
]
|
||||
++ optionals (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) [
|
||||
pkgs.kitty.terminfo
|
||||
];
|
||||
|
||||
environment.shellAliases = {
|
||||
l = "ls -lh";
|
||||
ll = "ls -lAh";
|
||||
ports = "ss -tulpn";
|
||||
publicip = "curl ifconfig.me/all";
|
||||
sudo = "sudo "; # make aliases work with `sudo`
|
||||
shellAliases = {
|
||||
l = "ls -lh";
|
||||
ll = "ls -lAh";
|
||||
ports = "ss -tulpn";
|
||||
publicip = "curl ifconfig.me/all";
|
||||
sudo = "sudo "; # make aliases work with `sudo`
|
||||
};
|
||||
|
||||
# saves one instance of nixpkgs.
|
||||
ldso32 = null;
|
||||
};
|
||||
|
||||
# saves one instance of nixpkgs.
|
||||
environment.ldso32 = null;
|
||||
|
||||
boot.tmp.cleanOnBoot = mkDefault true;
|
||||
boot.initrd.systemd.enable = mkDefault (!config.boot.swraid.enable && !config.boot.isContainer);
|
||||
boot = {
|
||||
tmp.cleanOnBoot = mkDefault true;
|
||||
initrd.systemd.enable = mkDefault (!config.boot.swraid.enable && !config.boot.isContainer);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,13 @@
|
|||
# avoid TOFU MITM
|
||||
programs.ssh.knownHosts = {
|
||||
"github.com".hostNames = [ "github.com" ];
|
||||
"github.com".publicKey =
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
|
||||
"github.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
|
||||
|
||||
"gitlab.com".hostNames = [ "gitlab.com" ];
|
||||
"gitlab.com".publicKey =
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf";
|
||||
"gitlab.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf";
|
||||
|
||||
"git.sr.ht".hostNames = [ "git.sr.ht" ];
|
||||
"git.sr.ht".publicKey =
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZvRd4EtM7R+IHVMWmDkVU3VLQTSwQDSAvW0t2Tkj60";
|
||||
"git.sr.ht".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZvRd4EtM7R+IHVMWmDkVU3VLQTSwQDSAvW0t2Tkj60";
|
||||
};
|
||||
# TODO: add synix
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,12 +42,8 @@ in
|
|||
static-auth-secret-file = mkIf cfg.sops config.sops.secrets."coturn/static-auth-secret".path;
|
||||
realm = mkDefault "turn.${config.networking.domain}";
|
||||
|
||||
cert =
|
||||
mkIf (!cfg.no-tls && cfg.sops)
|
||||
"${config.security.acme.certs.${cfg.realm}.directory}/full.pem";
|
||||
pkey =
|
||||
mkIf (!cfg.no-tls && cfg.sops)
|
||||
"${config.security.acme.certs.${cfg.realm}.directory}/key.pem";
|
||||
cert = mkIf (!cfg.no-tls && cfg.sops) "${config.security.acme.certs.${cfg.realm}.directory}/full.pem";
|
||||
pkey = mkIf (!cfg.no-tls && cfg.sops) "${config.security.acme.certs.${cfg.realm}.directory}/key.pem";
|
||||
|
||||
extraConfig = ''
|
||||
# ban private IP ranges
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@ in
|
|||
|
||||
fonts.fontconfig.enable = mkDefault false;
|
||||
|
||||
xdg.autostart.enable = mkDefault false;
|
||||
xdg.icons.enable = mkDefault false;
|
||||
xdg.menus.enable = mkDefault false;
|
||||
xdg.mime.enable = mkDefault false;
|
||||
xdg.sounds.enable = mkDefault false;
|
||||
xdg = {
|
||||
autostart.enable = mkDefault false;
|
||||
icons.enable = mkDefault false;
|
||||
menus.enable = mkDefault false;
|
||||
mime.enable = mkDefault false;
|
||||
sounds.enable = mkDefault false;
|
||||
};
|
||||
|
||||
programs.git.package = mkDefault pkgs.gitMinimal;
|
||||
|
||||
|
|
@ -48,22 +50,25 @@ in
|
|||
viAlias = mkDefault true;
|
||||
};
|
||||
|
||||
# emergency mode is useless on headless machines
|
||||
systemd.enableEmergencyMode = false;
|
||||
systemd = {
|
||||
# emergency mode is useless on headless machines
|
||||
enableEmergencyMode = false;
|
||||
|
||||
sleep.extraConfig = ''
|
||||
AllowSuspend=no
|
||||
AllowHibernation=no
|
||||
'';
|
||||
|
||||
# force reboots
|
||||
settings.Manager = {
|
||||
RuntimeWatchdogSec = mkDefault "15s";
|
||||
RebootWatchdogSec = mkDefault "30s";
|
||||
KExecWatchdogSec = mkDefault "1m";
|
||||
};
|
||||
};
|
||||
|
||||
boot.initrd.systemd.suppressedUnits = mkIf config.systemd.enableEmergencyMode [
|
||||
"emergency.service"
|
||||
"emergency.target"
|
||||
];
|
||||
|
||||
systemd.sleep.extraConfig = ''
|
||||
AllowSuspend=no
|
||||
AllowHibernation=no
|
||||
'';
|
||||
|
||||
# force reboots
|
||||
systemd.settings.Manager = {
|
||||
RuntimeWatchdogSec = mkDefault "15s";
|
||||
RebootWatchdogSec = mkDefault "30s";
|
||||
KExecWatchdogSec = mkDefault "1m";
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ let
|
|||
inherit (lib) mkDefault;
|
||||
in
|
||||
{
|
||||
services.qemuGuest.enable = mkDefault true;
|
||||
services.spice-vdagentd.enable = mkDefault true;
|
||||
services.spice-webdavd.enable = mkDefault true;
|
||||
services = {
|
||||
qemuGuest.enable = mkDefault true;
|
||||
spice-vdagentd.enable = mkDefault true;
|
||||
spice-webdavd.enable = mkDefault true;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
let
|
||||
cfg = config.services.ftp-webserver;
|
||||
domain = config.networking.domain;
|
||||
inherit (config.networking) domain;
|
||||
fqdn = if (cfg.subdomain != "") then "${cfg.subdomain}.${domain}" else domain;
|
||||
nginx = config.services.nginx;
|
||||
inherit (config.services) nginx;
|
||||
|
||||
inherit (lib)
|
||||
mkEnableOption
|
||||
|
|
@ -35,7 +35,7 @@ in
|
|||
|
||||
config = mkIf cfg.enable {
|
||||
services.nginx.virtualHosts."${fqdn}" = {
|
||||
root = cfg.root;
|
||||
inherit (cfg) root;
|
||||
locations."/" = {
|
||||
extraConfig = ''
|
||||
autoindex on;
|
||||
|
|
@ -43,7 +43,7 @@ in
|
|||
autoindex_localtime on;
|
||||
'';
|
||||
};
|
||||
forceSSL = cfg.forceSSL;
|
||||
inherit (cfg) forceSSL;
|
||||
enableACME = cfg.forceSSL;
|
||||
sslCertificate = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/cert.pem";
|
||||
sslCertificateKey = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/key.pem";
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
let
|
||||
cfg = config.services.headplane;
|
||||
domain = config.networking.domain;
|
||||
subdomain = cfg.reverseProxy.subdomain;
|
||||
inherit (config.networking) domain;
|
||||
inherit (cfg.reverseProxy) subdomain;
|
||||
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
|
||||
headscale = config.services.headscale;
|
||||
inherit (config.services) headscale;
|
||||
|
||||
inherit (lib)
|
||||
mkDefault
|
||||
|
|
@ -55,7 +55,7 @@ in
|
|||
|
||||
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
|
||||
"${fqdn}" = mkVirtualHost {
|
||||
port = cfg.settings.server.port;
|
||||
inherit (cfg.settings.server) port;
|
||||
ssl = cfg.reverseProxy.forceSSL;
|
||||
};
|
||||
};
|
||||
|
|
@ -63,7 +63,7 @@ in
|
|||
sops.secrets =
|
||||
let
|
||||
owner = headscale.user;
|
||||
group = headscale.group;
|
||||
inherit (headscale) group;
|
||||
mode = "0400";
|
||||
in
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
let
|
||||
cfg = config.services.headscale;
|
||||
domain = config.networking.domain;
|
||||
subdomain = cfg.reverseProxy.subdomain;
|
||||
inherit (config.networking) domain;
|
||||
inherit (cfg.reverseProxy) subdomain;
|
||||
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
|
||||
acl = "headscale/acl.hujson";
|
||||
|
||||
|
|
|
|||
|
|
@ -8,23 +8,9 @@ in
|
|||
|
||||
programs.dconf.enable = true; # fixes nixvim hm module
|
||||
|
||||
services.flatpak.enable = true;
|
||||
|
||||
xdg.portal = {
|
||||
enable = true;
|
||||
extraPortals = with pkgs; [
|
||||
xdg-desktop-portal-gtk
|
||||
];
|
||||
config.common.default = "gtk";
|
||||
services = {
|
||||
flatpak.enable = true;
|
||||
gnome.gnome-keyring.enable = true;
|
||||
udisks2.enable = mkDefault true;
|
||||
};
|
||||
|
||||
services.gnome.gnome-keyring.enable = true;
|
||||
security.pam.services = {
|
||||
login = {
|
||||
enableGnomeKeyring = true;
|
||||
};
|
||||
hyprlock = { };
|
||||
};
|
||||
|
||||
services.udisks2.enable = mkDefault true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
let
|
||||
cfg = config.services.jellyfin;
|
||||
domain = config.networking.domain;
|
||||
subdomain = cfg.reverseProxy.subdomain;
|
||||
inherit (config.networking) domain;
|
||||
inherit (cfg.reverseProxy) subdomain;
|
||||
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
|
||||
|
||||
inherit (lib)
|
||||
|
|
@ -48,9 +48,7 @@ in
|
|||
];
|
||||
|
||||
systemd.tmpfiles.rules =
|
||||
(map (
|
||||
library: "d ${cfg.dataDir}/libraries/${library} 0770 ${cfg.user} ${cfg.group} -"
|
||||
) cfg.libraries)
|
||||
(map (library: "d ${cfg.dataDir}/libraries/${library} 0770 ${cfg.user} ${cfg.group} -") cfg.libraries)
|
||||
++ [
|
||||
"z ${cfg.dataDir} 0770 ${cfg.user} ${cfg.group} -"
|
||||
"Z ${cfg.dataDir}/libraries 0770 ${cfg.user} ${cfg.group} -"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
let
|
||||
cfg = config.services.jirafeau;
|
||||
domain = config.networking.domain;
|
||||
subdomain = cfg.reverseProxy.subdomain;
|
||||
inherit (config.networking) domain;
|
||||
inherit (cfg.reverseProxy) subdomain;
|
||||
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
|
||||
|
||||
inherit (lib)
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ let
|
|||
mkOption {
|
||||
type = types.package;
|
||||
default = defaultImages.${name};
|
||||
description = description;
|
||||
inherit description;
|
||||
};
|
||||
|
||||
inherit (lib)
|
||||
|
|
@ -236,10 +236,123 @@ in
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
virtualisation.podman = {
|
||||
enable = true;
|
||||
autoPrune.enable = true;
|
||||
dockerCompat = true;
|
||||
virtualisation = {
|
||||
podman = {
|
||||
enable = true;
|
||||
autoPrune.enable = true;
|
||||
dockerCompat = true;
|
||||
};
|
||||
|
||||
oci-containers = {
|
||||
backend = "podman";
|
||||
|
||||
containers = {
|
||||
librechat-mongodb = {
|
||||
image = with cfg.images.mongodb; "${imageName}:${imageTag}";
|
||||
imageFile = cfg.images.mongodb;
|
||||
cmd = [
|
||||
"mongod"
|
||||
"--noauth"
|
||||
];
|
||||
volumes = [
|
||||
"librechat_mongodb_data:/data/db:rw"
|
||||
];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--network-alias=mongodb"
|
||||
"--network=librechat_default"
|
||||
];
|
||||
};
|
||||
|
||||
librechat-meilisearch = {
|
||||
image = with cfg.images.meilisearch; "${imageName}:${imageTag}";
|
||||
imageFile = cfg.images.meilisearch;
|
||||
environment = {
|
||||
MEILI_NO_ANALYTICS = "true";
|
||||
MEILI_HOST = "http://meilisearch:${toString cfg.meiliPort}";
|
||||
};
|
||||
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
|
||||
volumes = [
|
||||
"librechat_meili_data:/meili_data:rw"
|
||||
];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--network-alias=meilisearch"
|
||||
"--network=librechat_default"
|
||||
];
|
||||
};
|
||||
|
||||
librechat-vectordb = {
|
||||
image = with cfg.images.vectordb; "${imageName}:${imageTag}";
|
||||
imageFile = cfg.images.vectordb;
|
||||
environment = {
|
||||
POSTGRES_DB = "mydatabase";
|
||||
POSTGRES_USER = "myuser";
|
||||
POSTGRES_PASSWORD = "mypassword";
|
||||
};
|
||||
volumes = [
|
||||
"librechat_pgdata:/var/lib/postgresql/data:rw"
|
||||
];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--network-alias=vectordb"
|
||||
"--network=librechat_default"
|
||||
];
|
||||
};
|
||||
|
||||
librechat-rag-api = {
|
||||
image = with cfg.images.ragApi; "${imageName}:${imageTag}";
|
||||
imageFile = cfg.images.ragApi;
|
||||
environment = {
|
||||
DB_HOST = "vectordb";
|
||||
RAG_PORT = toString cfg.ragPort;
|
||||
};
|
||||
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
|
||||
dependsOn = [ "librechat-vectordb" ];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--network-alias=rag_api"
|
||||
"--network=librechat_default"
|
||||
];
|
||||
};
|
||||
|
||||
librechat = {
|
||||
image = with cfg.images.librechat; "${imageName}:${imageTag}";
|
||||
imageFile = cfg.images.librechat;
|
||||
environment =
|
||||
defaultEnv
|
||||
// {
|
||||
MONGO_URI = "mongodb://mongodb:27017/LibreChat";
|
||||
MEILI_HOST = "http://meilisearch:${toString cfg.meiliPort}";
|
||||
RAG_PORT = toString cfg.ragPort;
|
||||
RAG_API_URL = "http://rag_api:${toString cfg.ragPort}";
|
||||
DOMAIN_CLIENT = if cfg.externalUrl != null then cfg.externalUrl else "http://localhost:${toString cfg.port}";
|
||||
DOMAIN_SERVER = if cfg.externalUrl != null then cfg.externalUrl else "http://localhost:${toString cfg.port}";
|
||||
}
|
||||
// cfg.environment;
|
||||
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
|
||||
volumes = [
|
||||
"librechat_images:/app/client/public/images:rw"
|
||||
"librechat_uploads:/app/uploads:rw"
|
||||
"librechat_logs:/app/logs:rw"
|
||||
]
|
||||
++ optional (cfg.configFile != null) "${cfg.configFile}:/app/librechat.yaml:ro";
|
||||
|
||||
ports = [
|
||||
"0.0.0.0:${toString cfg.port}:${toString cfg.port}/tcp"
|
||||
];
|
||||
dependsOn = [
|
||||
"librechat-mongodb"
|
||||
"librechat-rag-api"
|
||||
];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--network-alias=api"
|
||||
"--network=librechat_default"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.interfaces =
|
||||
|
|
@ -250,278 +363,173 @@ in
|
|||
"${matchAll}".allowedUDPPorts = [ 53 ];
|
||||
};
|
||||
|
||||
virtualisation.oci-containers.backend = "podman";
|
||||
systemd = {
|
||||
services = {
|
||||
podman-librechat-mongodb = {
|
||||
serviceConfig.Restart = mkOverride 90 "always";
|
||||
after = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_mongodb_data.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_mongodb_data.service"
|
||||
];
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
virtualisation.oci-containers.containers.librechat-mongodb = {
|
||||
image = with cfg.images.mongodb; "${imageName}:${imageTag}";
|
||||
imageFile = cfg.images.mongodb;
|
||||
cmd = [
|
||||
"mongod"
|
||||
"--noauth"
|
||||
];
|
||||
volumes = [
|
||||
"librechat_mongodb_data:/data/db:rw"
|
||||
];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--network-alias=mongodb"
|
||||
"--network=librechat_default"
|
||||
];
|
||||
};
|
||||
podman-librechat-meilisearch = {
|
||||
serviceConfig.Restart = mkOverride 90 "always";
|
||||
after = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_meili_data.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_meili_data.service"
|
||||
];
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
virtualisation.oci-containers.containers.librechat-meilisearch = {
|
||||
image = with cfg.images.meilisearch; "${imageName}:${imageTag}";
|
||||
imageFile = cfg.images.meilisearch;
|
||||
environment = {
|
||||
MEILI_NO_ANALYTICS = "true";
|
||||
MEILI_HOST = "http://meilisearch:${toString cfg.meiliPort}";
|
||||
podman-librechat-vectordb = {
|
||||
serviceConfig.Restart = mkOverride 90 "always";
|
||||
after = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_pgdata.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_pgdata.service"
|
||||
];
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
podman-librechat-rag-api = {
|
||||
serviceConfig.Restart = mkOverride 90 "always";
|
||||
after = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-librechat-vectordb.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-librechat-vectordb.service"
|
||||
];
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
podman-librechat = {
|
||||
serviceConfig.Restart = mkOverride 90 "always";
|
||||
after = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_images.service"
|
||||
"podman-volume-librechat_uploads.service"
|
||||
"podman-volume-librechat_logs.service"
|
||||
"podman-librechat-mongodb.service"
|
||||
"podman-librechat-meilisearch.service"
|
||||
"podman-librechat-rag-api.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_images.service"
|
||||
"podman-volume-librechat_uploads.service"
|
||||
"podman-volume-librechat_logs.service"
|
||||
"podman-librechat-mongodb.service"
|
||||
"podman-librechat-meilisearch.service"
|
||||
"podman-librechat-rag-api.service"
|
||||
];
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
podman-network-librechat_default = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStop = "podman network rm -f librechat_default";
|
||||
};
|
||||
script = ''
|
||||
podman network inspect librechat_default || podman network create librechat_default
|
||||
'';
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
podman-volume-librechat_mongodb_data = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = "podman volume inspect librechat_mongodb_data || podman volume create librechat_mongodb_data";
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
podman-volume-librechat_meili_data = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = "podman volume inspect librechat_meili_data || podman volume create librechat_meili_data";
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
podman-volume-librechat_pgdata = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = "podman volume inspect librechat_pgdata || podman volume create librechat_pgdata";
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
podman-volume-librechat_images = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = "podman volume inspect librechat_images || podman volume create librechat_images";
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
podman-volume-librechat_uploads = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = "podman volume inspect librechat_uploads || podman volume create librechat_uploads";
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
podman-volume-librechat_logs = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = "podman volume inspect librechat_logs || podman volume create librechat_logs";
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
};
|
||||
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
|
||||
volumes = [
|
||||
"librechat_meili_data:/meili_data:rw"
|
||||
];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--network-alias=meilisearch"
|
||||
"--network=librechat_default"
|
||||
];
|
||||
};
|
||||
|
||||
virtualisation.oci-containers.containers.librechat-vectordb = {
|
||||
image = with cfg.images.vectordb; "${imageName}:${imageTag}";
|
||||
imageFile = cfg.images.vectordb;
|
||||
environment = {
|
||||
POSTGRES_DB = "mydatabase";
|
||||
POSTGRES_USER = "myuser";
|
||||
POSTGRES_PASSWORD = "mypassword";
|
||||
targets.podman-compose-librechat-root = {
|
||||
unitConfig.Description = "Root target generated by compose2nix.";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
volumes = [
|
||||
"librechat_pgdata:/var/lib/postgresql/data:rw"
|
||||
];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--network-alias=vectordb"
|
||||
"--network=librechat_default"
|
||||
];
|
||||
};
|
||||
|
||||
virtualisation.oci-containers.containers.librechat-rag-api = {
|
||||
image = with cfg.images.ragApi; "${imageName}:${imageTag}";
|
||||
imageFile = cfg.images.ragApi;
|
||||
environment = {
|
||||
DB_HOST = "vectordb";
|
||||
RAG_PORT = toString cfg.ragPort;
|
||||
};
|
||||
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
|
||||
dependsOn = [ "librechat-vectordb" ];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--network-alias=rag_api"
|
||||
"--network=librechat_default"
|
||||
];
|
||||
};
|
||||
|
||||
virtualisation.oci-containers.containers.librechat = {
|
||||
image = with cfg.images.librechat; "${imageName}:${imageTag}";
|
||||
imageFile = cfg.images.librechat;
|
||||
environment =
|
||||
defaultEnv
|
||||
// {
|
||||
MONGO_URI = "mongodb://mongodb:27017/LibreChat";
|
||||
MEILI_HOST = "http://meilisearch:${toString cfg.meiliPort}";
|
||||
RAG_PORT = toString cfg.ragPort;
|
||||
RAG_API_URL = "http://rag_api:${toString cfg.ragPort}";
|
||||
DOMAIN_CLIENT =
|
||||
if cfg.externalUrl != null then cfg.externalUrl else "http://localhost:${toString cfg.port}";
|
||||
DOMAIN_SERVER =
|
||||
if cfg.externalUrl != null then cfg.externalUrl else "http://localhost:${toString cfg.port}";
|
||||
}
|
||||
// cfg.environment;
|
||||
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
|
||||
volumes = [
|
||||
"librechat_images:/app/client/public/images:rw"
|
||||
"librechat_uploads:/app/uploads:rw"
|
||||
"librechat_logs:/app/logs:rw"
|
||||
]
|
||||
++ optional (cfg.configFile != null) "${cfg.configFile}:/app/librechat.yaml:ro";
|
||||
|
||||
ports = [
|
||||
"0.0.0.0:${toString cfg.port}:${toString cfg.port}/tcp"
|
||||
];
|
||||
dependsOn = [
|
||||
"librechat-mongodb"
|
||||
"librechat-rag-api"
|
||||
];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--network-alias=api"
|
||||
"--network=librechat_default"
|
||||
];
|
||||
};
|
||||
|
||||
systemd.services.podman-librechat-mongodb = {
|
||||
serviceConfig.Restart = mkOverride 90 "always";
|
||||
after = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_mongodb_data.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_mongodb_data.service"
|
||||
];
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
systemd.services.podman-librechat-meilisearch = {
|
||||
serviceConfig.Restart = mkOverride 90 "always";
|
||||
after = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_meili_data.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_meili_data.service"
|
||||
];
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
systemd.services.podman-librechat-vectordb = {
|
||||
serviceConfig.Restart = mkOverride 90 "always";
|
||||
after = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_pgdata.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_pgdata.service"
|
||||
];
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
systemd.services.podman-librechat-rag-api = {
|
||||
serviceConfig.Restart = mkOverride 90 "always";
|
||||
after = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-librechat-vectordb.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-librechat-vectordb.service"
|
||||
];
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
systemd.services.podman-librechat = {
|
||||
serviceConfig.Restart = mkOverride 90 "always";
|
||||
after = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_images.service"
|
||||
"podman-volume-librechat_uploads.service"
|
||||
"podman-volume-librechat_logs.service"
|
||||
"podman-librechat-mongodb.service"
|
||||
"podman-librechat-meilisearch.service"
|
||||
"podman-librechat-rag-api.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-network-librechat_default.service"
|
||||
"podman-volume-librechat_images.service"
|
||||
"podman-volume-librechat_uploads.service"
|
||||
"podman-volume-librechat_logs.service"
|
||||
"podman-librechat-mongodb.service"
|
||||
"podman-librechat-meilisearch.service"
|
||||
"podman-librechat-rag-api.service"
|
||||
];
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
systemd.services.podman-network-librechat_default = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStop = "podman network rm -f librechat_default";
|
||||
};
|
||||
script = ''
|
||||
podman network inspect librechat_default || podman network create librechat_default
|
||||
'';
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
systemd.services.podman-volume-librechat_mongodb_data = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = "podman volume inspect librechat_mongodb_data || podman volume create librechat_mongodb_data";
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
systemd.services.podman-volume-librechat_meili_data = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = "podman volume inspect librechat_meili_data || podman volume create librechat_meili_data";
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
systemd.services.podman-volume-librechat_pgdata = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = "podman volume inspect librechat_pgdata || podman volume create librechat_pgdata";
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
systemd.services.podman-volume-librechat_images = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = "podman volume inspect librechat_images || podman volume create librechat_images";
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
systemd.services.podman-volume-librechat_uploads = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = "podman volume inspect librechat_uploads || podman volume create librechat_uploads";
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
systemd.services.podman-volume-librechat_logs = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = "podman volume inspect librechat_logs || podman volume create librechat_logs";
|
||||
partOf = [ "podman-compose-librechat-root.target" ];
|
||||
wantedBy = [ "podman-compose-librechat-root.target" ];
|
||||
};
|
||||
|
||||
systemd.targets.podman-compose-librechat-root = {
|
||||
unitConfig.Description = "Root target generated by compose2nix.";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
let
|
||||
cfg = config.mailserver;
|
||||
domain = config.networking.domain;
|
||||
inherit (config.networking) domain;
|
||||
fqdn = "${cfg.subdomain}.${domain}";
|
||||
|
||||
inherit (lib)
|
||||
|
|
@ -74,7 +74,7 @@ in
|
|||
nameValuePair "${user}@${domain}" {
|
||||
name = "${user}@${domain}";
|
||||
aliases = map (alias: "${alias}@${domain}") (accConf.aliases or [ ]);
|
||||
sendOnly = accConf.sendOnly;
|
||||
inherit (accConf) sendOnly;
|
||||
quota = mkDefault "5G";
|
||||
hashedPasswordFile = config.sops.secrets."mailserver/accounts/${user}".path;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ let
|
|||
|
||||
services."mautrix-${name}" = {
|
||||
enable = true;
|
||||
package = cfg.bridges.${name}.package;
|
||||
inherit (cfg.bridges.${name}) package;
|
||||
environmentFile = mkIf cfg.sops config.sops.templates."mautrix-${name}/env-file".path;
|
||||
settings = {
|
||||
bridge = {
|
||||
|
|
@ -71,33 +71,29 @@ let
|
|||
mode = "0400";
|
||||
in
|
||||
{
|
||||
secrets."mautrix-${name}/encryption-pickle-key" = {
|
||||
inherit owner group mode;
|
||||
};
|
||||
secrets."mautrix-${name}/provisioning-shared-secret" = {
|
||||
inherit owner group mode;
|
||||
};
|
||||
secrets."mautrix-${name}/public-media-signing-key" = {
|
||||
inherit owner group mode;
|
||||
};
|
||||
secrets."mautrix-${name}/direct-media-server-key" = {
|
||||
inherit owner group mode;
|
||||
secrets = {
|
||||
"mautrix-${name}/encryption-pickle-key" = {
|
||||
inherit owner group mode;
|
||||
};
|
||||
"mautrix-${name}/provisioning-shared-secret" = {
|
||||
inherit owner group mode;
|
||||
};
|
||||
"mautrix-${name}/public-media-signing-key" = {
|
||||
inherit owner group mode;
|
||||
};
|
||||
"mautrix-${name}/direct-media-server-key" = {
|
||||
inherit owner group mode;
|
||||
};
|
||||
};
|
||||
templates."mautrix-${name}/env-file" = {
|
||||
inherit owner group mode;
|
||||
content = ''
|
||||
MAUTRIX_${toUpper name}_ENCRYPTION_PICKLE_KEY=${
|
||||
config.sops.placeholder."mautrix-${name}/encryption-pickle-key"
|
||||
}
|
||||
MAUTRIX_${toUpper name}_ENCRYPTION_PICKLE_KEY=${config.sops.placeholder."mautrix-${name}/encryption-pickle-key"}
|
||||
MAUTRIX_${toUpper name}_PROVISIONING_SHARED_SECRET=${
|
||||
config.sops.placeholder."mautrix-${name}/provisioning-shared-secret"
|
||||
}
|
||||
MAUTRIX_${toUpper name}_PUBLIC_MEDIA_SIGNING_KEY=${
|
||||
config.sops.placeholder."mautrix-${name}/public-media-signing-key"
|
||||
}
|
||||
MAUTRIX_${toUpper name}_DIRECT_MEDIA_SERVER_KEY=${
|
||||
config.sops.placeholder."mautrix-${name}/direct-media-server-key"
|
||||
}
|
||||
MAUTRIX_${toUpper name}_PUBLIC_MEDIA_SIGNING_KEY=${config.sops.placeholder."mautrix-${name}/public-media-signing-key"}
|
||||
MAUTRIX_${toUpper name}_DIRECT_MEDIA_SERVER_KEY=${config.sops.placeholder."mautrix-${name}/direct-media-server-key"}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,77 +84,74 @@ in
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
initialScript = pkgs.writeText "synapse-init.sql" ''
|
||||
CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
|
||||
CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
|
||||
TEMPLATE template0
|
||||
LC_COLLATE = 'C'
|
||||
LC_CTYPE = 'C';
|
||||
'';
|
||||
};
|
||||
services = {
|
||||
postgresql = {
|
||||
enable = true;
|
||||
initialScript = pkgs.writeText "synapse-init.sql" ''
|
||||
CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
|
||||
CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
|
||||
TEMPLATE template0
|
||||
LC_COLLATE = 'C'
|
||||
LC_CTYPE = 'C';
|
||||
'';
|
||||
};
|
||||
|
||||
services.matrix-synapse = mkMerge [
|
||||
{
|
||||
settings = {
|
||||
registration_shared_secret_path =
|
||||
mkIf cfg.sops
|
||||
config.sops.secrets."matrix/registration-shared-secret".path;
|
||||
server_name = config.networking.domain;
|
||||
public_baseurl = baseUrl;
|
||||
listeners = [
|
||||
{
|
||||
inherit (cfg) port;
|
||||
bind_addresses = [ "127.0.0.1" ];
|
||||
resources = [
|
||||
{
|
||||
compress = true;
|
||||
names = [ "client" ];
|
||||
}
|
||||
{
|
||||
compress = false;
|
||||
names = [ "federation" ];
|
||||
}
|
||||
];
|
||||
tls = false;
|
||||
type = "http";
|
||||
x_forwarded = true;
|
||||
}
|
||||
];
|
||||
matrix-synapse = mkMerge [
|
||||
{
|
||||
settings = {
|
||||
registration_shared_secret_path = mkIf cfg.sops config.sops.secrets."matrix/registration-shared-secret".path;
|
||||
server_name = config.networking.domain;
|
||||
public_baseurl = baseUrl;
|
||||
listeners = [
|
||||
{
|
||||
inherit (cfg) port;
|
||||
bind_addresses = [ "127.0.0.1" ];
|
||||
resources = [
|
||||
{
|
||||
compress = true;
|
||||
names = [ "client" ];
|
||||
}
|
||||
{
|
||||
compress = false;
|
||||
names = [ "federation" ];
|
||||
}
|
||||
];
|
||||
tls = false;
|
||||
type = "http";
|
||||
x_forwarded = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
(mkIf cfg.coturn.enable {
|
||||
settings = {
|
||||
turn_uris = with cfg.coturn; [
|
||||
"turn:${realm}:${toString listening-port}?transport=udp"
|
||||
"turn:${realm}:${toString listening-port}?transport=tcp"
|
||||
"turn:${realm}:${toString tls-listening-port}?transport=udp"
|
||||
"turn:${realm}:${toString tls-listening-port}?transport=tcp"
|
||||
"turn:${realm}:${toString alt-listening-port}?transport=udp"
|
||||
"turn:${realm}:${toString alt-listening-port}?transport=tcp"
|
||||
"turn:${realm}:${toString alt-tls-listening-port}?transport=udp"
|
||||
"turn:${realm}:${toString alt-tls-listening-port}?transport=tcp"
|
||||
];
|
||||
extraConfigFiles = mkIf cfg.sops [ config.sops.templates."coturn/static-auth-secret.env".path ];
|
||||
turn_user_lifetime = "1h";
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
nginx.virtualHosts."${cfg.settings.server_name}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
locations = {
|
||||
"= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
|
||||
"= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
|
||||
"/_matrix".proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
||||
"/_synapse".proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
||||
};
|
||||
}
|
||||
(mkIf cfg.coturn.enable {
|
||||
settings = {
|
||||
turn_uris = with cfg.coturn; [
|
||||
"turn:${realm}:${toString listening-port}?transport=udp"
|
||||
"turn:${realm}:${toString listening-port}?transport=tcp"
|
||||
"turn:${realm}:${toString tls-listening-port}?transport=udp"
|
||||
"turn:${realm}:${toString tls-listening-port}?transport=tcp"
|
||||
"turn:${realm}:${toString alt-listening-port}?transport=udp"
|
||||
"turn:${realm}:${toString alt-listening-port}?transport=tcp"
|
||||
"turn:${realm}:${toString alt-tls-listening-port}?transport=udp"
|
||||
"turn:${realm}:${toString alt-tls-listening-port}?transport=tcp"
|
||||
];
|
||||
extraConfigFiles = mkIf cfg.sops [ config.sops.templates."coturn/static-auth-secret.env".path ];
|
||||
turn_user_lifetime = "1h";
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
environment.shellAliases = mkIf cfg.sops {
|
||||
register_new_matrix_user = "${cfg.package}/bin/register_new_matrix_user -k $(sudo cat ${cfg.settings.registration_shared_secret_path})";
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${cfg.settings.server_name}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
|
||||
locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
|
||||
|
||||
locations."/_matrix".proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
||||
locations."/_synapse".proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
||||
};
|
||||
};
|
||||
|
||||
sops = mkIf cfg.sops {
|
||||
|
|
|
|||
|
|
@ -6,51 +6,53 @@
|
|||
|
||||
let
|
||||
cfg = config.services.matrix-synapse;
|
||||
domain = config.networking.domain;
|
||||
inherit (config.networking) domain;
|
||||
|
||||
inherit (lib) mkIf mkDefault;
|
||||
in
|
||||
{
|
||||
config = mkIf cfg.enable {
|
||||
services.livekit = {
|
||||
enable = true;
|
||||
settings.port = mkDefault 7880;
|
||||
settings.room.auto_create = mkDefault false;
|
||||
openFirewall = mkDefault true;
|
||||
keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path;
|
||||
};
|
||||
services = {
|
||||
livekit = {
|
||||
enable = true;
|
||||
settings.port = mkDefault 7880;
|
||||
settings.room.auto_create = mkDefault false;
|
||||
openFirewall = mkDefault true;
|
||||
keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path;
|
||||
};
|
||||
|
||||
services.lk-jwt-service = {
|
||||
enable = true;
|
||||
port = mkDefault 8080;
|
||||
livekitUrl = "wss://${domain}/livekit/sfu";
|
||||
keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path;
|
||||
};
|
||||
lk-jwt-service = {
|
||||
enable = true;
|
||||
port = mkDefault 8080;
|
||||
livekitUrl = "wss://${domain}/livekit/sfu";
|
||||
keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path;
|
||||
};
|
||||
|
||||
systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = domain;
|
||||
|
||||
services.nginx.virtualHosts = {
|
||||
"${domain}".locations = {
|
||||
"^~ /livekit/jwt/" = {
|
||||
priority = 400;
|
||||
proxyPass = "http://127.0.0.1:${toString config.services.lk-jwt-service.port}/";
|
||||
};
|
||||
"^~ /livekit/sfu/" = {
|
||||
priority = 400;
|
||||
proxyPass = "http://127.0.0.1:${toString config.services.livekit.settings.port}/";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_send_timeout 120;
|
||||
proxy_read_timeout 120;
|
||||
proxy_buffering off;
|
||||
proxy_set_header Accept-Encoding gzip;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
'';
|
||||
nginx.virtualHosts = {
|
||||
"${domain}".locations = {
|
||||
"^~ /livekit/jwt/" = {
|
||||
priority = 400;
|
||||
proxyPass = "http://127.0.0.1:${toString config.services.lk-jwt-service.port}/";
|
||||
};
|
||||
"^~ /livekit/sfu/" = {
|
||||
priority = 400;
|
||||
proxyPass = "http://127.0.0.1:${toString config.services.livekit.settings.port}/";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_send_timeout 120;
|
||||
proxy_read_timeout 120;
|
||||
proxy_buffering off;
|
||||
proxy_set_header Accept-Encoding gzip;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = domain;
|
||||
|
||||
sops = mkIf cfg.sops {
|
||||
secrets."livekit/key" = { };
|
||||
templates."livekit/key".content = ''
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ in
|
|||
sops = mkIf cfg.sops (
|
||||
let
|
||||
owner = user.name;
|
||||
group = user.group;
|
||||
inherit (user) group;
|
||||
mode = "0400";
|
||||
in
|
||||
{
|
||||
|
|
@ -98,9 +98,7 @@ in
|
|||
''
|
||||
admins:
|
||||
''
|
||||
+ concatLines (
|
||||
map (admin: " ${admin}: ${config.sops.placeholder."maubot/admins/${admin}"}") cfg.admins
|
||||
)
|
||||
+ concatLines (map (admin: " ${admin}: ${config.sops.placeholder."maubot/admins/${admin}"}") cfg.admins)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ in
|
|||
|
||||
users.users."${cfg.user}" = {
|
||||
isSystemUser = true;
|
||||
group = cfg.group;
|
||||
inherit (cfg) group;
|
||||
};
|
||||
|
||||
users.groups."${cfg.group}" = { };
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
let
|
||||
cfg = config.services.miniflux;
|
||||
domain = config.networking.domain;
|
||||
subdomain = cfg.reverseProxy.subdomain;
|
||||
inherit (config.networking) domain;
|
||||
inherit (cfg.reverseProxy) subdomain;
|
||||
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
|
||||
port = 8085;
|
||||
|
||||
|
|
|
|||
|
|
@ -50,8 +50,7 @@ in
|
|||
"1.1.1.1"
|
||||
"2606:4700:4700::1111"
|
||||
];
|
||||
resolvers =
|
||||
if config.networking.nameservers == [ ] then cloudflare else config.networking.nameservers;
|
||||
resolvers = if config.networking.nameservers == [ ] then cloudflare else config.networking.nameservers;
|
||||
in
|
||||
map escapeIPv6 resolvers;
|
||||
|
||||
|
|
@ -60,7 +59,7 @@ in
|
|||
virtualHosts = {
|
||||
"${config.networking.domain}" = mkDefault {
|
||||
enableACME = cfg.forceSSL;
|
||||
forceSSL = cfg.forceSSL;
|
||||
inherit (cfg) forceSSL;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ in
|
|||
types.submodule {
|
||||
options = {
|
||||
extraGroups = mkOption {
|
||||
type = (types.listOf types.str);
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = "Extra groups for the user";
|
||||
example = [ "wheel" ];
|
||||
|
|
@ -37,7 +37,7 @@ in
|
|||
description = "Initial password for the user";
|
||||
};
|
||||
sshKeyFiles = mkOption {
|
||||
type = (types.listOf types.path);
|
||||
type = types.listOf types.path;
|
||||
default = [ ];
|
||||
description = "SSH key files for the user";
|
||||
example = [ "/path/to/id_rsa.pub" ];
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
let
|
||||
cfg = config.services.nostr-relay;
|
||||
domain = config.networking.domain;
|
||||
subdomain = cfg.reverseProxy.subdomain;
|
||||
inherit (config.networking) domain;
|
||||
inherit (cfg.reverseProxy) subdomain;
|
||||
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
|
||||
|
||||
inherit (lib)
|
||||
|
|
@ -48,9 +48,8 @@ in
|
|||
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
|
||||
"${fqdn}" = {
|
||||
enableACME = cfg.reverseProxy.forceSSL;
|
||||
forceSSL = cfg.reverseProxy.forceSSL;
|
||||
locations."/".proxyPass =
|
||||
"http://127.0.0.1:${toString config.services.nostr-rs-relay.settings.network.port}";
|
||||
inherit (cfg.reverseProxy) forceSSL;
|
||||
locations."/".proxyPass = "http://127.0.0.1:${toString config.services.nostr-rs-relay.settings.network.port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,20 +9,26 @@ let
|
|||
inherit (lib) mkDefault;
|
||||
in
|
||||
{
|
||||
boot.blacklistedKernelModules = [ "nouveau" ];
|
||||
boot.extraModulePackages = [ config.hardware.nvidia.package ];
|
||||
boot.initrd.kernelModules = [ "nvidia" ];
|
||||
boot = {
|
||||
blacklistedKernelModules = [ "nouveau" ];
|
||||
extraModulePackages = [ config.hardware.nvidia.package ];
|
||||
initrd.kernelModules = [ "nvidia" ];
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
nvtopPackages.nvidia
|
||||
];
|
||||
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
hardware.graphics.enable = true;
|
||||
hardware.nvidia.modesetting.enable = true;
|
||||
hardware.nvidia.nvidiaSettings = true;
|
||||
hardware.nvidia.open = false;
|
||||
hardware.nvidia.package = mkDefault config.boot.kernelPackages.nvidiaPackages.latest;
|
||||
hardware = {
|
||||
enableRedistributableFirmware = true;
|
||||
graphics.enable = true;
|
||||
nvidia = {
|
||||
modesetting.enable = true;
|
||||
nvidiaSettings = true;
|
||||
open = false;
|
||||
package = mkDefault config.boot.kernelPackages.nvidiaPackages.latest;
|
||||
};
|
||||
};
|
||||
|
||||
nixpkgs.config.cudaSupport = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
let
|
||||
cfg = config.services.ollama;
|
||||
domain = config.networking.domain;
|
||||
subdomain = cfg.reverseProxy.subdomain;
|
||||
inherit (config.networking) domain;
|
||||
inherit (cfg.reverseProxy) subdomain;
|
||||
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
|
||||
|
||||
inherit (lib)
|
||||
|
|
@ -31,7 +31,7 @@ in
|
|||
|
||||
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
|
||||
"${fqdn}" = mkVirtualHost {
|
||||
port = cfg.port;
|
||||
inherit (cfg) port;
|
||||
ssl = cfg.reverseProxy.forceSSL;
|
||||
recommendedProxySettings = mkForce false;
|
||||
extraConfig = ''
|
||||
|
|
|
|||
|
|
@ -83,10 +83,43 @@ in
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
virtualisation.podman = {
|
||||
enable = true;
|
||||
autoPrune.enable = true;
|
||||
dockerCompat = true;
|
||||
virtualisation = {
|
||||
podman = {
|
||||
enable = true;
|
||||
autoPrune.enable = true;
|
||||
dockerCompat = true;
|
||||
};
|
||||
|
||||
oci-containers = {
|
||||
backend = "podman";
|
||||
|
||||
containers."open-webui" = {
|
||||
image = with cfg.image; imageName + ":" + imageTag;
|
||||
imageFile = cfg.image;
|
||||
environment =
|
||||
defaultEnv
|
||||
// cfg.environment
|
||||
// {
|
||||
PORT = "${toString cfg.port}";
|
||||
CORS_ALLOW_ORIGIN = concatStringsSep ";" (
|
||||
[
|
||||
"http://localhost:${toString cfg.port}"
|
||||
"http://127.0.0.1:${toString cfg.port}"
|
||||
"http://0.0.0.0:${toString cfg.port}"
|
||||
]
|
||||
++ optional (cfg.externalUrl != null) cfg.externalUrl
|
||||
);
|
||||
};
|
||||
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
|
||||
volumes = [
|
||||
"open-webui_open-webui:/app/backend/data:rw"
|
||||
];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--network=host"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.interfaces =
|
||||
|
|
@ -97,70 +130,44 @@ in
|
|||
"${matchAll}".allowedUDPPorts = [ 53 ];
|
||||
};
|
||||
|
||||
virtualisation.oci-containers.backend = "podman";
|
||||
|
||||
virtualisation.oci-containers.containers."open-webui" = {
|
||||
image = with cfg.image; imageName + ":" + imageTag;
|
||||
imageFile = cfg.image;
|
||||
environment =
|
||||
defaultEnv
|
||||
// cfg.environment
|
||||
// {
|
||||
PORT = "${toString cfg.port}";
|
||||
CORS_ALLOW_ORIGIN = concatStringsSep ";" (
|
||||
[
|
||||
"http://localhost:${toString cfg.port}"
|
||||
"http://127.0.0.1:${toString cfg.port}"
|
||||
"http://0.0.0.0:${toString cfg.port}"
|
||||
]
|
||||
++ optional (cfg.externalUrl != null) cfg.externalUrl
|
||||
);
|
||||
systemd = {
|
||||
services."podman-open-webui" = {
|
||||
serviceConfig = {
|
||||
Restart = mkOverride 90 "always";
|
||||
};
|
||||
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
|
||||
volumes = [
|
||||
"open-webui_open-webui:/app/backend/data:rw"
|
||||
];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--network=host"
|
||||
];
|
||||
};
|
||||
systemd.services."podman-open-webui" = {
|
||||
serviceConfig = {
|
||||
Restart = mkOverride 90 "always";
|
||||
after = [
|
||||
"podman-volume-open-webui_open-webui.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-volume-open-webui_open-webui.service"
|
||||
];
|
||||
partOf = [
|
||||
"podman-compose-open-webui-root.target"
|
||||
];
|
||||
wantedBy = [
|
||||
"podman-compose-open-webui-root.target"
|
||||
];
|
||||
};
|
||||
after = [
|
||||
"podman-volume-open-webui_open-webui.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-volume-open-webui_open-webui.service"
|
||||
];
|
||||
partOf = [
|
||||
"podman-compose-open-webui-root.target"
|
||||
];
|
||||
wantedBy = [
|
||||
"podman-compose-open-webui-root.target"
|
||||
];
|
||||
};
|
||||
|
||||
systemd.services."podman-volume-open-webui_open-webui" = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
services."podman-volume-open-webui_open-webui" = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = ''
|
||||
podman volume inspect open-webui_open-webui || podman volume create open-webui_open-webui
|
||||
'';
|
||||
partOf = [ "podman-compose-open-webui-root.target" ];
|
||||
wantedBy = [ "podman-compose-open-webui-root.target" ];
|
||||
};
|
||||
script = ''
|
||||
podman volume inspect open-webui_open-webui || podman volume create open-webui_open-webui
|
||||
'';
|
||||
partOf = [ "podman-compose-open-webui-root.target" ];
|
||||
wantedBy = [ "podman-compose-open-webui-root.target" ];
|
||||
};
|
||||
|
||||
systemd.targets."podman-compose-open-webui-root" = {
|
||||
unitConfig = {
|
||||
Description = "Root target generated by compose2nix.";
|
||||
targets."podman-compose-open-webui-root" = {
|
||||
unitConfig = {
|
||||
Description = "Root target generated by compose2nix.";
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
let
|
||||
cfg = config.services.print-server;
|
||||
domain = config.networking.domain;
|
||||
subdomain = cfg.reverseProxy.subdomain;
|
||||
inherit (config.networking) domain;
|
||||
inherit (cfg.reverseProxy) subdomain;
|
||||
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
|
||||
port = 631;
|
||||
|
||||
|
|
@ -36,47 +36,49 @@ in
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.printing = {
|
||||
enable = true;
|
||||
listenAddresses = [ "*:${builtins.toString port}" ];
|
||||
webInterface = true;
|
||||
tempDir = "/tmp/cups";
|
||||
allowFrom = [ "all" ];
|
||||
snmpConf = ''
|
||||
Address @LOCAL
|
||||
'';
|
||||
clientConf = "";
|
||||
openFirewall = cfg.openFirewall;
|
||||
drivers = with pkgs; [
|
||||
brlaser
|
||||
brgenml1lpr
|
||||
brgenml1cupswrapper # Brother
|
||||
postscript-lexmark # Lexmark
|
||||
hplip
|
||||
hplipWithPlugin # HP
|
||||
splix
|
||||
samsung-unified-linux-driver # Samsung
|
||||
gutenprint
|
||||
gutenprintBin # different vendors
|
||||
];
|
||||
defaultShared = true;
|
||||
browsing = true;
|
||||
browsedConf = ''
|
||||
BrowsePoll ${fqdn}
|
||||
'';
|
||||
};
|
||||
services = {
|
||||
printing = {
|
||||
enable = true;
|
||||
listenAddresses = [ "*:${builtins.toString port}" ];
|
||||
webInterface = true;
|
||||
tempDir = "/tmp/cups";
|
||||
allowFrom = [ "all" ];
|
||||
snmpConf = ''
|
||||
Address @LOCAL
|
||||
'';
|
||||
clientConf = "";
|
||||
inherit (cfg) openFirewall;
|
||||
drivers = with pkgs; [
|
||||
brlaser
|
||||
brgenml1lpr
|
||||
brgenml1cupswrapper # Brother
|
||||
postscript-lexmark # Lexmark
|
||||
hplip
|
||||
hplipWithPlugin # HP
|
||||
splix
|
||||
samsung-unified-linux-driver # Samsung
|
||||
gutenprint
|
||||
gutenprintBin # different vendors
|
||||
];
|
||||
defaultShared = true;
|
||||
browsing = true;
|
||||
browsedConf = ''
|
||||
BrowsePoll ${fqdn}
|
||||
'';
|
||||
};
|
||||
|
||||
# autodiscovery of network printers
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
nssmdns4 = true;
|
||||
openFirewall = cfg.openFirewall;
|
||||
};
|
||||
# autodiscovery of network printers
|
||||
avahi = {
|
||||
enable = true;
|
||||
nssmdns4 = true;
|
||||
inherit (cfg) openFirewall;
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
|
||||
${fqdn} = mkVirtualHost {
|
||||
inherit port;
|
||||
ssl = cfg.reverseProxy.forceSSL;
|
||||
nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
|
||||
${fqdn} = mkVirtualHost {
|
||||
inherit port;
|
||||
ssl = cfg.reverseProxy.forceSSL;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
let
|
||||
cfg = config.services.radicale;
|
||||
domain = config.networking.domain;
|
||||
subdomain = cfg.reverseProxy.subdomain;
|
||||
inherit (config.networking) domain;
|
||||
inherit (cfg.reverseProxy) subdomain;
|
||||
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
|
||||
port = 5232;
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ in
|
|||
|
||||
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
|
||||
"${fqdn}" = {
|
||||
forceSSL = cfg.reverseProxy.forceSSL;
|
||||
inherit (cfg.reverseProxy) forceSSL;
|
||||
enableACME = cfg.reverseProxy.forceSSL;
|
||||
locations = {
|
||||
"/" = {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
let
|
||||
cfg = config.services.rss-bridge;
|
||||
domain = config.networking.domain;
|
||||
subdomain = cfg.reverseProxy.subdomain;
|
||||
inherit (config.networking) domain;
|
||||
inherit (cfg.reverseProxy) subdomain;
|
||||
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
|
||||
|
||||
inherit (lib)
|
||||
|
|
@ -33,7 +33,7 @@ in
|
|||
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
|
||||
"${fqdn}" = {
|
||||
enableACME = cfg.reverseProxy.forceSSL;
|
||||
forceSSL = cfg.reverseProxy.forceSSL;
|
||||
inherit (cfg.reverseProxy) forceSSL;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -56,8 +56,7 @@ in
|
|||
config =
|
||||
let
|
||||
defaultTailnets = filterAttrs (_: t: t.default) cfg.tailnets;
|
||||
defaultTailnet =
|
||||
if defaultTailnets == { } then null else builtins.head (builtins.attrValues defaultTailnets);
|
||||
defaultTailnet = if defaultTailnets == { } then null else builtins.head (builtins.attrValues defaultTailnets);
|
||||
|
||||
entries = mapAttrsToList (name: tcfg: ''
|
||||
TAILNETS["${name}"]="${tcfg.loginServer}|${if tcfg.enableSSH then "true" else "false"}|${
|
||||
|
|
@ -111,8 +110,7 @@ in
|
|||
mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
(builtins.length (builtins.attrValues (filterAttrs (_: t: t.default) cfg.tailnets))) <= 1;
|
||||
assertion = (builtins.length (builtins.attrValues (filterAttrs (_: t: t.default) cfg.tailnets))) <= 1;
|
||||
message = "services.tailscale.tailnets: Only one tailnet can be set as default.";
|
||||
}
|
||||
{
|
||||
|
|
|
|||
|
|
@ -58,16 +58,18 @@ in
|
|||
enable = mkDefault true;
|
||||
onBoot = mkDefault "ignore";
|
||||
onShutdown = mkDefault "shutdown";
|
||||
qemu.runAsRoot = mkDefault false;
|
||||
qemu.verbatimConfig = ''
|
||||
clear_emulation_capabilities = ${boolToZeroOne cfg.libvirtd.clearEmulationCapabilities}
|
||||
''
|
||||
+ optionalString (cfg.libvirtd.deviceACL != [ ]) ''
|
||||
cgroup_device_acl = [
|
||||
${aclString}
|
||||
]
|
||||
'';
|
||||
qemu.swtpm.enable = mkDefault true; # TPM 2.0
|
||||
qemu = {
|
||||
runAsRoot = mkDefault false;
|
||||
verbatimConfig = ''
|
||||
clear_emulation_capabilities = ${boolToZeroOne cfg.libvirtd.clearEmulationCapabilities}
|
||||
''
|
||||
+ optionalString (cfg.libvirtd.deviceACL != [ ]) ''
|
||||
cgroup_device_acl = [
|
||||
${aclString}
|
||||
]
|
||||
'';
|
||||
swtpm.enable = mkDefault true; # TPM 2.0
|
||||
};
|
||||
};
|
||||
spiceUSBRedirection.enable = mkDefault true;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
shopt -s nullglob
|
||||
for d in /sys/kernel/iommu_groups/*/devices/*; do
|
||||
n=${d#*/iommu_groups/*}; n=${n%%/*}
|
||||
|
|
|
|||
|
|
@ -78,34 +78,32 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
deviceType = (
|
||||
types.submodule (
|
||||
{ config, options, ... }:
|
||||
{
|
||||
options = {
|
||||
resolution = mkOption {
|
||||
type = types.nullOr resolutionType;
|
||||
default = null;
|
||||
description = "Automatically calculate the minimum device size for a specific resolution. Overrides `size` if set.";
|
||||
};
|
||||
|
||||
size = mkOption {
|
||||
type = types.number;
|
||||
description = "Size for the kvmfr device in megabytes.";
|
||||
};
|
||||
|
||||
permissions = mkOption {
|
||||
type = permissionsType;
|
||||
default = { };
|
||||
description = "Permissions of the kvmfr device.";
|
||||
};
|
||||
deviceType = types.submodule (
|
||||
{ config, options, ... }:
|
||||
{
|
||||
options = {
|
||||
resolution = mkOption {
|
||||
type = types.nullOr resolutionType;
|
||||
default = null;
|
||||
description = "Automatically calculate the minimum device size for a specific resolution. Overrides `size` if set.";
|
||||
};
|
||||
|
||||
config = {
|
||||
size = mkIf (config.resolution != null) (sizeFromResolution config.resolution);
|
||||
size = mkOption {
|
||||
type = types.number;
|
||||
description = "Size for the kvmfr device in megabytes.";
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
permissions = mkOption {
|
||||
type = permissionsType;
|
||||
default = { };
|
||||
description = "Permissions of the kvmfr device.";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
size = mkIf (config.resolution != null) (sizeFromResolution config.resolution);
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
inherit (lib)
|
||||
|
|
@ -144,7 +142,7 @@ in
|
|||
'';
|
||||
|
||||
"modprobe.d/kvmfr.conf".text = ''
|
||||
options kvmfr static_size_mb=${concatStringsSep "," (map (size: toString size) deviceSizes)}
|
||||
options kvmfr static_size_mb=${concatStringsSep "," (map toString deviceSizes)}
|
||||
'';
|
||||
|
||||
"apparmor.d/local/abstractions/libvirt-qemu" = mkIf config.security.apparmor.enable {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
let
|
||||
cfg = config.services.webPage;
|
||||
domain = config.networking.domain;
|
||||
inherit (config.networking) domain;
|
||||
fqdn = if (cfg.subdomain != "") then "${cfg.subdomain}.${domain}" else domain;
|
||||
nginxUser = config.services.nginx.user;
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ in
|
|||
config = mkIf cfg.enable {
|
||||
services.nginx.virtualHosts."${fqdn}" = {
|
||||
enableACME = cfg.forceSSL;
|
||||
forceSSL = cfg.forceSSL;
|
||||
inherit (cfg) forceSSL;
|
||||
root = cfg.webRoot;
|
||||
locations."/".index = "index.html";
|
||||
sslCertificate = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/cert.pem";
|
||||
|
|
|
|||
|
|
@ -81,90 +81,97 @@ in
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.tmpfiles.rules = [ "d ${cfg.volume} 0755 root podman -" ];
|
||||
systemd = {
|
||||
tmpfiles.rules = [ "d ${cfg.volume} 0755 root podman -" ];
|
||||
|
||||
virtualisation.podman = {
|
||||
enable = true;
|
||||
autoPrune.enable = true;
|
||||
dockerCompat = true;
|
||||
defaultNetwork.settings = {
|
||||
dns_enabled = true;
|
||||
services = {
|
||||
"podman-windows" = {
|
||||
serviceConfig = {
|
||||
Restart = mkOverride 90 "always";
|
||||
};
|
||||
after = [
|
||||
"podman-network-windows_default.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-network-windows_default.service"
|
||||
];
|
||||
partOf = [
|
||||
"podman-compose-windows-root.target"
|
||||
];
|
||||
wantedBy = [
|
||||
"podman-compose-windows-root.target"
|
||||
];
|
||||
};
|
||||
|
||||
"podman-network-windows_default" = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStop = "podman network rm -f windows_default";
|
||||
};
|
||||
script = ''
|
||||
podman network inspect windows_default || podman network create windows_default
|
||||
'';
|
||||
partOf = [ "podman-compose-windows-root.target" ];
|
||||
wantedBy = [ "podman-compose-windows-root.target" ];
|
||||
};
|
||||
};
|
||||
|
||||
targets."podman-compose-windows-root" = {
|
||||
unitConfig = {
|
||||
Description = "Root target generated by compose2nix.";
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
};
|
||||
|
||||
virtualisation = {
|
||||
podman = {
|
||||
enable = true;
|
||||
autoPrune.enable = true;
|
||||
dockerCompat = true;
|
||||
defaultNetwork.settings = {
|
||||
dns_enabled = true;
|
||||
};
|
||||
};
|
||||
|
||||
oci-containers = {
|
||||
backend = "podman";
|
||||
containers."windows" = {
|
||||
image = "dockurr/windows";
|
||||
environment = with cfg.settings; {
|
||||
"VERSION" = version;
|
||||
"RAM_SIZE" = ramSize;
|
||||
"CPU_CORES" = cpuCores;
|
||||
"DISK_SIZE" = diskSize;
|
||||
"USERNAME" = username;
|
||||
"PASSWORD" = password;
|
||||
"REGION" = region;
|
||||
"KEYBOARD" = keyboard;
|
||||
};
|
||||
volumes = [
|
||||
"${cfg.volume}:/storage:rw"
|
||||
]
|
||||
++ optional (cfg.sharedVolume != null) "${cfg.sharedVolume}:/shared:rw";
|
||||
ports = [
|
||||
"8006:8006/tcp"
|
||||
"3389:3389/tcp"
|
||||
"3389:3389/udp"
|
||||
];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--cap-add=NET_ADMIN"
|
||||
"--device=/dev/kvm:/dev/kvm:rwm"
|
||||
"--device=/dev/net/tun:/dev/net/tun:rwm"
|
||||
"--network-alias=windows"
|
||||
"--network=windows_default"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/issues/226365
|
||||
networking.firewall.interfaces."podman+".allowedUDPPorts = [ 53 ];
|
||||
|
||||
virtualisation.oci-containers.backend = "podman";
|
||||
|
||||
virtualisation.oci-containers.containers."windows" = {
|
||||
image = "dockurr/windows";
|
||||
environment = with cfg.settings; {
|
||||
"VERSION" = version;
|
||||
"RAM_SIZE" = ramSize;
|
||||
"CPU_CORES" = cpuCores;
|
||||
"DISK_SIZE" = diskSize;
|
||||
"USERNAME" = username;
|
||||
"PASSWORD" = password;
|
||||
"LANGUAGE" = language;
|
||||
"REGION" = region;
|
||||
"KEYBOARD" = keyboard;
|
||||
};
|
||||
volumes = [
|
||||
"${cfg.volume}:/storage:rw"
|
||||
]
|
||||
++ optional (cfg.sharedVolume != null) "${cfg.sharedVolume}:/shared:rw";
|
||||
ports = [
|
||||
"8006:8006/tcp"
|
||||
"3389:3389/tcp"
|
||||
"3389:3389/udp"
|
||||
];
|
||||
log-driver = "journald";
|
||||
extraOptions = [
|
||||
"--cap-add=NET_ADMIN"
|
||||
"--device=/dev/kvm:/dev/kvm:rwm"
|
||||
"--device=/dev/net/tun:/dev/net/tun:rwm"
|
||||
"--network-alias=windows"
|
||||
"--network=windows_default"
|
||||
];
|
||||
};
|
||||
systemd.services."podman-windows" = {
|
||||
serviceConfig = {
|
||||
Restart = mkOverride 90 "always";
|
||||
};
|
||||
after = [
|
||||
"podman-network-windows_default.service"
|
||||
];
|
||||
requires = [
|
||||
"podman-network-windows_default.service"
|
||||
];
|
||||
partOf = [
|
||||
"podman-compose-windows-root.target"
|
||||
];
|
||||
wantedBy = [
|
||||
"podman-compose-windows-root.target"
|
||||
];
|
||||
};
|
||||
|
||||
systemd.services."podman-network-windows_default" = {
|
||||
path = [ pkgs.podman ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStop = "podman network rm -f windows_default";
|
||||
};
|
||||
script = ''
|
||||
podman network inspect windows_default || podman network create windows_default
|
||||
'';
|
||||
partOf = [ "podman-compose-windows-root.target" ];
|
||||
wantedBy = [ "podman-compose-windows-root.target" ];
|
||||
};
|
||||
|
||||
systemd.targets."podman-compose-windows-root" = {
|
||||
unitConfig = {
|
||||
Description = "Root target generated by compose2nix.";
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,74 +14,78 @@ let
|
|||
;
|
||||
in
|
||||
{
|
||||
nix.package = mkDefault pkgs.nix;
|
||||
nix = {
|
||||
package = mkDefault pkgs.nix;
|
||||
|
||||
# for `nix run synix#foo`, `nix build synix#bar`, etc
|
||||
nix.registry = {
|
||||
synix = {
|
||||
from = {
|
||||
id = "synix";
|
||||
type = "indirect";
|
||||
};
|
||||
to = {
|
||||
owner = "sid";
|
||||
repo = "synix";
|
||||
host = "git.sid.ovh";
|
||||
type = "gitea";
|
||||
# for `nix run synix#foo`, `nix build synix#bar`, etc
|
||||
registry = {
|
||||
synix = {
|
||||
from = {
|
||||
id = "synix";
|
||||
type = "indirect";
|
||||
};
|
||||
to = {
|
||||
owner = "sid";
|
||||
repo = "synix";
|
||||
host = "git.sid.ovh";
|
||||
type = "gitea";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nix.settings.warn-dirty = mkDefault false;
|
||||
settings = {
|
||||
warn-dirty = mkDefault false;
|
||||
|
||||
# fallback quickly if substituters are not available.
|
||||
nix.settings.connect-timeout = mkDefault 5;
|
||||
nix.settings.fallback = true;
|
||||
# fallback quickly if substituters are not available.
|
||||
connect-timeout = mkDefault 5;
|
||||
fallback = true;
|
||||
|
||||
nix.settings.experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
]
|
||||
++ optional (
|
||||
config.nix.package != null && versionOlder (versions.majorMinor config.nix.package.version) "2.22"
|
||||
) "repl-flake";
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
]
|
||||
++ optional (
|
||||
config.nix.package != null && versionOlder (versions.majorMinor config.nix.package.version) "2.22"
|
||||
) "repl-flake";
|
||||
|
||||
nix.settings.log-lines = mkDefault 25;
|
||||
log-lines = mkDefault 25;
|
||||
|
||||
# avoid disk full issues
|
||||
nix.settings.max-free = mkDefault (3000 * 1024 * 1024);
|
||||
nix.settings.min-free = mkDefault (512 * 1024 * 1024);
|
||||
# avoid disk full issues
|
||||
max-free = mkDefault (3000 * 1024 * 1024);
|
||||
min-free = mkDefault (512 * 1024 * 1024);
|
||||
|
||||
# avoid copying unnecessary stuff over SSH
|
||||
nix.settings.builders-use-substitutes = true;
|
||||
# avoid copying unnecessary stuff over SSH
|
||||
builders-use-substitutes = true;
|
||||
|
||||
# workaround for https://github.com/NixOS/nix/issues/9574
|
||||
nix.settings.nix-path = config.nix.nixPath;
|
||||
# workaround for https://github.com/NixOS/nix/issues/9574
|
||||
nix-path = config.nix.nixPath;
|
||||
|
||||
nix.settings.download-buffer-size = 524288000; # 500 MiB
|
||||
download-buffer-size = 524288000; # 500 MiB
|
||||
|
||||
# add all wheel users to the trusted-users group
|
||||
nix.settings.trusted-users = [
|
||||
"@wheel"
|
||||
];
|
||||
# add all wheel users to the trusted-users group
|
||||
trusted-users = [
|
||||
"@wheel"
|
||||
];
|
||||
|
||||
# binary caches
|
||||
nix.settings.substituters = [
|
||||
"https://cache.nixos.org"
|
||||
"https://nix-community.cachix.org"
|
||||
"https://cache.garnix.io"
|
||||
"https://numtide.cachix.org"
|
||||
];
|
||||
nix.settings.trusted-public-keys = [
|
||||
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
|
||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||
"cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g="
|
||||
"numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE="
|
||||
];
|
||||
# binary caches
|
||||
substituters = [
|
||||
"https://cache.nixos.org"
|
||||
"https://nix-community.cachix.org"
|
||||
"https://cache.garnix.io"
|
||||
"https://numtide.cachix.org"
|
||||
];
|
||||
trusted-public-keys = [
|
||||
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
|
||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||
"cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g="
|
||||
"numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE="
|
||||
];
|
||||
};
|
||||
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 30d";
|
||||
gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 30d";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue