Compare commits
3 Commits
main
...
60a6cf8e89
| Author | SHA1 | Date | |
|---|---|---|---|
| 60a6cf8e89 | |||
| 509c861529 | |||
| df2c2aa1ae |
56
flake.lock
generated
56
flake.lock
generated
@@ -3,36 +3,64 @@
|
|||||||
"home-manager": {
|
"home-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs-stable"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767910483,
|
"lastModified": 1743788974,
|
||||||
"narHash": "sha256-MOU5YdVu4DVwuT5ztXgQpPuRRBjSjUGIdUzOQr9iQOY=",
|
"narHash": "sha256-2LeVyQZI2wTkSzMLvnN/kJjXVWp4HCVUoq17Bv8TNTk=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "82fb7dedaad83e5e279127a38ef410bcfac6d77c",
|
"rev": "0f5908daf890c3d7e7052bef1d6deb0f2710aaa1",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"ref": "release-25.11",
|
"ref": "master",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767799921,
|
"lastModified": 0,
|
||||||
"narHash": "sha256-r4GVX+FToWVE2My8VVZH4V0pTIpnu2ZE8/Z4uxGEMBE=",
|
"narHash": "sha256-F7n4+KOIfWrwoQjXrL2wD9RhFYLs2/GGe/MQY1sSdlE=",
|
||||||
|
"path": "/nix/store/fwhfa9pbx8vdi8nd5pcys665baz6xdxf-source",
|
||||||
|
"type": "path"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-stable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1744168086,
|
||||||
|
"narHash": "sha256-S9M4HddBCxbbX1CKSyDYgZ8NCVyHcbKnBfoUXeRu2jQ=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "d351d0653aeb7877273920cd3e823994e7579b0b",
|
"rev": "60e405b241edb6f0573f3d9f944617fe33ac4a73",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"ref": "nixos-25.11",
|
"ref": "nixos-24.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-unstable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1744098102,
|
||||||
|
"narHash": "sha256-tzCdyIJj9AjysC3OuKA+tMD/kDEDAF9mICPDU7ix0JA=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "c8cd81426f45942bb2906d5ed2fe21d2f19d95b7",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
@@ -41,21 +69,23 @@
|
|||||||
"inputs": {
|
"inputs": {
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
|
"nixpkgs-stable": "nixpkgs-stable",
|
||||||
|
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||||
"sops-nix": "sops-nix"
|
"sops-nix": "sops-nix"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sops-nix": {
|
"sops-nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs-stable"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767826491,
|
"lastModified": 1743756170,
|
||||||
"narHash": "sha256-WSBENPotD2MIhZwolL6GC9npqgaS5fkM7j07V2i/Ur8=",
|
"narHash": "sha256-2b11EYa08oqDmF3zEBLkG1AoNn9rB1k39ew/T/mSvbU=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "ea3adcb6d2a000d9a69d0e23cad1f2cacb3a9fbe",
|
"rev": "cff8437c5fe8c68fc3a840a21bf1f4dc801da40d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
51
flake.nix
51
flake.nix
@@ -2,43 +2,54 @@
|
|||||||
description = "System Configuration";
|
description = "System Configuration";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-25.11";
|
nixpkgs-unstable = {
|
||||||
home-manager = {
|
url = "github:nixos/nixpkgs?ref=nixos-unstable";
|
||||||
url = "github:nix-community/home-manager?ref=release-25.11";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
};
|
||||||
|
nixpkgs-stable = {
|
||||||
|
url = "github:nixos/nixpkgs?ref=nixos-24.11";
|
||||||
|
};
|
||||||
|
home-manager = {
|
||||||
|
url = "github:nix-community/home-manager/master";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs-stable";
|
||||||
|
};
|
||||||
|
# hyprland = {
|
||||||
|
# url = "github:hyprwm/Hyprland";
|
||||||
|
# inputs.nixpkgs.follows = "nixpkgs-stable";
|
||||||
|
# };
|
||||||
|
# hy3 = {
|
||||||
|
# url = "github:outfoxxed/hy3";
|
||||||
|
# inputs.hyprland.follows = "hyprland";
|
||||||
|
# };
|
||||||
|
# split-monitor-workspaces = {
|
||||||
|
# url = "github:Duckonaut/split-monitor-workspaces";
|
||||||
|
# inputs.hyprland.follows = "hyprland";
|
||||||
|
# };
|
||||||
sops-nix = {
|
sops-nix = {
|
||||||
url = "github:Mic92/sops-nix";
|
url = "github:Mic92/sops-nix";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs-stable";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
{
|
{ self, nixpkgs, ... }@inputs:
|
||||||
self,
|
|
||||||
nixpkgs,
|
|
||||||
...
|
|
||||||
}@inputs:
|
|
||||||
let
|
let
|
||||||
local = import ./lib;
|
local = import ./lib;
|
||||||
|
# TODO: Convert other configurations to use this function.
|
||||||
mkNixosConfig =
|
mkNixosConfig =
|
||||||
{
|
{
|
||||||
path,
|
path,
|
||||||
system ? "x86_64-linux",
|
system ? "x86_64-linux",
|
||||||
nixpkgs ? inputs.nixpkgs,
|
nixpkgs ? inputs.nixpkgs-stable,
|
||||||
home-manager ? inputs.home-manager,
|
|
||||||
}:
|
}:
|
||||||
nixpkgs.lib.nixosSystem {
|
nixpkgs.lib.nixosSystem {
|
||||||
inherit system;
|
inherit system;
|
||||||
modules = [
|
modules = [
|
||||||
home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
{
|
{
|
||||||
home-manager = {
|
home-manager.useGlobalPkgs = true;
|
||||||
useGlobalPkgs = true;
|
home-manager.useUserPackages = true;
|
||||||
useUserPackages = true;
|
home-manager.extraSpecialArgs = {
|
||||||
extraSpecialArgs = {
|
inherit inputs local;
|
||||||
inherit inputs local;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
path
|
path
|
||||||
@@ -61,7 +72,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
features = {
|
features = {
|
||||||
development = import ./home-manager/features/development/development.nix;
|
development = (import ./home-manager/features/development/development.nix);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,7 @@
|
|||||||
discord = {
|
discord = {
|
||||||
name = "Discord";
|
name = "Discord";
|
||||||
# Custom options to reduce flickering under wayland.
|
# Custom options to reduce flickering under wayland.
|
||||||
exec = "env ELECTRON_OZONE_PLATFORM_HINT= discord --enable-features=UseOzonePlatform --ozone-platform=wayland --disable-gpu";
|
exec = "discord --enable-features=UseOzonePlatform --ozone-platform=wayland --disable-gpu";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
wayland.windowManager.hyprland.settings.bind = [
|
|
||||||
# Pass Mouse4 through to discord
|
|
||||||
# ", mouse:275, pass, class:^discord$"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
{
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
freecad-wrapped = pkgs.symlinkJoin {
|
|
||||||
name = "freecad-wrapped";
|
|
||||||
paths = [ pkgs.freecad ];
|
|
||||||
buildInputs = [ pkgs.makeWrapper ];
|
|
||||||
postBuild = ''
|
|
||||||
wrapProgram $out/bin/freecad \
|
|
||||||
--prefix MESA_LOADER_DRIVER_OVERRIDE : zink \
|
|
||||||
--prefix __EGL_VENDOR_LIBRARY_FILENAMES : ${pkgs.mesa}/share/glvnd/egl_vendor.d/50_mesa.json
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
bambu-studio-wrapped = pkgs.symlinkJoin {
|
|
||||||
name = "bambu-studio-wrapped";
|
|
||||||
paths = [ pkgs.bambu-studio ];
|
|
||||||
buildInputs = [ pkgs.makeWrapper ];
|
|
||||||
postBuild = ''
|
|
||||||
wrapProgram $out/bin/bambu-studio \
|
|
||||||
--prefix MESA_LOADER_DRIVER_OVERRIDE : zink \
|
|
||||||
--prefix __EGL_VENDOR_LIBRARY_FILENAMES : ${pkgs.mesa}/share/glvnd/egl_vendor.d/50_mesa.json
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
bambu-studio-wrapped
|
|
||||||
LycheeSlicer
|
|
||||||
orca-slicer
|
|
||||||
|
|
||||||
blender
|
|
||||||
|
|
||||||
freecad-wrapped
|
|
||||||
openscad
|
|
||||||
];
|
|
||||||
|
|
||||||
xdg.desktopEntries.orynt3d =
|
|
||||||
let
|
|
||||||
orynt3d-appimage = pkgs.fetchurl {
|
|
||||||
name = "orynt3d-appimage";
|
|
||||||
url = "https://files.orynt3d.com/client/Orynt3D-0.15.3.AppImage";
|
|
||||||
sha256 = "0j10myj06ff4frsd4yv7z3lb3qgw3ha70hc5hdc9idbryica801y";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
name = "Orynt3D";
|
|
||||||
exec = "env __EGL_VENDOR_LIBRARY_FILENAMES=/run/opengl-driver/share/glvnd/egl_vendor.d/10_nvidia.json ${pkgs.appimage-run}/bin/appimage-run ${orynt3d-appimage}";
|
|
||||||
terminal = false;
|
|
||||||
type = "Application";
|
|
||||||
# icon = "";
|
|
||||||
comment = "3D model viewer and organizer";
|
|
||||||
categories = [
|
|
||||||
"Science"
|
|
||||||
"Development"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Options to get Bambu Studio to run:
|
|
||||||
# __GLX_VENDOR_LIBRARY_NAME=mesa __EGL_VENDOR_LIBRARY_FILENAMES=/nix/store/js9cfbjvlsls14nddk39fw74vyvlhz4l-mesa-25.0.7/share/glvnd/egl_vendor.d/50_mesa.json MESA_LOADER_DRIVER_OVERRIDE=zink GALLIUM_DRIVER=zink WEBKIT_DISABLE_DMABUF_RENDERER=1 bambu-studio
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
stellarium
|
|
||||||
kstars
|
|
||||||
celestia
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,41 +1,7 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
with pkgs;
|
|
||||||
let
|
|
||||||
# A script that runs as long as media is playing.
|
|
||||||
isMediaPlaying = writeShellApplication {
|
|
||||||
name = "isMediaPlaying";
|
|
||||||
runtimeInputs = [
|
|
||||||
playerctl
|
|
||||||
];
|
|
||||||
text = ''
|
|
||||||
set -e
|
|
||||||
|
|
||||||
while [ "$(playerctl status)" = "Playing" ]; do
|
|
||||||
echo -n "."
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
# A script that prevents the system from going to sleep while media is playing
|
|
||||||
mediaCaffeine = writeShellApplication {
|
|
||||||
name = "media-caffeine";
|
|
||||||
runtimeInputs = [
|
|
||||||
isMediaPlaying
|
|
||||||
systemd
|
|
||||||
];
|
|
||||||
text = ''
|
|
||||||
set -e
|
|
||||||
|
|
||||||
systemd-inhibit --what=sleep --why="Media is playing" --mode=block isMediaPlaying
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
pulseaudio # for pactl and other tools
|
pulseaudio # for pactl and other tools
|
||||||
pavucontrol # GUI volume control with lots of options
|
pavucontrol # GUI volume control with lots of options
|
||||||
|
|
||||||
mediaCaffeine
|
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
../apps/element.nix
|
|
||||||
../apps/discord.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
signal-desktop
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,64 +1,7 @@
|
|||||||
include "%L"
|
include "%L"
|
||||||
|
|
||||||
<Multi_key> <m> <u> : "μ"
|
<Multi_key> <m> <u> : "μ"
|
||||||
<Multi_key> <p> <i> : "π"
|
|
||||||
<Multi_key> <minus> <comma> : "¬"
|
<Multi_key> <minus> <comma> : "¬"
|
||||||
<Multi_key> <asciicircum> <asciicircum> : "∧"
|
<Multi_key> <asciicircum> <asciicircum> : "∧"
|
||||||
<Multi_key> <v> <v> : "∨"
|
<Multi_key> <v> <v> : "∨"
|
||||||
|
|
||||||
# GREEK CAPITAL LETTERS
|
|
||||||
<Multi_key> <G> <A> : "Α" U0391 # GREEK CAPITAL LETTER ALPHA
|
|
||||||
<Multi_key> <G> <B> : "Β" U0392 # GREEK CAPITAL LETTER BETA
|
|
||||||
<Multi_key> <G> <G> : "Γ" U0393 # GREEK CAPITAL LETTER GAMMA
|
|
||||||
<Multi_key> <G> <D> : "Δ" U0394 # GREEK CAPITAL LETTER DELTA
|
|
||||||
<Multi_key> <G> <E> : "Ε" U0395 # GREEK CAPITAL LETTER EPSILON
|
|
||||||
<Multi_key> <G> <Z> : "Ζ" U0396 # GREEK CAPITAL LETTER ZETA
|
|
||||||
<Multi_key> <G> <H> : "Η" U0397 # GREEK CAPITAL LETTER ETA
|
|
||||||
<Multi_key> <G> <I> : "Ι" U0399 # GREEK CAPITAL LETTER IOTA
|
|
||||||
<Multi_key> <G> <K> : "Κ" U039A # GREEK CAPITAL LETTER KAPPA
|
|
||||||
<Multi_key> <G> <L> : "Λ" U039B # GREEK CAPITAL LETTER LAMDA
|
|
||||||
<Multi_key> <G> <M> : "Μ" U039C # GREEK CAPITAL LETTER MU
|
|
||||||
<Multi_key> <G> <N> : "Ν" U039D # GREEK CAPITAL LETTER NU
|
|
||||||
<Multi_key> <G> <P> : "Π" U03A0 # GREEK CAPITAL LETTER PI
|
|
||||||
<Multi_key> <G> <R> : "Ρ" U03A1 # GREEK CAPITAL LETTER RHO
|
|
||||||
<Multi_key> <G> <S> : "Σ" U03A3 # GREEK CAPITAL LETTER SIGMA
|
|
||||||
<Multi_key> <G> <T> : "Τ" U03A4 # GREEK CAPITAL LETTER TAU
|
|
||||||
<Multi_key> <G> <U> : "Υ" U03A5 # GREEK CAPITAL LETTER UPSILON
|
|
||||||
<Multi_key> <G> <F> : "Φ" U03A6 # GREEK CAPITAL LETTER PHI
|
|
||||||
<Multi_key> <G> <X> : "Χ" U03A7 # GREEK CAPITAL LETTER CHI
|
|
||||||
<Multi_key> <G> <O> : "Ω" U03A9 # GREEK CAPITAL LETTER OMEGA
|
|
||||||
|
|
||||||
# DOUBLES (additional stroke <Q>)
|
|
||||||
<Multi_key> <G> <Q> <T> : "Θ" U0398 # GREEK CAPITAL LETTER THETA
|
|
||||||
<Multi_key> <G> <Q> <O> : "Ο" U039F # GREEK CAPITAL LETTER OMICRON
|
|
||||||
<Multi_key> <G> <Q> <X> : "Ξ" U039E # GREEK CAPITAL LETTER XI
|
|
||||||
<Multi_key> <G> <Q> <P> : "Ψ" U03A8 # GREEK CAPITAL LETTER PSI
|
|
||||||
|
|
||||||
# greek small letters
|
|
||||||
<Multi_key> <g> <a> : "α" U03B1 # GREEK SMALL LETTER ALPHA
|
|
||||||
<Multi_key> <g> <b> : "β" U03B2 # GREEK SMALL LETTER BETA
|
|
||||||
<Multi_key> <g> <g> : "γ" U03B3 # GREEK SMALL LETTER GAMMA
|
|
||||||
<Multi_key> <g> <d> : "δ" U03B4 # GREEK SMALL LETTER DELTA
|
|
||||||
<Multi_key> <g> <e> : "ε" U03B5 # GREEK SMALL LETTER EPSILON
|
|
||||||
<Multi_key> <g> <z> : "ζ" U03B6 # GREEK SMALL LETTER ZETA
|
|
||||||
<Multi_key> <g> <h> : "η" U03B7 # GREEK SMALL LETTER ETA
|
|
||||||
<Multi_key> <g> <i> : "ι" U03B9 # GREEK SMALL LETTER IOTA
|
|
||||||
<Multi_key> <g> <k> : "κ" U03BA # GREEK SMALL LETTER KAPPA
|
|
||||||
<Multi_key> <g> <l> : "λ" U03BB # GREEK SMALL LETTER LAMDA
|
|
||||||
<Multi_key> <g> <m> : "μ" U03BC # GREEK SMALL LETTER MU
|
|
||||||
<Multi_key> <g> <n> : "ν" U03BD # GREEK SMALL LETTER NU
|
|
||||||
<Multi_key> <g> <p> : "π" U03C0 # GREEK SMALL LETTER PI
|
|
||||||
<Multi_key> <g> <r> : "ρ" U03C1 # GREEK SMALL LETTER RHO
|
|
||||||
<Multi_key> <g> <s> : "σ" U03C3 # GREEK SMALL LETTER SIGMA
|
|
||||||
<Multi_key> <g> <t> : "τ" U03C4 # GREEK SMALL LETTER TAU
|
|
||||||
<Multi_key> <g> <u> : "υ" U03C5 # GREEK SMALL LETTER UPSILON
|
|
||||||
<Multi_key> <g> <f> : "φ" U03C6 # GREEK SMALL LETTER PHI
|
|
||||||
<Multi_key> <g> <x> : "χ" U03C7 # GREEK SMALL LETTER CHI
|
|
||||||
<Multi_key> <g> <o> : "ω" U03C9 # GREEK SMALL LETTER OMEGA
|
|
||||||
|
|
||||||
# doubles (additional stroke <q>)
|
|
||||||
<Multi_key> <g> <q> <t> : "θ" U03B8 # GREEK SMALL LETTER THETA
|
|
||||||
<Multi_key> <g> <q> <o> : "ο" U03BF # GREEK SMALL LETTER OMICRON
|
|
||||||
<Multi_key> <g> <q> <p> : "ψ" U03C8 # GREEK SMALL LETTER PSI
|
|
||||||
<Multi_key> <g> <q> <s> : "ς" U03C2 # GREEK SMALL LETTER FINAL SIGMA
|
|
||||||
<Multi_key> <g> <q> <x> : "ξ" U03BE # GREEK SMALL LETTER X
|
|
||||||
|
|||||||
@@ -10,17 +10,10 @@
|
|||||||
# Base languages that should always be available
|
# Base languages that should always be available
|
||||||
./nix.nix
|
./nix.nix
|
||||||
./lua.nix
|
./lua.nix
|
||||||
./sh.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
hyperfine # Benchmarking tool
|
# Dev helpers
|
||||||
|
direnv
|
||||||
];
|
];
|
||||||
|
|
||||||
programs.direnv = {
|
|
||||||
enable = true;
|
|
||||||
enableBashIntegration = true;
|
|
||||||
enableZshIntegration = true;
|
|
||||||
nix-direnv.enable = true;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
docker-compose
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
markdownlint-cli2 # linter
|
|
||||||
marksman # language server
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
nixfmt-rfc-style # Formatter
|
nixfmt-rfc-style # Formatter
|
||||||
nil # Language Server
|
nil # Language Server
|
||||||
statix # Lints and suggestions for Nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
home.shellAliases = {
|
home.shellAliases = {
|
||||||
@@ -15,3 +14,4 @@
|
|||||||
rebuild-boot = "sudo nixos-rebuild boot --flake ~/system-config --show-trace --print-build-logs --verbose";
|
rebuild-boot = "sudo nixos-rebuild boot --flake ~/system-config --show-trace --print-build-logs --verbose";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
shfmt # Formatter
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
vtsls # Language Server
|
|
||||||
eslint # Linter
|
|
||||||
nodePackages.prettier # Formatter
|
|
||||||
tailwindcss-language-server # Language server for tailwind CSS
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
programs.vscode = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
extensions = with pkgs.vscode-extensions; [
|
|
||||||
asvetliakov.vscode-neovim # Use embedded neovim editor
|
|
||||||
enkia.tokyo-night # Color theme
|
|
||||||
eamodio.gitlens # Show git info inline
|
|
||||||
mechatroner.rainbow-csv # Make it easier to read CSV files
|
|
||||||
aaron-bond.better-comments # Provides some highlighting in comments
|
|
||||||
|
|
||||||
# Typescript
|
|
||||||
esbenp.prettier-vscode # Auto-formatting
|
|
||||||
|
|
||||||
# AI Agents
|
|
||||||
github.copilot
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -33,16 +33,6 @@ $color-standout-dark: darker($color-standout);
|
|||||||
font-family: 'Noto Sans Nerd Font', sans-serif;
|
font-family: 'Noto Sans Nerd Font', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.vertical-statusbar {
|
|
||||||
background-color: $color-background;
|
|
||||||
// background-image: linear-gradient(160deg, rgba(255,00,00,0.5), $color-background);
|
|
||||||
color: $color-foreground;
|
|
||||||
padding: 16px;
|
|
||||||
font-size: 14px;
|
|
||||||
border-right: 3px solid $color-border;
|
|
||||||
font-family: 'Noto Sans Nerd Font', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.system-monitor {
|
.system-monitor {
|
||||||
padding-top: 8px;
|
padding-top: 8px;
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
|
|||||||
@@ -3,4 +3,5 @@
|
|||||||
(include "./primary-statusbar.yuck")
|
(include "./primary-statusbar.yuck")
|
||||||
(include "./secondary-statusbar.yuck")
|
(include "./secondary-statusbar.yuck")
|
||||||
(include "./system-monitor.yuck")
|
(include "./system-monitor.yuck")
|
||||||
|
(include "./launcher.yuck")
|
||||||
(include "./vertical-statusbar.yuck")
|
(include "./vertical-statusbar.yuck")
|
||||||
|
|||||||
74
home-manager/features/eww/config/launcher.yuck
Normal file
74
home-manager/features/eww/config/launcher.yuck
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
(defwindow launcher
|
||||||
|
:monitor '[ "<primary>", "DP-2", 0 ]'
|
||||||
|
:geometry (geometry
|
||||||
|
:x "100px"
|
||||||
|
:y "100px"
|
||||||
|
:anchor "top left"
|
||||||
|
)
|
||||||
|
:stacking "bottom"
|
||||||
|
:exclusive false
|
||||||
|
:focusable false
|
||||||
|
(box
|
||||||
|
:class "launcher-window stand-alone"
|
||||||
|
:orientation "v"
|
||||||
|
:spacing 4
|
||||||
|
:visible { arraylength(jq(workspaces-json-dp2, "map(select(.active and (.has_windows | not)))")) > 0 }
|
||||||
|
(box
|
||||||
|
:orientation "v"
|
||||||
|
:halign "start"
|
||||||
|
:spacing 4
|
||||||
|
:space-evenly false
|
||||||
|
(label
|
||||||
|
:text "Apps"
|
||||||
|
:halign "start"
|
||||||
|
)
|
||||||
|
(box
|
||||||
|
:orientation "h"
|
||||||
|
:halign "start"
|
||||||
|
:spacing 4
|
||||||
|
:space-evenly false
|
||||||
|
(button
|
||||||
|
:onclick "firefox"
|
||||||
|
(image
|
||||||
|
:class "launcher-icon"
|
||||||
|
:icon "firefox"
|
||||||
|
:icon-size "dialog"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(box
|
||||||
|
:orientation "v"
|
||||||
|
:halign "start"
|
||||||
|
:spacing 4
|
||||||
|
:space-evenly false
|
||||||
|
(label
|
||||||
|
:text "Games"
|
||||||
|
:halign "start"
|
||||||
|
)
|
||||||
|
(box
|
||||||
|
:orientation "h"
|
||||||
|
:halign "start"
|
||||||
|
:spacing 4
|
||||||
|
:space-evenly false
|
||||||
|
(button
|
||||||
|
;; :onclick "env LUTRIS_SKIP_INIT=1 lutris lutris:rungameid/1"
|
||||||
|
:onclick "/home/drew/.local/bin/wow.sh >/tmp/wow.log 2>&1"
|
||||||
|
(image
|
||||||
|
:class "launcher-icon"
|
||||||
|
:image-width 48
|
||||||
|
:path "/home/drew/.local/share/icons/hicolor/128x128/apps/lutris_battlenet.png"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
;; (button
|
||||||
|
;; :onclick "steam steam://rungameid/1145350"
|
||||||
|
;; (image
|
||||||
|
;; :class "launcher-icon"
|
||||||
|
;; :icon "steam_icon_1145350"
|
||||||
|
;; :icon-size "dialog"
|
||||||
|
;; )
|
||||||
|
;;)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
:spacing 8
|
:spacing 8
|
||||||
(system-monitor-perf)
|
(system-monitor-perf)
|
||||||
(system-monitor-disks)
|
(system-monitor-disks)
|
||||||
(system-monitor-net :interface "wlo1")
|
(system-monitor-net)
|
||||||
)
|
)
|
||||||
(box
|
(box
|
||||||
:orientation "h"
|
:orientation "h"
|
||||||
@@ -145,13 +145,13 @@
|
|||||||
:name "Disks"
|
:name "Disks"
|
||||||
(system-monitor-gauge
|
(system-monitor-gauge
|
||||||
:name "Root"
|
:name "Root"
|
||||||
:text-value {EWW_DISK['/'].free / 1000000000}
|
:text-value {EWW_DISK['/'].free / powi(2, 30)}
|
||||||
:gauge-pct {EWW_DISK['/'].used_perc}
|
:gauge-pct {EWW_DISK['/'].used_perc}
|
||||||
:units " GB"
|
:units " GB"
|
||||||
)
|
)
|
||||||
(system-monitor-gauge
|
(system-monitor-gauge
|
||||||
:name "Home"
|
:name "Home"
|
||||||
:text-value {EWW_DISK['/home'].free / 1000000000}
|
:text-value {EWW_DISK['/home'].free / powi(2, 30)}
|
||||||
:gauge-pct {EWW_DISK['/home'].used_perc}
|
:gauge-pct {EWW_DISK['/home'].used_perc}
|
||||||
:units " GB"
|
:units " GB"
|
||||||
)
|
)
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
`iwgetid -r`
|
`iwgetid -r`
|
||||||
)
|
)
|
||||||
|
|
||||||
(defwidget system-monitor-net [ interface ]
|
(defwidget system-monitor-net []
|
||||||
(system-monitor-group
|
(system-monitor-group
|
||||||
:name "Network"
|
:name "Network"
|
||||||
:orientation "v"
|
:orientation "v"
|
||||||
@@ -174,12 +174,12 @@
|
|||||||
)
|
)
|
||||||
(system-monitor-sparkgraph
|
(system-monitor-sparkgraph
|
||||||
:name "Down"
|
:name "Down"
|
||||||
:value {EWW_NET[interface]["NET_DOWN"] / 1000000}
|
:value {EWW_NET["wlo1"]["NET_DOWN"] / 1000000}
|
||||||
:units " MB/s"
|
:units " MB/s"
|
||||||
)
|
)
|
||||||
(system-monitor-sparkgraph
|
(system-monitor-sparkgraph
|
||||||
:name "Up"
|
:name "Up"
|
||||||
:value {EWW_NET[interface]["NET_UP"] / 1000000}
|
:value {EWW_NET["wlo1"]["NET_UP"] / 1000000}
|
||||||
:units " MB/s"
|
:units " MB/s"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -17,22 +17,11 @@
|
|||||||
(workspaces :workspaces-json workspaces-json-hdmi-a-1)
|
(workspaces :workspaces-json workspaces-json-hdmi-a-1)
|
||||||
)
|
)
|
||||||
|
|
||||||
(defwidget disks-vega []
|
|
||||||
(system-monitor-group
|
|
||||||
:name "Disks"
|
|
||||||
(system-monitor-gauge
|
|
||||||
:name "Root"
|
|
||||||
:text-value {EWW_DISK['/'].free / 1000000000}
|
|
||||||
:gauge-pct {EWW_DISK['/'].used_perc}
|
|
||||||
:units " GB"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
(defwidget vertical-statusbar []
|
(defwidget vertical-statusbar []
|
||||||
(box
|
(box
|
||||||
|
:class "statusbar"
|
||||||
:orientation "v"
|
:orientation "v"
|
||||||
:halign "fill"
|
:halign "center"
|
||||||
:spacing 8
|
:spacing 8
|
||||||
:space-evenly false
|
:space-evenly false
|
||||||
(clock-large)
|
(clock-large)
|
||||||
@@ -44,8 +33,8 @@
|
|||||||
(system-monitor-perf-cpu)
|
(system-monitor-perf-cpu)
|
||||||
(system-monitor-perf-gpu)
|
(system-monitor-perf-gpu)
|
||||||
)
|
)
|
||||||
(disks-vega)
|
(system-monitor-disks)
|
||||||
(system-monitor-net :interface "wlp5s0")
|
(system-monitor-net)
|
||||||
(system-monitor-audio)
|
(system-monitor-audio)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
{ pkgs, ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
home.packages = with pkgs; [
|
|
||||||
# For Noto Sans NF
|
|
||||||
# 25.05
|
|
||||||
nerd-fonts.noto
|
|
||||||
# 24.11
|
|
||||||
# (nerdfonts.override { fonts = [ "NotoSans" ]; })
|
|
||||||
];
|
|
||||||
|
|
||||||
programs.eww = {
|
programs.eww = {
|
||||||
enable = true;
|
enable = true;
|
||||||
configDir = ./config;
|
configDir = ./config;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ let
|
|||||||
# '';
|
# '';
|
||||||
warcraftLogsUploader = pkgs.fetchurl {
|
warcraftLogsUploader = pkgs.fetchurl {
|
||||||
name = "warcraftlogs-client";
|
name = "warcraftlogs-client";
|
||||||
url = "https://github.com/RPGLogs/Uploaders-warcraftlogs/releases/download/v8.17.47/warcraftlogs-v8.17.47.AppImage";
|
url = "https://github.com/RPGLogs/Uploaders-warcraftlogs/releases/download/v8.16.56/warcraftlogs-v8.16.56.AppImage";
|
||||||
sha256 = "1aypr3ffy6lq0qj64d48c7n54nfs72404xb2kpxsw5slqh66imw6";
|
sha256 = "1aypr3ffy6lq0qj64d48c7n54nfs72404xb2kpxsw5slqh66imw6";
|
||||||
};
|
};
|
||||||
warcraftLogsIcon = pkgs.fetchurl {
|
warcraftLogsIcon = pkgs.fetchurl {
|
||||||
@@ -27,7 +27,7 @@ let
|
|||||||
raiderioClient = pkgs.fetchurl {
|
raiderioClient = pkgs.fetchurl {
|
||||||
name = "raiderio-client";
|
name = "raiderio-client";
|
||||||
url = "https://raider.io/client/download/linux";
|
url = "https://raider.io/client/download/linux";
|
||||||
sha256 = "0wcw53bgr9dr02x1ci2jlnc5irpiqxqxgs2hpbrsnj67q50nvlm9";
|
sha256 = "0k665s5frs7pga38yjz38gszkn5gkxkfzqlq07x0bm4qjvbrjf7z";
|
||||||
};
|
};
|
||||||
raiderioIcon = pkgs.fetchurl {
|
raiderioIcon = pkgs.fetchurl {
|
||||||
name = "raiderio-icon";
|
name = "raiderio-icon";
|
||||||
@@ -46,15 +46,10 @@ in
|
|||||||
];
|
];
|
||||||
})
|
})
|
||||||
protonup-ng
|
protonup-ng
|
||||||
protonplus
|
|
||||||
protontricks
|
|
||||||
vulkan-tools # useful for debugging Vulkan issues
|
vulkan-tools # useful for debugging Vulkan issues
|
||||||
|
|
||||||
# WoW addon updater
|
# WoW addon updater
|
||||||
wowup-cf
|
wowup-cf
|
||||||
|
|
||||||
# Nexus Mod Manager
|
|
||||||
nexusmods-app-unfree
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# xdg.dataFile."applications/wowup-cf.desktop" = {
|
# xdg.dataFile."applications/wowup-cf.desktop" = {
|
||||||
@@ -85,7 +80,7 @@ in
|
|||||||
categories = [ "Game" ];
|
categories = [ "Game" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
xdg.desktopEntries.raiderio = {
|
xdg.desktopEntries.raiderio = local.electronDesktopEntry {
|
||||||
name = "Raider.io";
|
name = "Raider.io";
|
||||||
exec = "${pkgs.appimage-run}/bin/appimage-run ${raiderioClient}";
|
exec = "${pkgs.appimage-run}/bin/appimage-run ${raiderioClient}";
|
||||||
terminal = false;
|
terminal = false;
|
||||||
@@ -94,26 +89,4 @@ in
|
|||||||
comment = "Raider.io Client";
|
comment = "Raider.io Client";
|
||||||
categories = [ "Game" ];
|
categories = [ "Game" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
wayland.windowManager.hyprland.settings.windowrulev2 = [
|
|
||||||
# Set up full-screen games on monitor 1 (since window 0 is the vertical one.)
|
|
||||||
"monitor 1,class:^steam_app_\d+$"
|
|
||||||
"float,class:^steam_app_\d+$"
|
|
||||||
"monitor 1,fullscreen:1"
|
|
||||||
"center,class:^steam_app_\d+$"
|
|
||||||
|
|
||||||
# Make sure WoW spawns on the right monitor and that Battlenet floats so it renders correctly
|
|
||||||
"monitor 1,title:^World of Warcraft$"
|
|
||||||
"fullscreen,title:^World of Warcraft$"
|
|
||||||
"monitor 1,title:^Battle.net$"
|
|
||||||
"float,title:^Battle.net$"
|
|
||||||
|
|
||||||
# Make Balatro into a regular window.
|
|
||||||
"monitor 1,title:^Balatro$"
|
|
||||||
"tile,title:^Balatro$"
|
|
||||||
|
|
||||||
# Load Cyberpunk 2077 on the right monitor.
|
|
||||||
"monitor 1,class:steam_app_1091500"
|
|
||||||
"fullscreen,class:steam_app_1091500"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
"l" = "log --oneline";
|
"l" = "log --oneline";
|
||||||
};
|
};
|
||||||
extraConfig = {
|
extraConfig = {
|
||||||
|
core = {
|
||||||
|
pager = "";
|
||||||
|
};
|
||||||
pull = {
|
pull = {
|
||||||
rebase = true;
|
rebase = true;
|
||||||
};
|
};
|
||||||
@@ -22,7 +25,5 @@
|
|||||||
defaultBranch = "main";
|
defaultBranch = "main";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
# Enable the delta diff pager.
|
|
||||||
delta.enable = true;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
services.hypridle = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
general = {
|
|
||||||
lock_cmd = "pidof swaylock || ~/.config/swaylock/swaylock.sh"; # avoid starting multiple lock instances.
|
|
||||||
before_sleep_cmd = "loginctl lock-session"; # lock before suspend.
|
|
||||||
after_sleep_cmd = "hyprctl dispatch dpms on"; # to avoid having to press a key twice to turn on the display.
|
|
||||||
};
|
|
||||||
|
|
||||||
listener = [
|
|
||||||
{
|
|
||||||
timeout = 300; # 5min
|
|
||||||
on-timeout = "brightnessctl -s set 10"; # set monitor backlight to minimum, avoid 0 on OLED monitor.
|
|
||||||
on-resume = "brightnessctl -r"; # monitor backlight restore.
|
|
||||||
}
|
|
||||||
{
|
|
||||||
timeout = 330; # 5.5 min
|
|
||||||
on-timeout = "loginctl lock-session"; # lock screen when timeout has passed
|
|
||||||
}
|
|
||||||
{
|
|
||||||
timeout = 600; # 10 min
|
|
||||||
on-timeout = "hyprctl dispatch dpms off"; # screen off when timeout has passed
|
|
||||||
on-resume = "hyprctl dispatch dpms on && brightnessctl -r"; # screen on when activity is detected after timeout has fired.
|
|
||||||
}
|
|
||||||
{
|
|
||||||
timeout = 1800; # 30min
|
|
||||||
on-timeout = "systemctl suspend"; # suspend pc
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,19 +1,11 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
|
||||||
./swaylock.nix
|
|
||||||
./hypr/hypridle.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
|
swayidle # lock on idle
|
||||||
swayosd # volume pop-up
|
swayosd # volume pop-up
|
||||||
swaynotificationcenter # notifications
|
swaynotificationcenter # notifications
|
||||||
hyprpolkitagent # Privilege managent
|
hyprpolkitagent # Privilege managent
|
||||||
hyprshot # Screenshot utility
|
hyprshot # Screenshot utility
|
||||||
|
|
||||||
# For clipboard management. See below.
|
|
||||||
wl-clipboard
|
|
||||||
xclip
|
|
||||||
];
|
];
|
||||||
|
|
||||||
wayland.windowManager.hyprland = {
|
wayland.windowManager.hyprland = {
|
||||||
@@ -36,20 +28,34 @@
|
|||||||
|
|
||||||
"$terminal" = "foot";
|
"$terminal" = "foot";
|
||||||
"$menu" = "rofi -show combi -combi-modes drun,ssh,run -theme ~/.config/rofi/launcher/style.rasi";
|
"$menu" = "rofi -show combi -combi-modes drun,ssh,run -theme ~/.config/rofi/launcher/style.rasi";
|
||||||
"$browser" = "firefox --new-window";
|
"$browser" = "firefox";
|
||||||
|
|
||||||
exec-once = [
|
exec-once = [
|
||||||
"nm-applet"
|
"nm-applet"
|
||||||
"sleep 2 && hyprpm reload -n"
|
"sleep 2 && hyprpm reload -n"
|
||||||
|
"swayidle -w before-sleep hyprlock"
|
||||||
|
"swayosd-server"
|
||||||
"systemctl --user start hyprpolkitagent"
|
"systemctl --user start hyprpolkitagent"
|
||||||
|
|
||||||
"gsettings set org.gnome.desktop.interface color-scheme \"prefer-dark\""
|
"gsettings set org.gnome.desktop.interface color-scheme \"prefer-dark\""
|
||||||
"gsettings set org.gnome.desktop.interface gtk-theme \"Adwaita-dark\""
|
"gsettings set org.gnome.desktop.interface gtk-theme \"Adwaita-dark\""
|
||||||
# Hyprland doesn't paste into Firefox or Wine apps. This program is a workaround.
|
];
|
||||||
# See https://github.com/hyprwm/Hyprland/issues/2319
|
|
||||||
# -t text = Only handle text
|
env = [
|
||||||
# -w xclip -selection clipboard = Watch for events and invoke xclip
|
"XCURSOR_SIZE,32"
|
||||||
"wl-paste -t text -w xclip -selection clipboard"
|
"HYPRCURSOR_SIZE,32"
|
||||||
|
"HYPRCURSOR_THEME,phinger"
|
||||||
|
|
||||||
|
# Nvidia config
|
||||||
|
"LIBVA_DRIVER_NAME,nvidia"
|
||||||
|
"__GLX_VENDOR_LIBRARY_NAME,nvidia"
|
||||||
|
|
||||||
|
# For window theming
|
||||||
|
"QT_QPA_PLATFORMTHEME,qt6ct # for Qt apps"
|
||||||
|
"GTK_THEME,Adwaita-dark"
|
||||||
|
|
||||||
|
# Tell electron apps they should use OZone for Wayland
|
||||||
|
"ELECTRON_OZONE_PLATFORM_HINT,auto"
|
||||||
];
|
];
|
||||||
|
|
||||||
general = {
|
general = {
|
||||||
@@ -287,7 +293,6 @@
|
|||||||
"$mainMod, B, exec, $browser"
|
"$mainMod, B, exec, $browser"
|
||||||
"$mainMod, D, exec, $menu"
|
"$mainMod, D, exec, $menu"
|
||||||
"$mainMod + SHIFT, S, exec, hyprshot -m region --clipboard-only"
|
"$mainMod + SHIFT, S, exec, hyprshot -m region --clipboard-only"
|
||||||
"$mainMod + CTRL + SHIFT, S, exec, hyprshot -m region -o ~/Pictures"
|
|
||||||
"$mainMod, C, exec, swaync-client -t"
|
"$mainMod, C, exec, swaync-client -t"
|
||||||
|
|
||||||
"$mainMod + L_CONTROL, Q, exec, /home/drew/.config/rofi/powermenu/powermenu.sh"
|
"$mainMod + L_CONTROL, Q, exec, /home/drew/.config/rofi/powermenu/powermenu.sh"
|
||||||
@@ -399,6 +404,16 @@
|
|||||||
"opaque,class:(),title:()"
|
"opaque,class:(),title:()"
|
||||||
"noshadow,class:(),title:()"
|
"noshadow,class:(),title:()"
|
||||||
"noblur,class:(),title:()"
|
"noblur,class:(),title:()"
|
||||||
|
|
||||||
|
# Set up full-screen games on monitor 1
|
||||||
|
"monitor 1,class:^steam_app_\d+$"
|
||||||
|
"float,class:^steam_app_\d+$"
|
||||||
|
"monitor 1,fullscreen:1"
|
||||||
|
"center,class:^steam_app_\d+$"
|
||||||
|
|
||||||
|
"monitor 1,title:^World of Warcraft$"
|
||||||
|
"monitor 1,title:^Battle.net$"
|
||||||
|
"float,title:^Battle.net$"
|
||||||
];
|
];
|
||||||
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Workspace-Rules/ for workspace rules
|
# See https://wiki.hyprland.org/Configuring/Workspace-Rules/ for workspace rules
|
||||||
@@ -428,7 +443,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
programs.hyprlock = {
|
programs.hyprlock = {
|
||||||
enable = false;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
general = {
|
general = {
|
||||||
disable_loading_bar = true;
|
disable_loading_bar = true;
|
||||||
@@ -476,24 +491,4 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# UWSM sessions should not use Hyprland's variables but instead use UWSM's variable management.
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Environment-variables/
|
|
||||||
home.file.".config/uwsm/env".text = ''
|
|
||||||
export XCURSOR_SIZE="32"
|
|
||||||
export HYPRCURSOR_SIZE="32"
|
|
||||||
export HYPRCURSOR_THEME="phinger"
|
|
||||||
|
|
||||||
# Nvidia config
|
|
||||||
export LIBVA_DRIVER_NAME="nvidia"
|
|
||||||
export __GLX_VENDOR_LIBRARY_NAME="nvidia"
|
|
||||||
|
|
||||||
# For window theming
|
|
||||||
export QT_QPA_PLATFORMTHEME="qt6ct # for Qt apps"
|
|
||||||
export GTK_THEME="Adwaita-dark"
|
|
||||||
|
|
||||||
# Tell electron apps they should use OZone for Wayland
|
|
||||||
export ELECTRON_OZONE_PLATFORM_HINT="auto"
|
|
||||||
'';
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
gimp3
|
|
||||||
inkscape
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
imports = [
|
imports = [
|
||||||
./audio.nix
|
./audio.nix
|
||||||
./hyprland.nix
|
./hyprland.nix
|
||||||
|
./nix.nix
|
||||||
./rofi/rofi.nix
|
./rofi/rofi.nix
|
||||||
./sway.nix
|
./sway.nix
|
||||||
../apps/element.nix
|
../apps/element.nix
|
||||||
@@ -10,48 +11,40 @@
|
|||||||
./terminal.nix
|
./terminal.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
home = {
|
home.packages = with pkgs; [
|
||||||
packages = with pkgs; [
|
# Desktop Applications
|
||||||
# Desktop Applications
|
signal-desktop
|
||||||
gimp3
|
firefox
|
||||||
|
|
||||||
# Common utilities
|
# Common utilities
|
||||||
feh
|
feh
|
||||||
networkmanagerapplet # network control
|
networkmanagerapplet # network control
|
||||||
gnome-keyring # Secret management
|
gnome-keyring # Secret management
|
||||||
glib # for Gnome/GTK settings
|
glib # for Gnome/GTK settings
|
||||||
gsettings-desktop-schemas # So that we can access gnome settings
|
gsettings-desktop-schemas # So that we can access gnome settings
|
||||||
xdg-desktop-portal-hyprland
|
xdg-desktop-portal-hyprland
|
||||||
xdg-desktop-portal-gtk # GTK backend for XDG components like pickers
|
xdg-desktop-portal-gtk # GTK backend for XDG components like pickers
|
||||||
grim # Screenshot provider
|
grim # Screenshot provider
|
||||||
nwg-look # GTK settings editor
|
nwg-look # GTK settings editor
|
||||||
playerctl # for universal play/pause etc
|
playerctl # for universal play/pause etc
|
||||||
wirelesstools
|
wirelesstools
|
||||||
waypaper # Wallpaper switcher
|
waypaper # Wallpaper switcher
|
||||||
];
|
];
|
||||||
|
|
||||||
pointerCursor = {
|
home.pointerCursor = {
|
||||||
enable = true;
|
enable = true;
|
||||||
gtk.enable = true;
|
gtk.enable = true;
|
||||||
name = "phinger-cursors";
|
name = "phinger-cursors";
|
||||||
size = 16;
|
size = 16;
|
||||||
package = pkgs.phinger-cursors;
|
package = pkgs.phinger-cursors;
|
||||||
};
|
|
||||||
|
|
||||||
# Hint for electron apps to use wayland
|
|
||||||
sessionVariables.NIXOS_OZONE_WL = "1";
|
|
||||||
|
|
||||||
# Miscelaneous config files
|
|
||||||
file = {
|
|
||||||
".XCompose".source = ./config/XCompose;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
programs = {
|
# Hint for electron apps to use wayland
|
||||||
# browsers
|
home.sessionVariables.NIXOS_OZONE_WL = "1";
|
||||||
firefox.enable = true;
|
|
||||||
librewolf.enable = true;
|
# Miscelaneous config files
|
||||||
chromium.enable = true;
|
home.file = {
|
||||||
|
".XCompose".source = ./config/XCompose;
|
||||||
};
|
};
|
||||||
|
|
||||||
# GTK settings
|
# GTK settings
|
||||||
@@ -83,18 +76,4 @@
|
|||||||
platformTheme.name = "adwaita";
|
platformTheme.name = "adwaita";
|
||||||
style.name = "adwaita-dark";
|
style.name = "adwaita-dark";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Default apps
|
|
||||||
xdg.mimeApps = {
|
|
||||||
enable = true;
|
|
||||||
defaultApplications = {
|
|
||||||
"text/html" = [ "firefox.desktop" ];
|
|
||||||
"default-web-browser" = [ "firefox.desktop" ];
|
|
||||||
"x-scheme-handler/http" = [ "firefox.desktop" ];
|
|
||||||
"x-scheme-handler/https" = [ "firefox.desktop" ];
|
|
||||||
"x-scheme-handler/about" = [ "firefox.desktop" ];
|
|
||||||
"x-scheme-handler/unknown" = [ "firefox.desktop" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
home.sessionVariables.DEFAULT_BROWSER = "${pkgs.firefox}/bin/firefox";
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"extras": [
|
|
||||||
"lazyvim.plugins.extras.coding.mini-comment",
|
|
||||||
"lazyvim.plugins.extras.coding.mini-surround",
|
|
||||||
"lazyvim.plugins.extras.editor.snacks_picker",
|
|
||||||
"lazyvim.plugins.extras.lang.astro",
|
|
||||||
"lazyvim.plugins.extras.lang.haskell",
|
|
||||||
"lazyvim.plugins.extras.lang.json",
|
|
||||||
"lazyvim.plugins.extras.lang.markdown",
|
|
||||||
"lazyvim.plugins.extras.lang.nix",
|
|
||||||
"lazyvim.plugins.extras.lang.rust",
|
|
||||||
"lazyvim.plugins.extras.lang.tailwind",
|
|
||||||
"lazyvim.plugins.extras.lang.toml",
|
|
||||||
"lazyvim.plugins.extras.lang.typescript"
|
|
||||||
],
|
|
||||||
"install_version": 8,
|
|
||||||
"version": 8
|
|
||||||
}
|
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
vim.api.nvim_create_autocmd("FileType", {
|
vim.api.nvim_create_autocmd("FileType", {
|
||||||
pattern = { "markdown" },
|
pattern = { "markdown" },
|
||||||
callback = function()
|
callback = function()
|
||||||
vim.o.shiftwidth = 2
|
vim.bo.shiftwidth = 4
|
||||||
vim.o.tabstop = 2
|
vim.bo.tabstop = 4
|
||||||
vim.o.softtabstop = 2
|
vim.bo.softtabstop = 4
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -18,10 +18,6 @@ require("lazy").setup({
|
|||||||
spec = {
|
spec = {
|
||||||
-- add LazyVim and import its plugins
|
-- add LazyVim and import its plugins
|
||||||
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
|
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
|
||||||
-- Integrate ESlint for fixes and prettier for formatting
|
|
||||||
-- See: https://www.lazyvim.org/configuration/recipes
|
|
||||||
{ import = "lazyvim.plugins.extras.linting.eslint" },
|
|
||||||
{ import = "lazyvim.plugins.extras.formatting.prettier" },
|
|
||||||
-- import/override with your plugins
|
-- import/override with your plugins
|
||||||
{ import = "plugins" },
|
{ import = "plugins" },
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,6 +4,3 @@
|
|||||||
|
|
||||||
-- Creates a shortcut for adding the directory of the current buffer when specifying a file
|
-- Creates a shortcut for adding the directory of the current buffer when specifying a file
|
||||||
vim.cmd("cnoreabbrev %. %:h<Tab>")
|
vim.cmd("cnoreabbrev %. %:h<Tab>")
|
||||||
|
|
||||||
-- Set snacks as the preferred picker.
|
|
||||||
vim.g.lazyvim_picker = "snacks"
|
|
||||||
|
|||||||
@@ -1,29 +1,6 @@
|
|||||||
return {
|
return {
|
||||||
"saghen/blink.cmp",
|
"saghen/blink.cmp",
|
||||||
dependencies = {
|
|
||||||
"moyiz/blink-emoji.nvim",
|
|
||||||
},
|
|
||||||
opts = {
|
opts = {
|
||||||
sources = {
|
|
||||||
default = { "lsp", "buffer", "snippets", "path", "emoji" },
|
|
||||||
providers = {
|
|
||||||
-- https://github.com/moyiz/blink-emoji.nvim
|
|
||||||
emoji = {
|
|
||||||
module = "blink-emoji",
|
|
||||||
name = "Emoji",
|
|
||||||
score_offset = 15, -- Tune by preference
|
|
||||||
opts = { insert = true }, -- Insert emoji (default) or complete its name
|
|
||||||
should_show_items = function()
|
|
||||||
return vim.tbl_contains(
|
|
||||||
-- Enable emoji completion only for git commits and markdown.
|
|
||||||
-- By default, enabled for all file-types.
|
|
||||||
{ "gitcommit", "markdown" },
|
|
||||||
vim.o.filetype
|
|
||||||
)
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
keymap = {
|
keymap = {
|
||||||
preset = "default",
|
preset = "default",
|
||||||
["<C-space>"] = {
|
["<C-space>"] = {
|
||||||
@@ -31,7 +8,7 @@ return {
|
|||||||
cmp.show()
|
cmp.show()
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
["<Tab>"] = { "select_and_accept", "snippet_forward", "fallback" },
|
["<C-enter>"] = { "select_and_accept" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
return {
|
|
||||||
"stevearc/conform.nvim",
|
|
||||||
opts = {
|
|
||||||
formatters_by_ft = {
|
|
||||||
nix = { "nixfmt" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
return {
|
||||||
|
"zbirenbaum/copilot.lua",
|
||||||
|
opts = {
|
||||||
|
filetypes = {
|
||||||
|
markdown = false,
|
||||||
|
help = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
return {
|
return {
|
||||||
-- Maeson installs it's own binaries that are incompatible with NixOS.
|
-- Maeson installs it's own binaries that are incompatible with NixOS.
|
||||||
{ "mason-org/mason.nvim", enabled = false },
|
{ "williamboman/mason.nvim", enabled = false },
|
||||||
{ "mason-org/mason-lspconfig.nvim", enabled = false },
|
{ "williamboman/mason-lspconfig.nvim", enabled = false },
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,8 @@ return {
|
|||||||
"neovim/nvim-lspconfig",
|
"neovim/nvim-lspconfig",
|
||||||
opts = {
|
opts = {
|
||||||
servers = {
|
servers = {
|
||||||
-- Lua
|
|
||||||
lua_ls = {},
|
lua_ls = {},
|
||||||
-- Nix
|
|
||||||
nil_ls = {},
|
nil_ls = {},
|
||||||
-- Typescript
|
|
||||||
vtsls = {},
|
|
||||||
-- Haskell
|
|
||||||
hls = {},
|
|
||||||
},
|
|
||||||
codelens = {
|
|
||||||
enable = true,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
-- https://github.com/MeanderingProgrammer/render-markdown.nvim?tab=readme-ov-file#setup
|
|
||||||
return {
|
|
||||||
"MeanderingProgrammer/render-markdown.nvim",
|
|
||||||
opts = {
|
|
||||||
checkbox = {
|
|
||||||
enabled = true,
|
|
||||||
render_modes = true,
|
|
||||||
unchecked = {
|
|
||||||
icon = " ",
|
|
||||||
highlight = "RenderMarkdownUnchecked",
|
|
||||||
scope_highlight = nil,
|
|
||||||
},
|
|
||||||
checked = {
|
|
||||||
-- Replaces '[x]' of 'task_list_marker_checked'.
|
|
||||||
icon = " ",
|
|
||||||
-- Highlight for the checked icon.
|
|
||||||
highlight = "RenderMarkdownChecked",
|
|
||||||
-- Highlight for item associated with checked checkbox.
|
|
||||||
scope_highlight = nil,
|
|
||||||
},
|
|
||||||
-- Define custom checkbox states, more involved, not part of the markdown grammar.
|
|
||||||
-- As a result this requires neovim >= 0.10.0 since it relies on 'inline' extmarks.
|
|
||||||
-- The key is for healthcheck and to allow users to change its values, value type below.
|
|
||||||
-- | raw | matched against the raw text of a 'shortcut_link' |
|
|
||||||
-- | rendered | replaces the 'raw' value when rendering |
|
|
||||||
-- | highlight | highlight for the 'rendered' icon |
|
|
||||||
-- | scope_highlight | optional highlight for item associated with custom checkbox |
|
|
||||||
-- stylua: ignore
|
|
||||||
custom = {
|
|
||||||
partial = {
|
|
||||||
raw = '[/]',
|
|
||||||
rendered = '⛋ ',
|
|
||||||
highlight = 'RenderMarkdownTodo',
|
|
||||||
scope_highlight = nil
|
|
||||||
},
|
|
||||||
deferred = {
|
|
||||||
raw = '[>]',
|
|
||||||
rendered = '⛝ ',
|
|
||||||
highlight = 'RenderMarkdownWarn',
|
|
||||||
scope_highlight = nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -1,38 +1,10 @@
|
|||||||
return {
|
return {
|
||||||
{
|
{
|
||||||
"nvim-mini/mini.surround",
|
"echasnovski/mini.surround",
|
||||||
enable = true,
|
enable = true,
|
||||||
keys = function(_, keys)
|
|
||||||
-- Populate the keys based on the user's options
|
|
||||||
local opts = LazyVim.opts("mini.surround")
|
|
||||||
local mappings = {
|
|
||||||
{ opts.mappings.add, desc = "Add Surrounding", mode = { "n", "v" } },
|
|
||||||
{ opts.mappings.delete, desc = "Delete Surrounding" },
|
|
||||||
{ opts.mappings.find, desc = "Find Right Surrounding" },
|
|
||||||
{ opts.mappings.find_left, desc = "Find Left Surrounding" },
|
|
||||||
{ opts.mappings.highlight, desc = "Highlight Surrounding" },
|
|
||||||
{ opts.mappings.replace, desc = "Replace Surrounding" },
|
|
||||||
{ opts.mappings.update_n_lines, desc = "Update `MiniSurround.config.n_lines`" },
|
|
||||||
}
|
|
||||||
mappings = vim.tbl_filter(function(m)
|
|
||||||
return m[1] and #m[1] > 0
|
|
||||||
end, mappings)
|
|
||||||
return vim.list_extend(mappings, keys)
|
|
||||||
end,
|
|
||||||
opts = {
|
|
||||||
mappings = {
|
|
||||||
add = "gsa", -- Add surrounding in Normal and Visual modes
|
|
||||||
delete = "gsd", -- Delete surrounding
|
|
||||||
find = "gsf", -- Find surrounding (to the right)
|
|
||||||
find_left = "gsF", -- Find surrounding (to the left)
|
|
||||||
highlight = "gsh", -- Highlight surrounding
|
|
||||||
replace = "gsr", -- Replace surrounding
|
|
||||||
update_n_lines = "gsn", -- Update `n_lines`
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"nvim-mini/mini.comment",
|
"echasnovski/mini.comment",
|
||||||
enable = true,
|
enable = true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,20 @@
|
|||||||
return {
|
return {
|
||||||
"obsidian-nvim/obsidian.nvim",
|
"epwalsh/obsidian.nvim",
|
||||||
version = "*", -- recommended, use latest release instead of latest commit
|
version = "*", -- recommended, use latest release instead of latest commit
|
||||||
|
lazy = true,
|
||||||
ft = "markdown",
|
ft = "markdown",
|
||||||
|
-- Replace the above line with this if you only want to load obsidian.nvim for markdown files in your vault:
|
||||||
|
-- event = {
|
||||||
|
-- -- If you want to use the home shortcut '~' here you need to call 'vim.fn.expand'.
|
||||||
|
-- -- E.g. "BufReadPre " .. vim.fn.expand "~" .. "/my-vault/*.md"
|
||||||
|
-- -- refer to `:h file-pattern` for more examples
|
||||||
|
-- "BufReadPre path/to/my-vault/*.md",
|
||||||
|
-- "BufNewFile path/to/my-vault/*.md",
|
||||||
|
-- },
|
||||||
|
dependencies = {
|
||||||
|
-- Required.
|
||||||
|
"nvim-lua/plenary.nvim",
|
||||||
|
},
|
||||||
opts = {
|
opts = {
|
||||||
workspaces = {
|
workspaces = {
|
||||||
{
|
{
|
||||||
@@ -9,14 +22,6 @@ return {
|
|||||||
path = "~/Documents/Notes",
|
path = "~/Documents/Notes",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
-- Can I enable this somehow? I'm using blink.cmp but this is triggering
|
|
||||||
-- it to look for nvim-cmp directly.
|
|
||||||
-- completion = {
|
|
||||||
-- nvim_cmp = true,
|
|
||||||
-- min_chars = 2,
|
|
||||||
-- },
|
|
||||||
|
|
||||||
daily_notes = {
|
daily_notes = {
|
||||||
-- Optional, if you keep daily notes in a separate directory.
|
-- Optional, if you keep daily notes in a separate directory.
|
||||||
folder = "Daily Notes",
|
folder = "Daily Notes",
|
||||||
@@ -25,49 +30,10 @@ return {
|
|||||||
-- Optional, if you want to automatically insert a template from your template directory like ''
|
-- Optional, if you want to automatically insert a template from your template directory like ''
|
||||||
template = "Daily Note",
|
template = "Daily Note",
|
||||||
},
|
},
|
||||||
|
|
||||||
templates = {
|
templates = {
|
||||||
folder = "Templates",
|
folder = "Templates",
|
||||||
date_format = "%Y-%m-%d",
|
date_format = "%Y-%m-%d",
|
||||||
time_format = "%H:%M",
|
time_format = "%H:%M",
|
||||||
},
|
},
|
||||||
|
|
||||||
ui = {
|
|
||||||
-- Disable the UI features and let render-markdown.nvim handle it.
|
|
||||||
enable = false,
|
|
||||||
-- Even with UI disabled, this determines the order of checkbox states for the smart action.
|
|
||||||
checkboxes = {
|
|
||||||
[" "] = { char = "☐", hl_group = "ObsidianTodo" },
|
|
||||||
["x"] = { char = "✔", hl_group = "ObsidianDone" },
|
|
||||||
["/"] = { char = "⧗", hl_group = "ObsidianTodo" },
|
|
||||||
[">"] = { char = "»", hl_group = "ObsidianRightArrow" },
|
|
||||||
["~"] = { char = "»", hl_group = "ObsidianTilde" },
|
|
||||||
["!"] = { char = "⛝", hl_group = "ObsidianDone" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
-- Put the note ID in the wiki links
|
|
||||||
wiki_link_func = "prepend_note_id",
|
|
||||||
preferred_link_style = "wiki",
|
|
||||||
|
|
||||||
-- Customize how note IDs are generated given an optional title.
|
|
||||||
---@param title string|?
|
|
||||||
---@return string
|
|
||||||
note_id_func = function(title)
|
|
||||||
if title ~= nil then
|
|
||||||
-- If title is given, transform it into valid file name by removing most special characters
|
|
||||||
-- Note that parens are not supported because they interfere with markdown links.
|
|
||||||
return title:gsub("[^A-Za-z0-9-_]", ""):lower()
|
|
||||||
else
|
|
||||||
-- If title is nil, just put the date and four random characters
|
|
||||||
for _ = 1, 4 do
|
|
||||||
return os.date("%Y-%m-%d ") .. string.char(math.random(65, 90))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
follow_url_func = function(url)
|
|
||||||
vim.ui.open(url) -- Use the built-in open, need Neovim 0.10.0+
|
|
||||||
end,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +1,6 @@
|
|||||||
return {
|
return {
|
||||||
"folke/snacks.nvim",
|
"folke/snacks.nvim",
|
||||||
opts = function(_, opts)
|
---@type snacks.Config
|
||||||
vim.tbl_deep_extend("force", opts, {
|
|
||||||
picker = {
|
|
||||||
smart = {
|
|
||||||
-- Remove the "recent" picker so we don't get things from other directories.
|
|
||||||
multi = { "buffers", "files" },
|
|
||||||
matcher = {
|
|
||||||
-- sort even when the search string is empty
|
|
||||||
sort_empty = true,
|
|
||||||
-- Enable frecensy for matchers. This puts more common files near the top
|
|
||||||
frecency = false,
|
|
||||||
-- Make sure files in the current directory are prioritized
|
|
||||||
cwd_bonus = true,
|
|
||||||
-- Give more weight to files that are more recent
|
|
||||||
history_bonus = true,
|
|
||||||
-- Give more weight to places where the filename is part of the match
|
|
||||||
filename_bonus = true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
sources = {
|
|
||||||
explorer = {
|
|
||||||
layout = { layout = { position = "right" } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
-- This only supports the Kitty graphics protocol.
|
|
||||||
-- See
|
|
||||||
-- https://github.com/folke/snacks.nvim/blob/main/docs/image.md
|
|
||||||
-- https://github.com/obsidian-nvim/obsidian.nvim/wiki/Images
|
|
||||||
-- image = {
|
|
||||||
-- resolve = function(path, src)
|
|
||||||
-- if require("obsidian.api").path_is_note(path) then
|
|
||||||
-- return require("obsidian.api").resolve_image_path(src)
|
|
||||||
-- end
|
|
||||||
-- end,
|
|
||||||
-- },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
Snacks.toggle({
|
|
||||||
name = "Color Column",
|
|
||||||
get = function()
|
|
||||||
return vim.o.colorcolumn == "80"
|
|
||||||
end,
|
|
||||||
set = function(state)
|
|
||||||
if state then
|
|
||||||
vim.o.colorcolumn = "80"
|
|
||||||
vim.cmd([[highlight ColorColumn guibg=#202020]])
|
|
||||||
else
|
|
||||||
vim.o.colorcolumn = ""
|
|
||||||
vim.cmd([[highlight ColorColumn guibg=None]])
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
}):map("<leader>ut", { desc = "Toggle Color Column" })
|
|
||||||
end,
|
|
||||||
keys = {
|
keys = {
|
||||||
{
|
{
|
||||||
"<leader><space>",
|
"<leader><space>",
|
||||||
@@ -61,5 +9,257 @@ return {
|
|||||||
end,
|
end,
|
||||||
desc = "Smart Find Files",
|
desc = "Smart Find Files",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
-- The rest of these are just default bindings. Setting the one binding above seems to override the others.
|
||||||
|
{
|
||||||
|
"<leader>,",
|
||||||
|
function()
|
||||||
|
Snacks.picker.buffers()
|
||||||
|
end,
|
||||||
|
desc = "Buffers",
|
||||||
|
},
|
||||||
|
{ "<leader>/", LazyVim.pick("grep"), desc = "Grep (Root Dir)" },
|
||||||
|
{
|
||||||
|
"<leader>:",
|
||||||
|
function()
|
||||||
|
Snacks.picker.command_history()
|
||||||
|
end,
|
||||||
|
desc = "Command History",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>n",
|
||||||
|
function()
|
||||||
|
Snacks.picker.notifications()
|
||||||
|
end,
|
||||||
|
desc = "Notification History",
|
||||||
|
},
|
||||||
|
-- find
|
||||||
|
{
|
||||||
|
"<leader>fb",
|
||||||
|
function()
|
||||||
|
Snacks.picker.buffers()
|
||||||
|
end,
|
||||||
|
desc = "Buffers",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>fB",
|
||||||
|
function()
|
||||||
|
Snacks.picker.buffers({ hidden = true, nofile = true })
|
||||||
|
end,
|
||||||
|
desc = "Buffers (all)",
|
||||||
|
},
|
||||||
|
{ "<leader>fc", LazyVim.pick.config_files(), desc = "Find Config File" },
|
||||||
|
{ "<leader>ff", LazyVim.pick("files"), desc = "Find Files (Root Dir)" },
|
||||||
|
{ "<leader>fF", LazyVim.pick("files", { root = false }), desc = "Find Files (cwd)" },
|
||||||
|
{
|
||||||
|
"<leader>fg",
|
||||||
|
function()
|
||||||
|
Snacks.picker.git_files()
|
||||||
|
end,
|
||||||
|
desc = "Find Files (git-files)",
|
||||||
|
},
|
||||||
|
{ "<leader>fr", LazyVim.pick("oldfiles"), desc = "Recent" },
|
||||||
|
{
|
||||||
|
"<leader>fR",
|
||||||
|
function()
|
||||||
|
Snacks.picker.recent({ filter = { cwd = true } })
|
||||||
|
end,
|
||||||
|
desc = "Recent (cwd)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>fp",
|
||||||
|
function()
|
||||||
|
Snacks.picker.projects()
|
||||||
|
end,
|
||||||
|
desc = "Projects",
|
||||||
|
},
|
||||||
|
-- git
|
||||||
|
{
|
||||||
|
"<leader>gd",
|
||||||
|
function()
|
||||||
|
Snacks.picker.git_diff()
|
||||||
|
end,
|
||||||
|
desc = "Git Diff (hunks)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>gs",
|
||||||
|
function()
|
||||||
|
Snacks.picker.git_status()
|
||||||
|
end,
|
||||||
|
desc = "Git Status",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>gS",
|
||||||
|
function()
|
||||||
|
Snacks.picker.git_stash()
|
||||||
|
end,
|
||||||
|
desc = "Git Stash",
|
||||||
|
},
|
||||||
|
-- Grep
|
||||||
|
{
|
||||||
|
"<leader>sb",
|
||||||
|
function()
|
||||||
|
Snacks.picker.lines()
|
||||||
|
end,
|
||||||
|
desc = "Buffer Lines",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sB",
|
||||||
|
function()
|
||||||
|
Snacks.picker.grep_buffers()
|
||||||
|
end,
|
||||||
|
desc = "Grep Open Buffers",
|
||||||
|
},
|
||||||
|
{ "<leader>sg", LazyVim.pick("live_grep"), desc = "Grep (Root Dir)" },
|
||||||
|
{ "<leader>sG", LazyVim.pick("live_grep", { root = false }), desc = "Grep (cwd)" },
|
||||||
|
{
|
||||||
|
"<leader>sp",
|
||||||
|
function()
|
||||||
|
Snacks.picker.lazy()
|
||||||
|
end,
|
||||||
|
desc = "Search for Plugin Spec",
|
||||||
|
},
|
||||||
|
{ "<leader>sw", LazyVim.pick("grep_word"), desc = "Visual selection or word (Root Dir)", mode = { "n", "x" } },
|
||||||
|
{
|
||||||
|
"<leader>sW",
|
||||||
|
LazyVim.pick("grep_word", { root = false }),
|
||||||
|
desc = "Visual selection or word (cwd)",
|
||||||
|
mode = { "n", "x" },
|
||||||
|
},
|
||||||
|
-- search
|
||||||
|
{
|
||||||
|
'<leader>s"',
|
||||||
|
function()
|
||||||
|
Snacks.picker.registers()
|
||||||
|
end,
|
||||||
|
desc = "Registers",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>s/",
|
||||||
|
function()
|
||||||
|
Snacks.picker.search_history()
|
||||||
|
end,
|
||||||
|
desc = "Search History",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sa",
|
||||||
|
function()
|
||||||
|
Snacks.picker.autocmds()
|
||||||
|
end,
|
||||||
|
desc = "Autocmds",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sc",
|
||||||
|
function()
|
||||||
|
Snacks.picker.command_history()
|
||||||
|
end,
|
||||||
|
desc = "Command History",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sC",
|
||||||
|
function()
|
||||||
|
Snacks.picker.commands()
|
||||||
|
end,
|
||||||
|
desc = "Commands",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sd",
|
||||||
|
function()
|
||||||
|
Snacks.picker.diagnostics()
|
||||||
|
end,
|
||||||
|
desc = "Diagnostics",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sD",
|
||||||
|
function()
|
||||||
|
Snacks.picker.diagnostics_buffer()
|
||||||
|
end,
|
||||||
|
desc = "Buffer Diagnostics",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sh",
|
||||||
|
function()
|
||||||
|
Snacks.picker.help()
|
||||||
|
end,
|
||||||
|
desc = "Help Pages",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sH",
|
||||||
|
function()
|
||||||
|
Snacks.picker.highlights()
|
||||||
|
end,
|
||||||
|
desc = "Highlights",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>si",
|
||||||
|
function()
|
||||||
|
Snacks.picker.icons()
|
||||||
|
end,
|
||||||
|
desc = "Icons",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sj",
|
||||||
|
function()
|
||||||
|
Snacks.picker.jumps()
|
||||||
|
end,
|
||||||
|
desc = "Jumps",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sk",
|
||||||
|
function()
|
||||||
|
Snacks.picker.keymaps()
|
||||||
|
end,
|
||||||
|
desc = "Keymaps",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sl",
|
||||||
|
function()
|
||||||
|
Snacks.picker.loclist()
|
||||||
|
end,
|
||||||
|
desc = "Location List",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sM",
|
||||||
|
function()
|
||||||
|
Snacks.picker.man()
|
||||||
|
end,
|
||||||
|
desc = "Man Pages",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sm",
|
||||||
|
function()
|
||||||
|
Snacks.picker.marks()
|
||||||
|
end,
|
||||||
|
desc = "Marks",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sR",
|
||||||
|
function()
|
||||||
|
Snacks.picker.resume()
|
||||||
|
end,
|
||||||
|
desc = "Resume",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sq",
|
||||||
|
function()
|
||||||
|
Snacks.picker.qflist()
|
||||||
|
end,
|
||||||
|
desc = "Quickfix List",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>su",
|
||||||
|
function()
|
||||||
|
Snacks.picker.undo()
|
||||||
|
end,
|
||||||
|
desc = "Undotree",
|
||||||
|
},
|
||||||
|
-- ui
|
||||||
|
{
|
||||||
|
"<leader>uC",
|
||||||
|
function()
|
||||||
|
Snacks.picker.colorschemes()
|
||||||
|
end,
|
||||||
|
desc = "Colorschemes",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
return {
|
|
||||||
"nvim-treesitter/nvim-treesitter",
|
|
||||||
opts = {
|
|
||||||
ensure_installed = {
|
|
||||||
"astro",
|
|
||||||
"bash",
|
|
||||||
"html",
|
|
||||||
"css",
|
|
||||||
"javascript",
|
|
||||||
"json",
|
|
||||||
"lua",
|
|
||||||
"markdown",
|
|
||||||
"markdown_inline",
|
|
||||||
"python",
|
|
||||||
"query",
|
|
||||||
"regex",
|
|
||||||
"tsx",
|
|
||||||
"typescript",
|
|
||||||
"vim",
|
|
||||||
"yaml",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
extraPackages = with pkgs; [
|
extraPackages = with pkgs; [
|
||||||
gcc # For treesitter complation
|
gcc # For treesitter complation
|
||||||
tree-sitter # For treesitter binaries
|
|
||||||
ripgrep # Search support
|
ripgrep # Search support
|
||||||
wayclip # Clipboard support
|
wayclip # Clipboard support
|
||||||
fd # finder for telescope
|
fd # finder for telescope
|
||||||
@@ -18,7 +17,6 @@
|
|||||||
wget # LazyVim dep?
|
wget # LazyVim dep?
|
||||||
sqlite # For Snacks
|
sqlite # For Snacks
|
||||||
imagemagick # For image conversion/display
|
imagemagick # For image conversion/display
|
||||||
vscode-langservers-extracted # For language servers (it wants this version of eslint for some reason)
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
10
home-manager/features/nix.nix
Normal file
10
home-manager/features/nix.nix
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
# Enable flakes and nix-commnands.
|
||||||
|
nix.settings.experimental-features = ["flakes" "nix-command"];
|
||||||
|
|
||||||
|
# Allow unfree code
|
||||||
|
nixpkgs.config = {
|
||||||
|
allowUnfree = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -4,10 +4,6 @@
|
|||||||
obsidian
|
obsidian
|
||||||
];
|
];
|
||||||
|
|
||||||
home.shellAliases = {
|
|
||||||
"notes" = "(cd ~/Documents/Notes && nvim)";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.syncthing = {
|
services.syncthing = {
|
||||||
enable = true;
|
enable = true;
|
||||||
tray = {
|
tray = {
|
||||||
@@ -25,7 +21,6 @@
|
|||||||
"altair"
|
"altair"
|
||||||
"mcp"
|
"mcp"
|
||||||
"vega"
|
"vega"
|
||||||
"proxima"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -57,14 +52,6 @@
|
|||||||
];
|
];
|
||||||
compression = "always";
|
compression = "always";
|
||||||
};
|
};
|
||||||
proxima = {
|
|
||||||
id = "NWZL6LY-ULJQMZE-EWY3MQU-XPDAFQB-LTIBZV7-GPKIABJ-WBJE36F-SK6LVAY";
|
|
||||||
name = "Proxima";
|
|
||||||
addresses = [
|
|
||||||
"relay://syncthing.blazestar.net:22067"
|
|
||||||
];
|
|
||||||
compression = "always";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
options = {
|
options = {
|
||||||
localAnnounceEnabled = false;
|
localAnnounceEnabled = false;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
* {
|
* {
|
||||||
background: #15161ECC;
|
background: #15161EFF;
|
||||||
background-alt: #1A1B26FF;
|
background-alt: #1A1B26FF;
|
||||||
foreground: #C0CAF5FF;
|
foreground: #C0CAF5FF;
|
||||||
selected: #33467CFF;
|
selected: #33467CFF;
|
||||||
|
|||||||
@@ -15,4 +15,4 @@
|
|||||||
|
|
||||||
/* Import color-scheme from `colors` directory */
|
/* Import color-scheme from `colors` directory */
|
||||||
|
|
||||||
@import "~/.config/rofi/colors/tokyonight.rasi"
|
@import "~/.config/rofi/colors/onedark.rasi"
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
/*****----- Configuration -----*****/
|
/*****----- Configuration -----*****/
|
||||||
configuration {
|
configuration {
|
||||||
modi: "drun";
|
modi: "drun";
|
||||||
show-icons: true;
|
show-icons: true;
|
||||||
display-drun: "";
|
display-drun: "";
|
||||||
drun-display-format: "{name}";
|
drun-display-format: "{name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,8 +32,8 @@ window {
|
|||||||
enabled: true;
|
enabled: true;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
border: 2px solid;
|
border: 0px solid;
|
||||||
border-radius: 5px;
|
border-radius: 0px;
|
||||||
border-color: @selected;
|
border-color: @selected;
|
||||||
background-color: @background;
|
background-color: @background;
|
||||||
cursor: "default";
|
cursor: "default";
|
||||||
|
|||||||
@@ -15,4 +15,4 @@
|
|||||||
|
|
||||||
/* Import color-scheme from `colors` directory */
|
/* Import color-scheme from `colors` directory */
|
||||||
|
|
||||||
@import "~/.config/rofi/colors/tokyonight.rasi"
|
@import "~/.config/rofi/colors/onedark.rasi"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ dir="${HOME}/.config/rofi/powermenu"
|
|||||||
|
|
||||||
# CMDs
|
# CMDs
|
||||||
uptime="$(uptime | awk -F ' ' '{print $2}' | sed -e 's/,//g')"
|
uptime="$(uptime | awk -F ' ' '{print $2}' | sed -e 's/,//g')"
|
||||||
host=$(hostname)
|
host=`hostname`
|
||||||
|
|
||||||
# Options
|
# Options
|
||||||
shutdown=''
|
shutdown=''
|
||||||
@@ -24,94 +24,89 @@ no=''
|
|||||||
|
|
||||||
# Rofi CMD
|
# Rofi CMD
|
||||||
rofi_cmd() {
|
rofi_cmd() {
|
||||||
rofi -dmenu \
|
rofi -dmenu \
|
||||||
-p "Uptime: $uptime" \
|
-p "Uptime: $uptime" \
|
||||||
-mesg "Uptime: $uptime" \
|
-mesg "Uptime: $uptime" \
|
||||||
-theme ${dir}/style.rasi
|
-theme ${dir}/style.rasi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Confirmation CMD
|
# Confirmation CMD
|
||||||
confirm_cmd() {
|
confirm_cmd() {
|
||||||
rofi -theme-str 'window {location: center; anchor: center; fullscreen: false; width: 350px;}' \
|
rofi -theme-str 'window {location: center; anchor: center; fullscreen: false; width: 350px;}' \
|
||||||
-theme-str 'mainbox {children: [ "message", "listview" ];}' \
|
-theme-str 'mainbox {children: [ "message", "listview" ];}' \
|
||||||
-theme-str 'listview {columns: 2; lines: 1;}' \
|
-theme-str 'listview {columns: 2; lines: 1;}' \
|
||||||
-theme-str 'element-text {horizontal-align: 0.5;}' \
|
-theme-str 'element-text {horizontal-align: 0.5;}' \
|
||||||
-theme-str 'textbox {horizontal-align: 0.5;}' \
|
-theme-str 'textbox {horizontal-align: 0.5;}' \
|
||||||
-dmenu \
|
-dmenu \
|
||||||
-p 'Confirmation' \
|
-p 'Confirmation' \
|
||||||
-mesg 'Are you Sure?' \
|
-mesg 'Are you Sure?' \
|
||||||
-theme ${dir}/style.rasi
|
-theme ${dir}/style.rasi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Ask for confirmation
|
# Ask for confirmation
|
||||||
confirm_exit() {
|
confirm_exit() {
|
||||||
echo -e "$yes\n$no" | confirm_cmd
|
echo -e "$yes\n$no" | confirm_cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
# Pass variables to rofi dmenu
|
# Pass variables to rofi dmenu
|
||||||
run_rofi() {
|
run_rofi() {
|
||||||
echo -e "$lock\n$suspend\n$logout\n$reboot\n$shutdown" | rofi_cmd
|
echo -e "$lock\n$suspend\n$logout\n$reboot\n$shutdown" | rofi_cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute Command
|
# Execute Command
|
||||||
run_cmd() {
|
run_cmd() {
|
||||||
selected="$(confirm_exit)"
|
selected="$(confirm_exit)"
|
||||||
if [[ "$selected" == "$yes" ]]; then
|
if [[ "$selected" == "$yes" ]]; then
|
||||||
if [[ $1 == '--shutdown' ]]; then
|
if [[ $1 == '--shutdown' ]]; then
|
||||||
systemctl poweroff
|
systemctl poweroff
|
||||||
elif [[ $1 == '--reboot' ]]; then
|
elif [[ $1 == '--reboot' ]]; then
|
||||||
systemctl reboot
|
systemctl reboot
|
||||||
elif [[ $1 == '--suspend' ]]; then
|
elif [[ $1 == '--suspend' ]]; then
|
||||||
mpc -q pause
|
mpc -q pause
|
||||||
amixer set Master mute
|
amixer set Master mute
|
||||||
systemctl suspend
|
systemctl suspend
|
||||||
elif [[ $1 == '--logout' ]]; then
|
elif [[ $1 == '--logout' ]]; then
|
||||||
if [[ "$DESKTOP_SESSION" == 'openbox' ]]; then
|
if [[ "$DESKTOP_SESSION" == 'openbox' ]]; then
|
||||||
openbox --exit
|
openbox --exit
|
||||||
elif [[ "$DESKTOP_SESSION" == 'bspwm' ]]; then
|
elif [[ "$DESKTOP_SESSION" == 'bspwm' ]]; then
|
||||||
bspc quit
|
bspc quit
|
||||||
elif [[ "$DESKTOP_SESSION" == 'i3' ]]; then
|
elif [[ "$DESKTOP_SESSION" == 'i3' ]]; then
|
||||||
i3-msg exit
|
i3-msg exit
|
||||||
elif [[ "$DESKTOP_SESSION" == 'plasma' ]]; then
|
elif [[ "$DESKTOP_SESSION" == 'plasma' ]]; then
|
||||||
qdbus org.kde.ksmserver /KSMServer logout 0 0 0
|
qdbus org.kde.ksmserver /KSMServer logout 0 0 0
|
||||||
elif [[ "$DESKTOP_SESSION" == 'plasma' ]]; then
|
elif [[ "$DESKTOP_SESSION" == 'plasma' ]]; then
|
||||||
qdbus org.kde.ksmserver /KSMServer logout 0 0 0
|
qdbus org.kde.ksmserver /KSMServer logout 0 0 0
|
||||||
elif [[ "$DESKTOP_SESSION" == 'hyprland-uwsm' ]]; then
|
elif command -v hyprctl &>/dev/null; then
|
||||||
hyprctl dispatch exit
|
hyprctl dispatch exit
|
||||||
elif [[ "$DESKTOP_SESSION" == 'hyprland' ]]; then
|
fi
|
||||||
hyprctl dispatch exit
|
fi
|
||||||
fi
|
else
|
||||||
fi
|
exit 0
|
||||||
else
|
fi
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Actions
|
# Actions
|
||||||
chosen="$(run_rofi)"
|
chosen="$(run_rofi)"
|
||||||
case ${chosen} in
|
case ${chosen} in
|
||||||
$shutdown)
|
$shutdown)
|
||||||
run_cmd --shutdown
|
run_cmd --shutdown
|
||||||
;;
|
;;
|
||||||
$reboot)
|
$reboot)
|
||||||
run_cmd --reboot
|
run_cmd --reboot
|
||||||
;;
|
;;
|
||||||
$lock)
|
$lock)
|
||||||
loginctl lock-session
|
if [[ -x '/usr/bin/betterlockscreen' ]]; then
|
||||||
# if [[ -x '/usr/bin/betterlockscreen' ]]; then
|
betterlockscreen -l
|
||||||
# betterlockscreen -l
|
elif [[ -x '/usr/bin/i3lock' ]]; then
|
||||||
# elif [[ -x '/usr/bin/i3lock' ]]; then
|
i3lock
|
||||||
# i3lock
|
elif command -v hyprlock &>/dev/null; then
|
||||||
# elif command -v hyprlock &>/dev/null; then
|
hyprlock
|
||||||
# hyprlock
|
fi
|
||||||
# elif command -v swaylock &>/dev/null; then
|
;;
|
||||||
# swaylock
|
$suspend)
|
||||||
# fi
|
run_cmd --suspend
|
||||||
;;
|
;;
|
||||||
$suspend)
|
$logout)
|
||||||
run_cmd --suspend
|
run_cmd --logout
|
||||||
;;
|
;;
|
||||||
$logout)
|
|
||||||
run_cmd --logout
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ window {
|
|||||||
enabled: true;
|
enabled: true;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
border: 2px solid;
|
border: 0px solid;
|
||||||
border-radius: 5px;
|
border-radius: 0px;
|
||||||
border-color: @selected;
|
border-color: @selected;
|
||||||
cursor: "default";
|
cursor: "default";
|
||||||
background-color: @background;
|
background-color: @background;
|
||||||
|
|||||||
@@ -8,10 +8,4 @@
|
|||||||
source = ./config;
|
source = ./config;
|
||||||
recursive = true;
|
recursive = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
wayland.windowManager.hyprland.settings.windowrulev2 = [
|
|
||||||
# Forces the Rofi window to hold focus so that it gets input even if
|
|
||||||
# something else opens or the mouse is outside the window.
|
|
||||||
"stayfocused, class:Rofi"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,6 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
|
|
||||||
imports = [
|
|
||||||
./uutils.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
# These are all the sort of shell commands that we want available whereever
|
# These are all the sort of shell commands that we want available whereever
|
||||||
# there is shell. These include just a lot of useful utilities for managing
|
# there is shell. These include just a lot of useful utilities for managing
|
||||||
# a system or working with other shell commands. Packages more specific to
|
# a system or working with other shell commands. Packages more specific to
|
||||||
@@ -15,53 +11,35 @@
|
|||||||
htop
|
htop
|
||||||
btop
|
btop
|
||||||
neofetch
|
neofetch
|
||||||
psmisc # fuser, killal, pstree
|
killall
|
||||||
|
|
||||||
# Archives
|
# Files
|
||||||
zip
|
zip
|
||||||
xz
|
xz
|
||||||
unzip
|
unzip
|
||||||
p7zip
|
p7zip
|
||||||
unrar-wrapper
|
|
||||||
|
|
||||||
# File manipulation
|
|
||||||
file
|
file
|
||||||
tree
|
tree
|
||||||
yazi # File manager
|
ranger
|
||||||
|
ueberzugpp # for image previews
|
||||||
w3m # terminal browser for image previews
|
w3m # terminal browser for image previews
|
||||||
dysk # better disk info
|
|
||||||
ripgrep # better grep
|
|
||||||
fd # Better find
|
|
||||||
bat # cat with wings
|
|
||||||
eza # Modern replacement for ls
|
|
||||||
dust # More intuitive du
|
|
||||||
dua # Interactive disk usage analyzer
|
|
||||||
|
|
||||||
# Networking
|
# Networking
|
||||||
dnsutils
|
dnsutils
|
||||||
inetutils
|
inetutils
|
||||||
socat
|
socat
|
||||||
xh
|
httpie
|
||||||
|
|
||||||
# devices
|
# devices
|
||||||
usbutils
|
usbutils
|
||||||
|
|
||||||
# Other
|
# Other
|
||||||
jq
|
jq
|
||||||
mprocs # Manage multiple long-running processes
|
|
||||||
];
|
];
|
||||||
|
|
||||||
home.shellAliases = {
|
home.shellAliases = {
|
||||||
"p?" = "ps ax | rg";
|
"p?" = "ps ax | grep";
|
||||||
# Dysk is basically just better.
|
|
||||||
"df" = "echo 'Do you mean: dysk?'";
|
|
||||||
"grep" = "echo 'Do you mean: rg?'";
|
|
||||||
"find" = "echo 'Do you mean: fd'";
|
|
||||||
"cat" = "bat";
|
|
||||||
"ls" = "eza";
|
|
||||||
"http" = "echo 'Do you mean: xh'";
|
|
||||||
"du" = "echo 'Do you mean: dust or dua?'";
|
|
||||||
"ranger" = "echo 'Do you mean: yazi'";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.zsh = {
|
programs.zsh = {
|
||||||
@@ -70,7 +48,7 @@
|
|||||||
PATH=$PATH:$HOME/.local/bin
|
PATH=$PATH:$HOME/.local/bin
|
||||||
GITHUB_USERNAME=periodic
|
GITHUB_USERNAME=periodic
|
||||||
'';
|
'';
|
||||||
initContent = ''
|
initExtra = ''
|
||||||
# Make ^U work like it does in Bash
|
# Make ^U work like it does in Bash
|
||||||
bindkey "^U" backward-kill-line
|
bindkey "^U" backward-kill-line
|
||||||
|
|
||||||
@@ -116,12 +94,6 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.zoxide = {
|
|
||||||
# TODO: Learn all the capabilities of zoxide and use them.
|
|
||||||
enable = true;
|
|
||||||
enableZshIntegration = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.starship = {
|
programs.starship = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
|
|||||||
@@ -1,12 +1,21 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./swaync.nix
|
./swaync.nix
|
||||||
./swaylock.nix
|
];
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
hyprlock # lock screen
|
||||||
|
# swayidle # lock on idle
|
||||||
|
# swayosd # volume pop-up
|
||||||
|
# swaynotificationcenter # notifications
|
||||||
|
# hyprpolkitagent # Privilege managent
|
||||||
|
# hyprshot # Screenshot utility
|
||||||
];
|
];
|
||||||
|
|
||||||
services.swayosd = {
|
services.swayosd = {
|
||||||
@@ -14,6 +23,16 @@
|
|||||||
topMargin = 0.7;
|
topMargin = 0.7;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.swayidle = {
|
||||||
|
enable = true;
|
||||||
|
events = [
|
||||||
|
{
|
||||||
|
event = "before-sleep";
|
||||||
|
command = "hyprlock";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
# Enable sway config generation for home.pointerCursor
|
# Enable sway config generation for home.pointerCursor
|
||||||
home.pointerCursor.sway.enable = true;
|
home.pointerCursor.sway.enable = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
programs.swaylock = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.swaylock-effects;
|
|
||||||
settings = {
|
|
||||||
clock = true;
|
|
||||||
indicator = true;
|
|
||||||
effect-pixelate = 20;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
home.file.".config/swaylock/swaylock.sh" = {
|
|
||||||
executable = true;
|
|
||||||
# A script that will take the wallpaper folder for each monitor (see
|
|
||||||
# wallpaper.nix) and use a random image as the background on each monitor.
|
|
||||||
text = ''
|
|
||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
wallpaper_dir="$HOME/Pictures/Wallpaper"
|
|
||||||
cmd="swaylock"
|
|
||||||
|
|
||||||
for monitor in $(hyprctl monitors | awk '/^Monitor/ { print $2 }'); do
|
|
||||||
dir="$wallpaper_dir/$monitor"
|
|
||||||
if [ -d "$dir" ]; then
|
|
||||||
image=$(find "$dir" -type f | shuf -n 1)
|
|
||||||
if [ -n "$image" ]; then
|
|
||||||
cmd="$cmd --image \"$monitor:$image\""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Eval to handle the quoted image paths correctly
|
|
||||||
eval $cmd
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -5,15 +5,14 @@
|
|||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
# Font
|
# Font
|
||||||
# 24.11
|
# 24.11
|
||||||
# inconsolata-nerdfont
|
inconsolata-nerdfont
|
||||||
# fira-code-nerdfont
|
fira-code-nerdfont
|
||||||
# 25.05
|
# 25.05
|
||||||
nerd-fonts.inconsolata
|
# nerd-fonts.inconsolata
|
||||||
nerd-fonts.fira-code
|
# nerd-fonts.fira-code
|
||||||
nerd-fonts.jetbrains-mono
|
# nerd-fonts.jetbrains-mono
|
||||||
|
|
||||||
libsixel # For working with images in terminals
|
libsixel # For working with images in terminals
|
||||||
ueberzugpp # for image previews
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# Allow Home Manager to set fonts.
|
# Allow Home Manager to set fonts.
|
||||||
@@ -51,7 +50,7 @@
|
|||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
main = {
|
main = {
|
||||||
font = "FiraCode Nerd Font:size=12";
|
font = "FiraCode Nerd Font:size=13";
|
||||||
selection-target = "primary";
|
selection-target = "primary";
|
||||||
pad = "8x8";
|
pad = "8x8";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
{ pkgs, lib, ... }:
|
|
||||||
{
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
# Use uutils core-utils with no prefix so they override the GNU coreutils
|
|
||||||
(lib.hiPrio uutils-coreutils-noprefix)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,6 @@ monitors:
|
|||||||
map (mon: {
|
map (mon: {
|
||||||
name = mon;
|
name = mon;
|
||||||
value = {
|
value = {
|
||||||
# Each monitor gets a folder under wallpaper that containes the current images.
|
|
||||||
path = "~/Pictures/Wallpaper/${mon}";
|
path = "~/Pictures/Wallpaper/${mon}";
|
||||||
};
|
};
|
||||||
}) monitors
|
}) monitors
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
gitea:
|
gitea_db_password: ENC[AES256_GCM,data:G2YqiDk0msBRjUJkoPxWmayQ9dI=,iv:FsojIJIi61K7rD2VULDgIx6uSYX3iDiA6W744HlgHl0=,tag:BlmsM7LZHnBCKtfuqlhoKA==,type:str]
|
||||||
db_password: ENC[AES256_GCM,data:12FYMsc8HdTMdPegoPLCidaHMMU=,iv:Uat0g7Nvota1yvj6InIAo7Dzv3cBtVVzlRa1d09gx1s=,tag:sFavpAHW0k/Fv1uzPVuGcA==,type:str]
|
|
||||||
registration_token: ENC[AES256_GCM,data:zYfFATOuqACrGUyt6xPhiisz293uomKc6BLPKz8I+MFFBrBdzT9FqA==,iv:gyp2WsUHMMrNBmssWGPLSJmZqlAtopc6HeAtX9+oCXs=,tag:mLEPTapn7OM3bm5c9TKB0A==,type:str]
|
|
||||||
bookstack_app_key: ENC[AES256_GCM,data:N79JVlQSoVCXOsIHCxd19HFm6LkrYyXQu/xWenEdUlQWqwZEi3PuHXG7fQgvzQY4KI7S,iv:cd2l2eOv+wAJ5sih3YhHgQTdy1qrvaIsoHcywOnHuYM=,tag:5QvCHlQX8wUz3tI2NXl+8A==,type:str]
|
bookstack_app_key: ENC[AES256_GCM,data:N79JVlQSoVCXOsIHCxd19HFm6LkrYyXQu/xWenEdUlQWqwZEi3PuHXG7fQgvzQY4KI7S,iv:cd2l2eOv+wAJ5sih3YhHgQTdy1qrvaIsoHcywOnHuYM=,tag:5QvCHlQX8wUz3tI2NXl+8A==,type:str]
|
||||||
bookstack_db: ENC[AES256_GCM,data:m8fGgAfmJu1rEaxmTVH4FfBhyiU=,iv:OnBT/6sp9zmcJ1+kBmdmvaE630hifxBpvKnu3XrVXcE=,tag:SSVQcYkAymlbFOnf0MB6KA==,type:str]
|
bookstack_db: ENC[AES256_GCM,data:m8fGgAfmJu1rEaxmTVH4FfBhyiU=,iv:OnBT/6sp9zmcJ1+kBmdmvaE630hifxBpvKnu3XrVXcE=,tag:SSVQcYkAymlbFOnf0MB6KA==,type:str]
|
||||||
mariadb_root_password: ENC[AES256_GCM,data:p965ZhFQqqX+Ub1yhgklVYlBH6A=,iv:qC5WwTvZGvlbAkYiv35xHizMYAnP0V0Vw79EkvL32wQ=,tag:gOJQvHeOC9turFKOMQ9DNg==,type:str]
|
mariadb_root_password: ENC[AES256_GCM,data:p965ZhFQqqX+Ub1yhgklVYlBH6A=,iv:qC5WwTvZGvlbAkYiv35xHizMYAnP0V0Vw79EkvL32wQ=,tag:gOJQvHeOC9turFKOMQ9DNg==,type:str]
|
||||||
@@ -11,23 +9,11 @@ focalboard:
|
|||||||
offen:
|
offen:
|
||||||
secret: ENC[AES256_GCM,data:sH2siPc/QH1O2M7ZlJwqhqlHRIeLIG9r,iv:eD29ALx2ji0rm1t9j6RulTZT3f6VLK7dxpPOze3qDKA=,tag:zqJTgT2UeA/ecBS4VremUw==,type:str]
|
secret: ENC[AES256_GCM,data:sH2siPc/QH1O2M7ZlJwqhqlHRIeLIG9r,iv:eD29ALx2ji0rm1t9j6RulTZT3f6VLK7dxpPOze3qDKA=,tag:zqJTgT2UeA/ecBS4VremUw==,type:str]
|
||||||
smtp-token: ENC[AES256_GCM,data:ZTfe65g3JykPvG2l0AN8UQ==,iv:GTruGo/vcP+imfJyqB3NX9ic8dz5jvTEh6SF+OeqMDM=,tag:kgwd59pG/WUt8OAaVzi39Q==,type:str]
|
smtp-token: ENC[AES256_GCM,data:ZTfe65g3JykPvG2l0AN8UQ==,iv:GTruGo/vcP+imfJyqB3NX9ic8dz5jvTEh6SF+OeqMDM=,tag:kgwd59pG/WUt8OAaVzi39Q==,type:str]
|
||||||
traefik:
|
|
||||||
oauth2-client-secret: ENC[AES256_GCM,data:p7/6OsN2ytBj8mQiK0YL7J6NYLtMHOXIIs/6+bIDpsU=,iv:k6jLZifJEFLYKSFMkyn/kA7iBE+EFB8O/3/3fyTh1SY=,tag:6s49O2+tdlZoXyAGEamuMQ==,type:str]
|
|
||||||
oauth2-plugin-secret: ENC[AES256_GCM,data:sArqwKHAdW35o5kD7DGfXSYCXFUXqvKQdoVnXutsNLw=,iv:qWf597QS3BqkVQkeAb99HbpDB0kUhdD+qKdpUPZEB0o=,tag:vXnb93npaklItWkMZ+/M9Q==,type:str]
|
|
||||||
protonvpn:
|
|
||||||
private_key: ENC[AES256_GCM,data:41pfbR1klj1F24v3HlCCA4ofW2sCEnyE5TH8iX4Ug8D+kmwstTaj5RG2Zz8=,iv:P6XyQnDVoOmdkP8ilBR9DyfqPZA6GsQ6VUwY/tSGhx4=,tag:Bzgdv29lbk/gYlADPZMGVA==,type:str]
|
|
||||||
deploy-key:
|
|
||||||
mcp: ENC[AES256_GCM,data:eQcX8xdz5qZ6nU8ISOvZo+ZtP4Z/ePd+/ZZReX1BKvTUqGQPPFxConbLMwFzvzpD6xAUbA1MLkcR/bT98QbNx6LJYlhbofuDUg2DI79RB0fcrAcj/wUV0YPhmgofUdYYDaimH5A2PSvtmKfB3CtKKuA5HNeLymoXeLEpFzbckkGhzPee/CHiUmxayogp6za6btsDJsiT8hdHbrzyD2S6fhMJrzX+PlRzT32M/6eaFuFWE8EUO1gbkRlNfKPXw/EM2GXWJfR4qXfN2YKIKigqrtlAAoxnrUbp5EBrn/hGHS2ZYZXeRUFr3avFjcI0bLX423PWRHAylfQCPxgYVEtbcRv11CAFmq4rfFl0ZdvnAKbTLNmWcrQNijBATZPaAdQzgKPDHs8pwPUFR9Tcg8pZNbzw0mK9kPolniAOL2PBKUHv6LP/uEkB1E6Pxc7yms0kGpeJyo7hrFVOiVAckCey+SI9dpbJMSB3md070I1xk6Ik7PywrWh2QDeUtOU1U28UkYgnJ/9MJelWsNlUX9SR,iv:oCNeanaV/7UZ3dhmq4ZmJUZ5hb61AnHpHCfskM2Jsm8=,tag:F2uJKN5beM/rfiBMSyUP7w==,type:str]
|
|
||||||
matrix:
|
|
||||||
syncv3:
|
|
||||||
db-password: ENC[AES256_GCM,data:N/IO0k/2BZpmaDTbKZmSgZNzmdk=,iv:p0jGjJ9mTCh5FPM/Oe1vxusYvlyg14UeggE5ynpDVL8=,tag:tZbddwxJf6wSH6L1QRUQVg==,type:str]
|
|
||||||
secret: ENC[AES256_GCM,data:KZjYxjUxGgkY1I5jGF7XMEhkHK+khDaQzxugoKxpLsROmVs722tFfbUAxhp71llam55gy9+eUWGxIPlmvOySlw==,iv:OoThGcT08Z11kpnAMQ7w59wj5JheNFGEk1jfFENsmy0=,tag:8EeKT7dh2/a52Amf6LsL1w==,type:str]
|
|
||||||
blazestar-registration-token: ENC[AES256_GCM,data:TB3bR+E4H4c2l9pRcEOAZr35+vBVaJUcuCs9K0Pjd0aW+M35x5LgZ8+F99Y=,iv:e28sie6LSI5UX41BPb+yN+3n+Yw9Ssfsqe4zppwbPkU=,tag:cQPgZcRFbYSiZnmPVtZxHg==,type:str]
|
|
||||||
tandoor:
|
|
||||||
secret_key: ENC[AES256_GCM,data:nl7S2fS1wENrT5k2iZfLEAGc99lCUktgwR5L5KklF69BNVKQkW1rUgb3aIv50VpXZa+3OxV/vdPmG9NhKMy96I5+Dno=,iv:FFyGQBARz0B5zrONZELzUMsOIn8TWrDNTKGsAHPlS7w=,tag:/c4MnDfLXQpBZDqVxZ0DTg==,type:str]
|
|
||||||
immich:
|
|
||||||
database: ENC[AES256_GCM,data:1fjOQsLZcq/T+r+AkzomWwCQWw==,iv:c4pn2rC+3xkxLJ7uAdhnTE6zVTRQkfuKK3tjUyDhfAw=,tag:kvk7DOv6X/+RDxfPxVak7w==,type:str]
|
|
||||||
sops:
|
sops:
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
age:
|
age:
|
||||||
- recipient: age1yvdzvuvu5wqztcx6ll2xk6x547uuyqy735tjjdd7zftkz53jsf9qf5ahue
|
- recipient: age1yvdzvuvu5wqztcx6ll2xk6x547uuyqy735tjjdd7zftkz53jsf9qf5ahue
|
||||||
enc: |
|
enc: |
|
||||||
@@ -47,7 +33,8 @@ sops:
|
|||||||
by9aNFY4dXNxaWxnTXFTQS9reHhuQWMKh5rZ93nFtBV9EpFVRp+E+GXZ6xzVy2Jw
|
by9aNFY4dXNxaWxnTXFTQS9reHhuQWMKh5rZ93nFtBV9EpFVRp+E+GXZ6xzVy2Jw
|
||||||
vFh4deGcAb60q4odSaeWfk1Dr7L9Ua69oK9omjbCNUt+P7Kwlfca7Q==
|
vFh4deGcAb60q4odSaeWfk1Dr7L9Ua69oK9omjbCNUt+P7Kwlfca7Q==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2026-02-25T00:28:13Z"
|
lastmodified: "2025-04-24T23:16:22Z"
|
||||||
mac: ENC[AES256_GCM,data:hDmqObrtfoVkQqz8JPkqlyXMbiuyBophjdZNLvTFrZw3pAVNCuzsH4zxFBOaxJttkzLc65DWDHDeEIBY5YZam1GLFFXUQ5E3Dxno7hnyzOoM2ipgDTOacI0gbKJAWgGUF3LNDdqVoREA9LC91LoNUJoNmzpTSFtuLb7ORuwCrH4=,iv:8+W3n1Cr6woEiPU9ECaMYM64HNmFHr2AIw6UohCJi00=,tag:7drkZiPAUHaEx5PagXA9JQ==,type:str]
|
mac: ENC[AES256_GCM,data:NY9uhBwukENyny0lSnYDrdRDlAm5o0kGBs8Tes4x3/dofWibl9HqHobilg4qrLFzwCgQsgyPAFoRKV7ZVQ25YHjXM4YnoFVmUASfyTfoejWet/J3HwOO1xNkX8N6iYWJRYHOWaKMm46ZvkjmqAB0N6L7Z/8Uk7b09HoAxJ3aVHA=,iv:kI3kv0e9kcc8cb4H+YCnQYs7qDbucQYo264lz4zR/2E=,tag:ELqxtawXwhEPBncDz3REVA==,type:str]
|
||||||
|
pgp: []
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.11.0
|
version: 3.9.4
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
programs.adb.enable = true;
|
|
||||||
users.users.drew.extraGroups = [ "adbusers" ];
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
# RealtimeKit hands out realtime scheduling priority to user processes on
|
|
||||||
# demand, e.g. audio
|
|
||||||
security.rtkit.enable = true;
|
|
||||||
|
|
||||||
# Enable sound with pipewire.
|
|
||||||
services.pulseaudio = {
|
|
||||||
enable = false;
|
|
||||||
daemon.config = {
|
|
||||||
exit-idle-time = -1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
services.pipewire = {
|
|
||||||
enable = true;
|
|
||||||
alsa.enable = true;
|
|
||||||
alsa.support32Bit = true;
|
|
||||||
pulse.enable = true;
|
|
||||||
# If you want to use JACK applications, uncomment this
|
|
||||||
#jack.enable = true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
virtualisation = {
|
|
||||||
docker = {
|
|
||||||
enable = true;
|
|
||||||
# rootless = {
|
|
||||||
# enable = true;
|
|
||||||
# setSocketVariable = true;
|
|
||||||
# };
|
|
||||||
};
|
|
||||||
|
|
||||||
# Do not use Podman in Wayland/Hyperland. It will crash the session. Very annoying.
|
|
||||||
# podman.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
hardware.nvidia-container-toolkit.enable = true;
|
|
||||||
|
|
||||||
home-manager.users.drew =
|
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
# Add the path to the docker socket to the environment.
|
|
||||||
programs.zsh.envExtra = ''
|
|
||||||
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
services.flatpak.enable = true;
|
|
||||||
|
|
||||||
systemd.services.flatpak-repo = {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
path = [ pkgs.flatpak ];
|
|
||||||
script = ''
|
|
||||||
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
{ config, lib, ... }:
|
|
||||||
{
|
|
||||||
options =
|
|
||||||
with lib;
|
|
||||||
with types;
|
|
||||||
{
|
|
||||||
graphics = {
|
|
||||||
enable = mkEnableOption "graphics support";
|
|
||||||
driverChannel = mkOption {
|
|
||||||
type = str;
|
|
||||||
# Default to production because I often want new features, but I don't want bleeding edge.
|
|
||||||
default = "production";
|
|
||||||
description = "Driver channel to use (in order of oldest to newest): stable, beta, latest";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf config.graphics.enable {
|
|
||||||
# Graphics settings
|
|
||||||
hardware.graphics = {
|
|
||||||
enable = true;
|
|
||||||
enable32Bit = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.xserver.videoDrivers = [ "nvidia" ];
|
|
||||||
|
|
||||||
hardware.nvidia = {
|
|
||||||
package = config.boot.kernelPackages.nvidiaPackages."${config.graphics.driverChannel}";
|
|
||||||
|
|
||||||
modesetting.enable = true;
|
|
||||||
|
|
||||||
# Nvidia power management. Experimental, and can cause sleep/suspend to fail.
|
|
||||||
# Enable this if you have graphical corruption issues or application crashes after waking
|
|
||||||
# up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
|
|
||||||
# of just the bare essentials.
|
|
||||||
powerManagement.enable = true;
|
|
||||||
|
|
||||||
# Fine-grained power management for PRIME. Turns off GPU when not in use.
|
|
||||||
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
|
|
||||||
# Requires offload to be enabled.
|
|
||||||
# powerManagement.finegrained = false;
|
|
||||||
|
|
||||||
# Use the open-source driver?
|
|
||||||
open = false;
|
|
||||||
|
|
||||||
# Enable the nvidia-settings menu?
|
|
||||||
nvidiaSettings = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -26,12 +26,4 @@
|
|||||||
xwayland.enable = true;
|
xwayland.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.sway = {
|
|
||||||
enable = true;
|
|
||||||
xwayland.enable = true;
|
|
||||||
wrapperFeatures = {
|
|
||||||
gtk = true;
|
|
||||||
base = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
services.printing = {
|
|
||||||
enable = true;
|
|
||||||
drivers = [ pkgs.brlaser ];
|
|
||||||
};
|
|
||||||
hardware.printers = {
|
|
||||||
ensurePrinters = [
|
|
||||||
{
|
|
||||||
name = "Brother_HL-L2370DW_series";
|
|
||||||
location = "Home";
|
|
||||||
deviceUri = "dnssd://Brother%20HL-L2370DW%20series._ipp._tcp.local/?uuid=e3248000-80ce-11db-8000-3c2af4f28c38";
|
|
||||||
model = "drv:///brlaser.drv/brl2370d.ppd";
|
|
||||||
ppdOptions = {
|
|
||||||
PageSize = "Letter";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
ensureDefaultPrinter = "Brother_HL-L2370DW_series";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
{ config, lib, ... }:
|
|
||||||
{
|
|
||||||
options =
|
|
||||||
with lib;
|
|
||||||
with types;
|
|
||||||
{
|
|
||||||
virtualisation.web-containers = {
|
|
||||||
enable = mkEnableOption "web containers";
|
|
||||||
containers = mkOption {
|
|
||||||
type = lazyAttrsOf (submodule {
|
|
||||||
options =
|
|
||||||
let
|
|
||||||
strOpt = mkOption { type = str; };
|
|
||||||
intOpt = mkOption { type = int; };
|
|
||||||
boolOpt = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
strList = mkOption {
|
|
||||||
type = listOf str;
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
attrOpt = mkOption {
|
|
||||||
type = attrsOf str;
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
image = strOpt;
|
|
||||||
hostname = strOpt;
|
|
||||||
port = intOpt;
|
|
||||||
homepageOpts = attrOpt;
|
|
||||||
dependsOn = strList;
|
|
||||||
domain = strOpt;
|
|
||||||
volumes = strList;
|
|
||||||
environment = attrOpt;
|
|
||||||
environmentFiles = strList;
|
|
||||||
public = boolOpt;
|
|
||||||
user = mkOption {
|
|
||||||
type = nullOr str;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
extraOptions = strList;
|
|
||||||
oauthProxy = boolOpt;
|
|
||||||
extraLabels = attrOpt;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
default = { };
|
|
||||||
description = "";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
virtualisation.oci-containers.containers = lib.mkIf config.virtualisation.web-containers.enable (
|
|
||||||
let
|
|
||||||
hostRule = host: domain: "Host(`${host}.${domain}`)";
|
|
||||||
localNet = "192.168.0.0/16";
|
|
||||||
dockerNet = "10.88.0.0/16";
|
|
||||||
localNetRule = "(ClientIP(`${localNet}`) || ClientIP(`${dockerNet}`))";
|
|
||||||
localHostRule = host: domain: "${localNetRule} && ${hostRule host domain}";
|
|
||||||
mkContainer =
|
|
||||||
key:
|
|
||||||
{
|
|
||||||
image,
|
|
||||||
hostname,
|
|
||||||
port,
|
|
||||||
homepageOpts,
|
|
||||||
dependsOn,
|
|
||||||
domain,
|
|
||||||
volumes,
|
|
||||||
environment,
|
|
||||||
environmentFiles,
|
|
||||||
public,
|
|
||||||
user,
|
|
||||||
extraOptions,
|
|
||||||
oauthProxy,
|
|
||||||
extraLabels,
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
fqn = "${hostname}.${domain}";
|
|
||||||
serviceName = builtins.replaceStrings [ "." ] [ "-" ] fqn;
|
|
||||||
routerRule = if public then hostRule hostname domain else localHostRule hostname domain;
|
|
||||||
homepageLabels =
|
|
||||||
if homepageOpts == { } then
|
|
||||||
{ }
|
|
||||||
else
|
|
||||||
{
|
|
||||||
"homepage.group" = "${homepageOpts.group}";
|
|
||||||
"homepage.name" = "${homepageOpts.name}";
|
|
||||||
"homepage.icon" = "${homepageOpts.icon}";
|
|
||||||
"homepage.href" = "https://${fqn}";
|
|
||||||
"homepage.description" = "${homepageOpts.description}";
|
|
||||||
};
|
|
||||||
oauthLabels =
|
|
||||||
if oauthProxy then
|
|
||||||
{ "traefik.http.routers.${serviceName}.middlewares" = "oidc-auth@file"; }
|
|
||||||
else
|
|
||||||
{ };
|
|
||||||
in
|
|
||||||
{
|
|
||||||
inherit
|
|
||||||
image
|
|
||||||
dependsOn
|
|
||||||
volumes
|
|
||||||
environment
|
|
||||||
environmentFiles
|
|
||||||
user
|
|
||||||
extraOptions
|
|
||||||
;
|
|
||||||
autoStart = true;
|
|
||||||
labels = {
|
|
||||||
"traefik.enable" = "true";
|
|
||||||
"traefik.http.routers.${serviceName}.rule" = "${routerRule}";
|
|
||||||
"traefik.http.routers.${serviceName}.service" = "${serviceName}";
|
|
||||||
"traefik.http.routers.${serviceName}.entrypoints" = "web,websecure";
|
|
||||||
"traefik.http.services.${serviceName}.loadbalancer.server.port" = "${toString port}";
|
|
||||||
}
|
|
||||||
// oauthLabels
|
|
||||||
// homepageLabels
|
|
||||||
// extraLabels;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
builtins.mapAttrs mkContainer config.virtualisation.web-containers.containers
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -8,6 +8,10 @@
|
|||||||
}:
|
}:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
imports = [
|
||||||
|
./qmk.nix
|
||||||
|
];
|
||||||
|
|
||||||
networking.hostName = "altair"; # Define your hostname.
|
networking.hostName = "altair"; # Define your hostname.
|
||||||
|
|
||||||
# Configure network proxy if necessary
|
# Configure network proxy if necessary
|
||||||
@@ -88,6 +92,11 @@
|
|||||||
# Enable touchpad support (enabled default in most desktopManager).
|
# Enable touchpad support (enabled default in most desktopManager).
|
||||||
# services.xserver.libinput.enable = true;
|
# services.xserver.libinput.enable = true;
|
||||||
|
|
||||||
|
# Allow unfree packages
|
||||||
|
nixpkgs.config = {
|
||||||
|
allowUnfree = true;
|
||||||
|
};
|
||||||
|
|
||||||
# List packages installed in system profile. To search, run:
|
# List packages installed in system profile. To search, run:
|
||||||
# $ nix search wget
|
# $ nix search wget
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
|
|||||||
@@ -3,14 +3,9 @@
|
|||||||
imports = [
|
imports = [
|
||||||
./configuration.nix
|
./configuration.nix
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
./qmk.nix
|
|
||||||
../../authorized-keys.nix
|
../../authorized-keys.nix
|
||||||
../../features/audio.nix
|
|
||||||
../../features/gc.nix
|
../../features/gc.nix
|
||||||
../../features/gui.nix
|
../../features/gui.nix
|
||||||
../../features/container-dev.nix
|
|
||||||
../../features/android-dev.nix
|
|
||||||
../../features/flatpak.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|||||||
@@ -8,31 +8,17 @@ in
|
|||||||
{
|
{
|
||||||
imports =
|
imports =
|
||||||
map (x: ../../../home-manager + x) [
|
map (x: ../../../home-manager + x) [
|
||||||
"/features/astronomy.nix"
|
|
||||||
"/features/chat.nix"
|
|
||||||
"/features/development/development.nix"
|
"/features/development/development.nix"
|
||||||
"/features/development/docker.nix"
|
|
||||||
"/features/development/haskell.nix"
|
"/features/development/haskell.nix"
|
||||||
"/features/development/markdown.nix"
|
|
||||||
"/features/development/typescript.nix"
|
|
||||||
"/features/development/vscode.nix"
|
|
||||||
"/features/eww"
|
|
||||||
"/features/gaming.nix"
|
"/features/gaming.nix"
|
||||||
"/features/image-editing.nix"
|
|
||||||
"/features/linux-desktop.nix"
|
"/features/linux-desktop.nix"
|
||||||
"/features/notes.nix"
|
"/features/notes.nix"
|
||||||
"/features/3d-printing.nix"
|
"/features/eww"
|
||||||
]
|
]
|
||||||
++ [
|
++ [
|
||||||
(import ../../../home-manager/features/wallpaper.nix monitors)
|
(import ../../../home-manager/features/wallpaper.nix monitors)
|
||||||
];
|
];
|
||||||
|
|
||||||
# This config file is needed for nix shell to allow unfree programs. I'm not
|
|
||||||
# sure why this isn't a home-manager option.
|
|
||||||
home.file.".config/nixpkgs/config.nix".text = ''
|
|
||||||
{ allowUnfree = true; }
|
|
||||||
'';
|
|
||||||
|
|
||||||
home.stateVersion = "24.11";
|
home.stateVersion = "24.11";
|
||||||
|
|
||||||
home.username = "drew";
|
home.username = "drew";
|
||||||
@@ -43,16 +29,9 @@ in
|
|||||||
userEmail = "drew.haven@gmail.com";
|
userEmail = "drew.haven@gmail.com";
|
||||||
};
|
};
|
||||||
|
|
||||||
wayland.windowManager.hyprland.settings = {
|
# Set up eww here because it's based on the monitor configuration
|
||||||
exec-once = [
|
# Eww is idempotent, so it's fine to just run it on every reload to make sure things are open
|
||||||
# Set up eww here because it's based on the monitor configuration
|
wayland.windowManager.hyprland.settings.exec = [
|
||||||
"sleep 2 && eww open-many primary-statusbar secondary-statusbar"
|
"eww open-many primary-statusbar secondary-statusbar launcher"
|
||||||
# Set DP-2 as the primary monitor, otherwise it defaults to DP-1 because it's first in the list.
|
];
|
||||||
"xrandr --output DP-2 --primary"
|
|
||||||
];
|
|
||||||
windowrulev2 = [
|
|
||||||
# Rofi doesn't center properly when I have the two asymetric monitors, so we need hyprland to manage it.
|
|
||||||
"center, class:Rofi"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,46 +13,38 @@
|
|||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
];
|
];
|
||||||
# Bootloader.
|
# Bootloader.
|
||||||
boot = {
|
boot.loader.systemd-boot.enable = true;
|
||||||
loader = {
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
systemd-boot.enable = true;
|
|
||||||
efi.canTouchEfiVariables = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
initrd = {
|
boot.initrd.availableKernelModules = [
|
||||||
availableKernelModules = [
|
"xhci_pci"
|
||||||
"xhci_pci"
|
"ahci"
|
||||||
"ahci"
|
"nvme"
|
||||||
"nvme"
|
"usbhid"
|
||||||
"usbhid"
|
"usb_storage"
|
||||||
"usb_storage"
|
"sd_mod"
|
||||||
"sd_mod"
|
];
|
||||||
];
|
boot.initrd.kernelModules = [ ];
|
||||||
kernelModules = [ ];
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
};
|
boot.extraModulePackages = [ ];
|
||||||
kernelModules = [ "kvm-intel" ];
|
|
||||||
extraModulePackages = [ ];
|
fileSystems."/" = {
|
||||||
|
device = "/dev/disk/by-uuid/343c0ac5-3973-49b3-964a-6ad90c36b89c";
|
||||||
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems = {
|
fileSystems."/boot" = {
|
||||||
"/" = {
|
device = "/dev/disk/by-uuid/5F99-043D";
|
||||||
device = "/dev/disk/by-uuid/343c0ac5-3973-49b3-964a-6ad90c36b89c";
|
fsType = "vfat";
|
||||||
fsType = "ext4";
|
options = [
|
||||||
};
|
"fmask=0077"
|
||||||
|
"dmask=0077"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
"/boot" = {
|
fileSystems."/home" = {
|
||||||
device = "/dev/disk/by-uuid/5F99-043D";
|
device = "/dev/disk/by-uuid/28f4fb41-9414-4504-a767-c2e8bf5eb2c8";
|
||||||
fsType = "vfat";
|
fsType = "ext4";
|
||||||
options = [
|
|
||||||
"fmask=0077"
|
|
||||||
"dmask=0077"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
"/home" = {
|
|
||||||
device = "/dev/disk/by-uuid/28f4fb41-9414-4504-a767-c2e8bf5eb2c8";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices = [ ];
|
swapDevices = [ ];
|
||||||
@@ -66,47 +58,37 @@
|
|||||||
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
|
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
|
||||||
|
# Graphics settings
|
||||||
|
hardware.graphics = {
|
||||||
|
enable = true;
|
||||||
|
enable32Bit = true;
|
||||||
|
};
|
||||||
|
|
||||||
services.xserver.videoDrivers = [ "nvidia" ];
|
services.xserver.videoDrivers = [ "nvidia" ];
|
||||||
|
|
||||||
hardware = {
|
hardware.nvidia = {
|
||||||
cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
package = config.boot.kernelPackages.nvidiaPackages.beta;
|
||||||
graphics = {
|
|
||||||
enable = true;
|
|
||||||
enable32Bit = true;
|
|
||||||
};
|
|
||||||
nvidia = {
|
|
||||||
# Other options include:
|
|
||||||
# stable - Current stable
|
|
||||||
# production - Same as stable
|
|
||||||
# latest - Bleeding edge
|
|
||||||
# beta - latest beta
|
|
||||||
#
|
|
||||||
# See https://nixos.wiki/wiki/Nvidia
|
|
||||||
#
|
|
||||||
# Current versions can be found in https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/os-specific/linux/nvidia-x11/default.nix
|
|
||||||
#
|
|
||||||
package = config.boot.kernelPackages.nvidiaPackages.beta;
|
|
||||||
|
|
||||||
modesetting.enable = true;
|
modesetting.enable = true;
|
||||||
|
|
||||||
# Nvidia power management. Experimental, and can cause sleep/suspend to fail.
|
# Nvidia power management. Experimental, and can cause sleep/suspend to fail.
|
||||||
# Enable this if you have graphical corruption issues or application crashes after waking
|
# Enable this if you have graphical corruption issues or application crashes after waking
|
||||||
# up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
|
# up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
|
||||||
# of just the bare essentials.
|
# of just the bare essentials.
|
||||||
powerManagement.enable = true;
|
powerManagement.enable = true;
|
||||||
|
|
||||||
# Fine-grained power management for PRIME. Turns off GPU when not in use.
|
# Fine-grained power management for PRIME. Turns off GPU when not in use.
|
||||||
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
|
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
|
||||||
# Requires offload to be enabled.
|
# Requires offload to be enabled.
|
||||||
# powerManagement.finegrained = false;
|
# powerManagement.finegrained = false;
|
||||||
|
|
||||||
# Use the open-source driver?
|
# Use the open-source driver?
|
||||||
open = false;
|
open = false;
|
||||||
|
|
||||||
# Enable the nvidia-settings menu?
|
# Enable the nvidia-settings menu?
|
||||||
nvidiaSettings = true;
|
nvidiaSettings = true;
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Add a udev rule to prevent the mouse from waking the system. Note that it
|
# Add a udev rule to prevent the mouse from waking the system. Note that it
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./vars.nix
|
./vars.nix
|
||||||
@@ -16,6 +16,9 @@
|
|||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.systemd-boot.enable = true;
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
# Set the kernel to be compatible with ZFS
|
||||||
|
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
|
||||||
|
|
||||||
networking.hostName = "mcp"; # Define your hostname.
|
networking.hostName = "mcp"; # Define your hostname.
|
||||||
networking.hostId = "5e292f2d"; # Define a host ID for ZFS with `head -c 8 /etc/machine-id`
|
networking.hostId = "5e292f2d"; # Define a host ID for ZFS with `head -c 8 /etc/machine-id`
|
||||||
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
|
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
|
||||||
@@ -59,7 +62,6 @@
|
|||||||
"networkmanager"
|
"networkmanager"
|
||||||
"wheel"
|
"wheel"
|
||||||
"docker-registry"
|
"docker-registry"
|
||||||
"docker"
|
|
||||||
];
|
];
|
||||||
shell = pkgs.zsh;
|
shell = pkgs.zsh;
|
||||||
# Enable linger so that systemd services run for this user are started and
|
# Enable linger so that systemd services run for this user are started and
|
||||||
@@ -94,8 +96,7 @@
|
|||||||
port = 5000;
|
port = 5000;
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
# Bind to the podman network so Traefik can route to it.
|
# Bind to the podman network so Traefik can route to it.
|
||||||
# Note that it may fail to start if this network has not been created yet,
|
# Note that it may fail to start if this network has not been created yet.
|
||||||
# so this has to be manually restarted when the system boots.
|
|
||||||
listenAddress = "10.88.0.1";
|
listenAddress = "10.88.0.1";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,10 +107,8 @@
|
|||||||
enabledCollectors = [ "systemd" ];
|
enabledCollectors = [ "systemd" ];
|
||||||
port = 9002;
|
port = 9002;
|
||||||
# Open the firewall, but only listen on the internal address
|
# Open the firewall, but only listen on the internal address
|
||||||
|
# TODO: Add some form authentication
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
# Bind to the podman network so Traefik can route to it.
|
|
||||||
# Note that it may fail to start if this network has not been created yet,
|
|
||||||
# so this has to be manually restarted when the system boots.
|
|
||||||
listenAddress = "10.88.0.1";
|
listenAddress = "10.88.0.1";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,183 +1,333 @@
|
|||||||
{
|
# Started from https://nixos.wiki/wiki/Podman
|
||||||
config,
|
{ config, pkgs, ... }:
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
{
|
||||||
# Additional configuration
|
# Additional configuration
|
||||||
imports = [
|
imports = [
|
||||||
./containers/havenisms.com
|
./containers/bookstack.nix
|
||||||
./containers/blazestar.net
|
./containers/focalboard.nix
|
||||||
|
|
||||||
# Docker containers
|
|
||||||
./containers/dm-companion.nix
|
|
||||||
./containers/freshrss.nix
|
|
||||||
./containers/gitea.nix
|
./containers/gitea.nix
|
||||||
./containers/goatcounter.nix
|
|
||||||
./containers/grafana.nix
|
./containers/grafana.nix
|
||||||
# ./containers/jobhunt.nix
|
./containers/jobhunt.nix
|
||||||
./containers/mariadb.nix
|
./containers/mariadb.nix
|
||||||
./containers/media-system.nix
|
|
||||||
./containers/nextcloud.nix
|
./containers/nextcloud.nix
|
||||||
# ./containers/offen.nix
|
./containers/offen.nix
|
||||||
./containers/pocket-id.nix
|
./containers/pocket-id.nix
|
||||||
./containers/prometheus.nix
|
./containers/prometheus.nix
|
||||||
./containers/public-homepage.nix
|
./containers/public-homepage.nix
|
||||||
./containers/searxng.nix
|
./containers/searxng.nix
|
||||||
./containers/shared-postgres.nix
|
./containers/shared-postgres.nix
|
||||||
# ./containers/timetagger.nix
|
./containers/synapse.nix
|
||||||
./containers/traefik.nix
|
./containers/traefik.nix
|
||||||
./containers/users.nix
|
./containers/users.nix
|
||||||
|
|
||||||
# NixOS Containers
|
|
||||||
./static-site-hooks.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
options.local = with lib; {
|
# Enable common container config files in /etc/containers
|
||||||
container-backend = mkOption {
|
virtualisation.containers.enable = true;
|
||||||
type = with types; uniq str;
|
virtualisation = {
|
||||||
default = "docker";
|
podman = {
|
||||||
example = "docker";
|
enable = true;
|
||||||
description = "Which backend to use for containers: docker or podman";
|
|
||||||
};
|
# Create a `docker` alias for podman, to use it as a drop-in replacement
|
||||||
container-socket = mkOption {
|
dockerCompat = true;
|
||||||
type = with types; uniq str;
|
|
||||||
default = "/var/run/docker.sock";
|
# Required for containers under podman-compose to be able to talk to each other.
|
||||||
example = "/var/run/docker.sock";
|
defaultNetwork.settings.dns_enabled = true;
|
||||||
description = "Path to the container management deamon's socket.";
|
|
||||||
|
extraPackages = [ pkgs.zfs ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
# Useful other development tools
|
||||||
# local = {
|
environment.systemPackages = with pkgs; [
|
||||||
# container-backend = "docker";
|
dive # look into docker image layers
|
||||||
# container-socket = "/var/run/docker.sock";
|
podman-tui # status of containers in the terminal
|
||||||
# };
|
docker-compose # start group of containers for dev
|
||||||
local = {
|
#podman-compose # start group of containers for dev
|
||||||
container-backend = "podman";
|
];
|
||||||
container-socket = "/var/run/podman/podman.sock";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Enable common container config files in /etc/containers
|
virtualisation.oci-containers.backend = "podman";
|
||||||
|
virtualisation.oci-containers.containers =
|
||||||
virtualisation = {
|
let
|
||||||
containers.enable = true;
|
inherit (import ./containers/lib.nix config)
|
||||||
oci-containers.backend = config.local.container-backend;
|
hostRuleHavenisms
|
||||||
|
localHostRuleHavenisms
|
||||||
docker = lib.mkIf (config.local.container-backend == "docker") {
|
havenisms;
|
||||||
enable = true;
|
in
|
||||||
# Enable rootless so that I can run containers as other users for security.
|
{
|
||||||
rootless = {
|
jellyfin = {
|
||||||
enable = true;
|
image = "lscr.io/linuxserver/jellyfin";
|
||||||
# Set this to make the default DOCKER_HOST be the rootless version for normal users.
|
autoStart = true;
|
||||||
setSocketVariable = true;
|
extraOptions = [
|
||||||
daemon = {
|
"--device=/dev/dri:/dev/dri"
|
||||||
settings = {
|
"-l=traefik.enable=true"
|
||||||
default-address-pools = [
|
"-l=traefik.http.routers.jellyfin.rule=${hostRuleHavenisms "jellyfin"}"
|
||||||
{
|
"-l=traefik.http.services.jellyfin.loadbalancer.server.port=8096"
|
||||||
base = "10.88.0.0/16";
|
"-l=homepage.group=Apps"
|
||||||
size = 24;
|
"-l=homepage.name=Jellyfin"
|
||||||
}
|
"-l=homepage.icon=jellyfin.svg"
|
||||||
];
|
"-l=homepage.href=https://jellyfin.${havenisms}"
|
||||||
};
|
"-l=homepage.description=Media player"
|
||||||
};
|
"-l=homepage.widget.type=jellyfin"
|
||||||
};
|
"-l=homepage.widget.key={{HOMEPAGE_FILE_JELLYFIN_KEY}}"
|
||||||
daemon = {
|
"-l=homepage.widget.url=http://jellyfin:8096"
|
||||||
settings = {
|
"-l=homepage.widget.enableBlocks=true"
|
||||||
default-address-pools = [
|
];
|
||||||
{
|
volumes = [
|
||||||
base = "10.88.0.0/16";
|
"/tank/media/collection:/data"
|
||||||
size = 24;
|
"/tank/config/jellyfin:/config"
|
||||||
}
|
];
|
||||||
];
|
# environment = {
|
||||||
};
|
# TZ = vars.timeZone;
|
||||||
|
# PUID = "994";
|
||||||
|
# UMASK = "002";
|
||||||
|
# GUID = "993";
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
deluge = {
|
||||||
|
image = "linuxserver/deluge:latest";
|
||||||
|
autoStart = true;
|
||||||
|
dependsOn = [
|
||||||
|
"gluetun"
|
||||||
|
];
|
||||||
|
extraOptions = [
|
||||||
|
"--network=container:gluetun"
|
||||||
|
"-l=homepage.group=Arr"
|
||||||
|
"-l=homepage.name=Deluge"
|
||||||
|
"-l=homepage.icon=deluge.svg"
|
||||||
|
"-l=homepage.href=https://deluge.${havenisms}"
|
||||||
|
"-l=homepage.description=Torrent client"
|
||||||
|
"-l=homepage.widget.type=deluge"
|
||||||
|
"-l=homepage.widget.password={{HOMEPAGE_FILE_DELUGE_PASSWORD}}"
|
||||||
|
"-l=homepage.widget.url=http://gluetun:8112"
|
||||||
|
];
|
||||||
|
volumes = [
|
||||||
|
"/tank/media:/data"
|
||||||
|
"/tank/config/deluge:/config"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
qbittorrent = {
|
||||||
|
image = "linuxserver/qbittorrent:latest";
|
||||||
|
autoStart = true;
|
||||||
|
dependsOn = [
|
||||||
|
"gluetun"
|
||||||
|
];
|
||||||
|
extraOptions = [
|
||||||
|
"--network=container:gluetun"
|
||||||
|
"-l=homepage.group=Arr"
|
||||||
|
"-l=homepage.name=qBitTorrent"
|
||||||
|
"-l=homepage.icon=qbittorrent.svg"
|
||||||
|
"-l=homepage.href=https://torrents.${havenisms}"
|
||||||
|
"-l=homepage.description=Torrent client"
|
||||||
|
"-l=homepage.widget.type=qbittorrent"
|
||||||
|
"-l=homepage.widget.url=http://torrents.${havenisms}"
|
||||||
|
];
|
||||||
|
volumes = [
|
||||||
|
"/tank/media/Downloads:/downloads"
|
||||||
|
"/tank/config/qbittorrent:/config"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
PUID = "911";
|
||||||
|
PGID = "911";
|
||||||
|
UMASK = "002";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
podman = lib.mkIf (config.local.container-backend == "podman") {
|
gluetun = {
|
||||||
enable = true;
|
image = "qmcgaw/gluetun:latest";
|
||||||
|
autoStart = true;
|
||||||
# Create a `docker` alias for podman, to use it as a drop-in replacement
|
extraOptions = [
|
||||||
dockerCompat = true;
|
# add network admin capability.
|
||||||
|
"--cap-add=NET_ADMIN"
|
||||||
# Required for containers under podman-compose to be able to talk to each other.
|
"--device=/dev/net/tun:/dev/net/tun"
|
||||||
defaultNetwork.settings.dns_enabled = true;
|
"-l=traefik.enable=true"
|
||||||
|
"-l=traefik.http.routers.torrents.rule=${localHostRuleHavenisms "torrents"}"
|
||||||
extraPackages = [ pkgs.zfs ];
|
"-l=traefik.http.routers.torrents.service=torrents"
|
||||||
|
"-l=traefik.http.services.torrents.loadbalancer.server.port=8080"
|
||||||
|
"-l=homepage.group=Infra"
|
||||||
|
"-l=homepage.name=GlueTun"
|
||||||
|
"-l=homepage.icon=gluetun.svg"
|
||||||
|
"-l=homepage.href=https://torrents.${havenisms}"
|
||||||
|
"-l=homepage.description=VPN killswitch"
|
||||||
|
"-l=homepage.widget.type=gluetun"
|
||||||
|
"-l=homepage.widget.url=http://gluetun:8000"
|
||||||
|
];
|
||||||
|
ports = [
|
||||||
|
"127.0.0.1:8083:8000"
|
||||||
|
];
|
||||||
|
environmentFiles = [
|
||||||
|
"/tank/config/gluetun/vpn.env"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
VPN_SERVICE_PROVIDER = "protonvpn";
|
||||||
|
UMASK = "002";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
prowlarr = {
|
||||||
|
image = "lscr.io/linuxserver/prowlarr";
|
||||||
|
autoStart = true;
|
||||||
|
extraOptions = [
|
||||||
|
"-l=traefik.enable=true"
|
||||||
|
"-l=traefik.http.routers.prowlarr.rule=${localHostRuleHavenisms "prowlarr"}"
|
||||||
|
"-l=traefik.http.services.prowlarr.loadbalancer.server.port=9696"
|
||||||
|
"-l=homepage.group=Arr"
|
||||||
|
"-l=homepage.name=Prowlarr"
|
||||||
|
"-l=homepage.icon=prowlarr.svg"
|
||||||
|
"-l=homepage.href=https://prowlarr.${havenisms}"
|
||||||
|
"-l=homepage.description=Torrent indexer"
|
||||||
|
];
|
||||||
|
volumes = [
|
||||||
|
"/tank/config/prowlarr:/config"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
UMASK = "002";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# Currently broken and doesn't work. :(
|
||||||
|
# flaresolverr = {
|
||||||
|
# image = "ghcr.io/flaresolverr/flaresolverr:latest";
|
||||||
|
# autoStart = true;
|
||||||
|
# extraOptions = [
|
||||||
|
# "-l=homepage.group=Infra"
|
||||||
|
# "-l=homepage.name=FlareSolverr"
|
||||||
|
# "-l=homepage.icon=flaresolverr.svg"
|
||||||
|
# "-l=homepage.href=https://flaresolverr.${domain}"
|
||||||
|
# "-l=homepage.description=Cloudflare bypass"
|
||||||
|
# ];
|
||||||
|
# volumes = [
|
||||||
|
# "/tank/config/flaresolverr:/config"
|
||||||
|
# ];
|
||||||
|
# environment = {
|
||||||
|
# UMASK = "002";
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
radarr = {
|
||||||
|
image = "lscr.io/linuxserver/radarr";
|
||||||
|
autoStart = true;
|
||||||
|
extraOptions = [
|
||||||
|
"-l=traefik.enable=true"
|
||||||
|
"-l=traefik.http.routers.radarr.rule=${localHostRuleHavenisms "radarr"}"
|
||||||
|
"-l=traefik.http.services.radarr.loadbalancer.server.port=7878"
|
||||||
|
"-l=homepage.group=Arr"
|
||||||
|
"-l=homepage.name=Radarr"
|
||||||
|
"-l=homepage.icon=radarr.svg"
|
||||||
|
"-l=homepage.href=https://radarr.${havenisms}"
|
||||||
|
"-l=homepage.description=Movie acquisition"
|
||||||
|
"-l=homepage.widget.type=radarr"
|
||||||
|
"-l=homepage.widget.url=http://radarr:7878"
|
||||||
|
"-l=homepage.widget.key={{HOMEPAGE_FILE_RADARR_KEY}}"
|
||||||
|
];
|
||||||
|
volumes = [
|
||||||
|
"/tank/media:/data"
|
||||||
|
"/tank/config/radarr:/config"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
UMASK = "002";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
sonarr = {
|
||||||
|
image = "lscr.io/linuxserver/sonarr";
|
||||||
|
autoStart = true;
|
||||||
|
extraOptions = [
|
||||||
|
"-l=traefik.enable=true"
|
||||||
|
"-l=traefik.http.routers.sonarr.rule=${localHostRuleHavenisms "sonarr"}"
|
||||||
|
"-l=traefik.http.services.sonarr.loadbalancer.server.port=8989"
|
||||||
|
"-l=homepage.group=Arr"
|
||||||
|
"-l=homepage.name=Sonarr"
|
||||||
|
"-l=homepage.icon=sonarr.svg"
|
||||||
|
"-l=homepage.href=https://sonarr.${havenisms}"
|
||||||
|
"-l=homepage.description=Show acquisition"
|
||||||
|
"-l=homepage.widget.type=sonarr"
|
||||||
|
"-l=homepage.widget.url=http://sonarr:8989"
|
||||||
|
"-l=homepage.widget.key={{HOMEPAGE_FILE_SONARR_KEY}}"
|
||||||
|
];
|
||||||
|
volumes = [
|
||||||
|
"/tank/media:/data"
|
||||||
|
"/tank/config/sonarr:/config"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
UMASK = "002";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
readarr = {
|
||||||
|
# The Linuxserver version of this image doesn't have a latest tag. Odd.
|
||||||
|
image = "lscr.io/linuxserver/readarr:develop";
|
||||||
|
autoStart = true;
|
||||||
|
extraOptions = [
|
||||||
|
"-l=traefik.enable=true"
|
||||||
|
"-l=traefik.http.routers.readarr.rule=${localHostRuleHavenisms "readarr"}"
|
||||||
|
"-l=traefik.http.services.readarr.loadbalancer.server.port=8787"
|
||||||
|
"-l=homepage.group=Arr"
|
||||||
|
"-l=homepage.name=Readarr"
|
||||||
|
"-l=homepage.icon=readarr.svg"
|
||||||
|
"-l=homepage.href=https://readarr.${havenisms}"
|
||||||
|
"-l=homepage.description=E-book acquisition"
|
||||||
|
"-l=homepage.widget.type=readarr"
|
||||||
|
"-l=homepage.widget.url=http://readarr.havenisms.com:8787"
|
||||||
|
"-l=homepage.widget.key={{HOMEPAGE_FILE_READARR_KEY}}"
|
||||||
|
];
|
||||||
|
volumes = [
|
||||||
|
"/tank/media:/data"
|
||||||
|
"/tank/config/readarr:/config"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
UMASK = "002";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
homepage = {
|
||||||
|
image = "ghcr.io/gethomepage/homepage:latest";
|
||||||
|
autoStart = true;
|
||||||
|
extraOptions = [
|
||||||
|
"-l=traefik.enable=true"
|
||||||
|
"-l=traefik.http.routers.homepage.rule=${localHostRuleHavenisms "start"}"
|
||||||
|
"-l=traefik.http.services.homepage.loadbalancer.server.port=3000"
|
||||||
|
];
|
||||||
|
volumes = [
|
||||||
|
"/tank/config/homepage:/app/config"
|
||||||
|
"/tank/secrets/deluge.pass:/app/config/secrets/deluge.pass"
|
||||||
|
"/tank/secrets/jellyfin.key:/app/config/secrets/jellyfin.key"
|
||||||
|
"/tank/secrets/radarr.key:/app/config/secrets/radarr.key"
|
||||||
|
"/tank/secrets/sonarr.key:/app/config/secrets/sonarr.key"
|
||||||
|
"/var/run/podman/podman.sock:/var/run/docker.sock:ro"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
HOMEPAGE_FILE_JELLYFIN_KEY = "/app/config/secrets/jellyfin.key";
|
||||||
|
HOMEPAGE_FILE_RADARR_KEY = "/app/config/secrets/radarr.key";
|
||||||
|
HOMEPAGE_FILE_SONARR_KEY = "/app/config/secrets/sonarr.key";
|
||||||
|
HOMEPAGE_FILE_READARR_KEY = "/app/config/secrets/readarr.key";
|
||||||
|
HOMEPAGE_FILE_DELUGE_PASSWORD = "/app/config/secrets/deluge.pass";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
scrutiny = {
|
||||||
|
image = "ghcr.io/analogj/scrutiny:master-omnibus";
|
||||||
|
autoStart = true;
|
||||||
|
extraOptions = [
|
||||||
|
"-l=traefik.enable=true"
|
||||||
|
"-l=traefik.http.routers.scrutiny.rule=${localHostRuleHavenisms "scrutiny"}"
|
||||||
|
"-l=traefik.http.services.scrutiny.loadbalancer.server.port=8080"
|
||||||
|
"-l=homepage.group=Infra"
|
||||||
|
"-l=homepage.name=Scrutiny"
|
||||||
|
"-l=homepage.icon=scrutiny-light.png"
|
||||||
|
"-l=homepage.href=https://scrutiny.${havenisms}"
|
||||||
|
"-l=homepage.description=S.M.A.R.T. monitoring"
|
||||||
|
"-l=homepage.widget.type=scrutiny"
|
||||||
|
"-l=homepage.widget.url=http://scrutiny:8080"
|
||||||
|
"--cap-add=SYS_RAWIO"
|
||||||
|
"--device=/dev/sda:/dev/sda"
|
||||||
|
"--device=/dev/sdb:/dev/sdb"
|
||||||
|
"--device=/dev/sdc:/dev/sdc"
|
||||||
|
"--device=/dev/sdd:/dev/sdd"
|
||||||
|
];
|
||||||
|
volumes = [
|
||||||
|
"/run/udev:/run/udev:ro"
|
||||||
|
"/tank/config/scrutiny/config:/opt/scrutiny/config"
|
||||||
|
"/tank/config/scrutiny/influxdb:/opt/scrutiny/influxdb"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
valkey = {
|
||||||
|
image = "docker.io/valkey/valkey:7-alpine";
|
||||||
|
autoStart = true;
|
||||||
|
volumes = [
|
||||||
|
"/tank/config/valkey:/usr/local/etc/valkey"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Useful other development tools
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
dive # look into docker image layers
|
|
||||||
docker-compose # start group of containers for dev
|
|
||||||
];
|
|
||||||
|
|
||||||
virtualisation.oci-containers.containers =
|
|
||||||
let
|
|
||||||
inherit (import ./containers/lib.nix config)
|
|
||||||
localHostRuleHavenisms
|
|
||||||
havenisms
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
homepage = {
|
|
||||||
image = "ghcr.io/gethomepage/homepage:latest";
|
|
||||||
autoStart = true;
|
|
||||||
extraOptions = [
|
|
||||||
"-l=traefik.enable=true"
|
|
||||||
"-l=traefik.http.routers.homepage.rule=${localHostRuleHavenisms "start"}"
|
|
||||||
"-l=traefik.http.services.homepage.loadbalancer.server.port=3000"
|
|
||||||
];
|
|
||||||
volumes = [
|
|
||||||
"/tank/config/homepage:/app/config"
|
|
||||||
"/tank/secrets/deluge.pass:/app/config/secrets/deluge.pass"
|
|
||||||
"/tank/secrets/jellyfin.key:/app/config/secrets/jellyfin.key"
|
|
||||||
"/tank/secrets/radarr.key:/app/config/secrets/radarr.key"
|
|
||||||
"/tank/secrets/sonarr.key:/app/config/secrets/sonarr.key"
|
|
||||||
"${config.local.container-socket}:/var/run/docker.sock:ro"
|
|
||||||
];
|
|
||||||
environment = {
|
|
||||||
HOMEPAGE_FILE_JELLYFIN_KEY = "/app/config/secrets/jellyfin.key";
|
|
||||||
HOMEPAGE_FILE_RADARR_KEY = "/app/config/secrets/radarr.key";
|
|
||||||
HOMEPAGE_FILE_SONARR_KEY = "/app/config/secrets/sonarr.key";
|
|
||||||
HOMEPAGE_FILE_READARR_KEY = "/app/config/secrets/readarr.key";
|
|
||||||
HOMEPAGE_FILE_DELUGE_PASSWORD = "/app/config/secrets/deluge.pass";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
scrutiny = {
|
|
||||||
image = "ghcr.io/analogj/scrutiny:master-omnibus";
|
|
||||||
autoStart = true;
|
|
||||||
extraOptions = [
|
|
||||||
"-l=traefik.enable=true"
|
|
||||||
"-l=traefik.http.routers.scrutiny.rule=${localHostRuleHavenisms "scrutiny"}"
|
|
||||||
"-l=traefik.http.services.scrutiny.loadbalancer.server.port=8080"
|
|
||||||
"-l=homepage.group=Infra"
|
|
||||||
"-l=homepage.name=Scrutiny"
|
|
||||||
"-l=homepage.icon=scrutiny-light.png"
|
|
||||||
"-l=homepage.href=https://scrutiny.${havenisms}"
|
|
||||||
"-l=homepage.description=S.M.A.R.T. monitoring"
|
|
||||||
"-l=homepage.widget.type=scrutiny"
|
|
||||||
"-l=homepage.widget.url=http://scrutiny:8080"
|
|
||||||
"--cap-add=SYS_RAWIO"
|
|
||||||
"--device=/dev/disk/by-id/wwn-0x5000cca26fca1aed:/dev/disk/by-id/wwn-0x5000cca26fca1aed"
|
|
||||||
"--device=/dev/disk/by-id/wwn-0x5000cca26fef696c:/dev/disk/by-id/wwm-0x5000cca26fef696c"
|
|
||||||
"--device=/dev/disk/by-id/wwn-0x5000cca270db1d0e:/dev/disk/by-id/wwn-0x5000cca270db1d0e"
|
|
||||||
# "--device=/dev/sdd:/dev/sdd" Removing this one while the disk is down
|
|
||||||
];
|
|
||||||
volumes = [
|
|
||||||
"/run/udev:/run/udev:ro"
|
|
||||||
"/tank/config/scrutiny/config:/opt/scrutiny/config"
|
|
||||||
"/tank/config/scrutiny/influxdb:/opt/scrutiny/influxdb"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
valkey = {
|
|
||||||
image = "docker.io/valkey/valkey:7-alpine";
|
|
||||||
autoStart = true;
|
|
||||||
volumes = [
|
|
||||||
"/tank/config/valkey:/usr/local/etc/valkey"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,104 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ../lib.nix config) mkContainer blazestar;
|
|
||||||
matrixHost = "matrix";
|
|
||||||
serviceName = "matrix-blazestar-net";
|
|
||||||
dbPath = "/var/lib/matrix";
|
|
||||||
port = 8448;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sops.secrets = {
|
|
||||||
"matrix/blazestar-registration-token" = {
|
|
||||||
restartUnits = [ "${config.local.container-backend}-matrix-blazestar-net.service" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.templates."matrix-blazestar-net.env".content = ''
|
|
||||||
TUWUNEL_REGISTRATION_TOKEN=${config.sops.placeholder."matrix/blazestar-registration-token"}
|
|
||||||
'';
|
|
||||||
|
|
||||||
# This isn't using any of my usual helpers because I wanted to set a custom
|
|
||||||
# serviceName in Traefik that is different from the hostname to avoid
|
|
||||||
# conflicts with the havenisms.com server.
|
|
||||||
virtualisation.oci-containers.containers."${serviceName}" = {
|
|
||||||
# The 1.1.0 version has an issue with the compression being incorrectly tagged.
|
|
||||||
# See: https://github.com/matrix-construct/tuwunel/issues/79
|
|
||||||
image = "ghcr.io/matrix-construct/tuwunel:v1.0.0-release-all-x86_64-linux-gnu";
|
|
||||||
autoStart = true;
|
|
||||||
volumes = [
|
|
||||||
"matrix-blazestar-net-db:${dbPath}"
|
|
||||||
];
|
|
||||||
environment = {
|
|
||||||
TUWUNEL_PORT = toString port;
|
|
||||||
TUWUNEL_ADDRESS = "0.0.0.0"; # It'll bind to localhost by default with Podman
|
|
||||||
TUWUNEL_SERVER_NAME = "blazestar.net";
|
|
||||||
TUWUNEL_ALLOW_REGISTRATION = "true";
|
|
||||||
TUWUNEL_ALLOW_CHECK_FOR_UPDATES = "true";
|
|
||||||
TUWUNEL_ALLOW_FEDERATION = "true";
|
|
||||||
TUWUNEL_DATABASE_BACKEND = "rocksdb";
|
|
||||||
TUWUNEL_DATABASE_PATH = dbPath;
|
|
||||||
TUWUNEL_WELL_KNOWN = ''
|
|
||||||
{
|
|
||||||
client=https://${matrixHost}.blazestar.net,
|
|
||||||
server=${matrixHost}.blazestar.net:443
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
TUWUNEL_TRUSTED_SERVERS = ''["matrix.org", "chat.havenisms.com"]'';
|
|
||||||
};
|
|
||||||
environmentFiles = [
|
|
||||||
config.sops.templates."matrix-blazestar-net.env".path
|
|
||||||
];
|
|
||||||
labels = {
|
|
||||||
"traefik.enable" = "true";
|
|
||||||
"traefik.http.routers.${serviceName}.rule" = "Host(`${matrixHost}.${blazestar}`)";
|
|
||||||
"traefik.http.services.${serviceName}.loadbalancer.server.port" = "${toString port}";
|
|
||||||
|
|
||||||
# Redirect well-known requests to this host.
|
|
||||||
"traefik.http.routers.${matrixHost}-blazestar-net-well-known.rule" =
|
|
||||||
"Host(`blazestar.net`) && PathPrefix(`/.well-known/matrix`)";
|
|
||||||
"traefik.http.routers.${matrixHost}-blazestar-net-well-known.service" = serviceName;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# virtualisation.oci-containers.containers.matrix-blazestar-net =
|
|
||||||
# mkContainer {
|
|
||||||
# image = "registry.gitlab.com/famedly/conduit/matrix-conduit:latest";
|
|
||||||
# hostName = hostname;
|
|
||||||
# domain = blazestar;
|
|
||||||
# port = port;
|
|
||||||
# ports = [
|
|
||||||
# "8449:6167"
|
|
||||||
# ];
|
|
||||||
# volumes = [
|
|
||||||
# "chat-blazestar-net-db:${dbPath}"
|
|
||||||
# ];
|
|
||||||
# environment = {
|
|
||||||
# CONDUIT_PORT = "6167";
|
|
||||||
# CONDUIT_SERVER_NAME = "blazestar.net";
|
|
||||||
# CONDUIT_ALLOW_REGISTRATION = "true";
|
|
||||||
# CONDUIT_DATABASE_BACKEND = "rocksdb";
|
|
||||||
# CONDUIT_DATABASE_PATH = dbPath;
|
|
||||||
# CONDUIT_ALLOW_CHECK_FOR_UPDATES = "true";
|
|
||||||
# CONDUIT_ALLOW_FEDERATION = "true";
|
|
||||||
# CONDUIT_MAX_REQUEST_SIZE = "20000000";
|
|
||||||
# CONDUIT_TRUSTED_SERVERS = "[\"matrix.org\"]";
|
|
||||||
# CONDUIT_MAX_CONCURRENT_REQUESTS = "100";
|
|
||||||
# CONDUIT_WELL_KNOWN_CLIENT = "https://${hostname}.blazestar.net";
|
|
||||||
# CONDUIT_WELL_KNOWN_SERVER = "${hostname}.blazestar.net:443";
|
|
||||||
# CONDUIT_CONFIG = ""; # Ignore the config file
|
|
||||||
# };
|
|
||||||
# extraLabels = {
|
|
||||||
# "traefik.http.routers.${hostname}-blazestar-net-well-known.rule" =
|
|
||||||
# "Host(`blazestar.net`) && PathPrefix(`/.well-known`)";
|
|
||||||
# "traefik.http.routers.${hostname}-blazestar-net-well-known.service" = "${hostname}-blazestar-net";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
virtualisation.oci-containers.containers.chat = mkContainer {
|
|
||||||
image = "vectorim/element-web:latest";
|
|
||||||
hostName = "chat";
|
|
||||||
port = 8080;
|
|
||||||
domain = blazestar;
|
|
||||||
environment = {
|
|
||||||
ELEMENT_WEB_PORT = "8080";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./chat.nix
|
|
||||||
./uptime.nix
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ../lib.nix config) blazestar;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
virtualisation.web-containers.containers.uptime = {
|
|
||||||
image = "louislam/uptime-kuma:1";
|
|
||||||
hostname = "uptime";
|
|
||||||
domain = blazestar;
|
|
||||||
port = 3001;
|
|
||||||
volumes = [
|
|
||||||
"uptime-kuma:/app/data"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let
|
let
|
||||||
inherit (import ./lib.nix config) mkContainer mkMariaDbContainer havenisms;
|
inherit (import ./lib.nix config) mkContainer mkMariaDbContainer havenisms;
|
||||||
in
|
in {
|
||||||
{
|
|
||||||
imports = [
|
imports = [
|
||||||
(mkMariaDbContainer {
|
(mkMariaDbContainer {
|
||||||
name = "bookstack";
|
name = "bookstack";
|
||||||
@@ -15,12 +14,12 @@ in
|
|||||||
|
|
||||||
sops.secrets = {
|
sops.secrets = {
|
||||||
bookstack_app_key = {
|
bookstack_app_key = {
|
||||||
restartUnits = [ "${config.local.container-backend}-bookstack.service" ];
|
restartUnits = [ "podman-bookstack.service" ];
|
||||||
mode = "0400";
|
mode = "0400";
|
||||||
owner = config.users.users.bookstack.name;
|
owner = config.users.users.bookstack.name;
|
||||||
};
|
};
|
||||||
bookstack_db = {
|
bookstack_db = {
|
||||||
restartUnits = [ "${config.local.container-backend}-bookstack-mariadb.service" ];
|
restartUnits = [ "podman-bookstack-mariadb.service" ];
|
||||||
mode = "0400";
|
mode = "0400";
|
||||||
owner = config.users.users.bookstack.name;
|
owner = config.users.users.bookstack.name;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,108 +0,0 @@
|
|||||||
{ config, pkgs, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ./lib.nix config) mkContainer localHostRule terakoda;
|
|
||||||
|
|
||||||
nginxConf = pkgs.writeText "dm-companion-nginx.conf" ''
|
|
||||||
user nginx;
|
|
||||||
worker_processes auto;
|
|
||||||
|
|
||||||
# error.log is symlinked to /dev/stderr
|
|
||||||
error_log /var/log/nginx/error.log notice;
|
|
||||||
pid /run/nginx.pid;
|
|
||||||
|
|
||||||
events {
|
|
||||||
worker_connections 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
http {
|
|
||||||
include /etc/nginx/mime.types;
|
|
||||||
default_type application/octet-stream;
|
|
||||||
|
|
||||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
|
||||||
'$status $body_bytes_sent "$http_referer" '
|
|
||||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
|
||||||
|
|
||||||
# access.log is symlinked to /dev/stdout
|
|
||||||
access_log /var/log/nginx/access.log main;
|
|
||||||
|
|
||||||
sendfile on;
|
|
||||||
|
|
||||||
keepalive_timeout 65;
|
|
||||||
|
|
||||||
gzip on;
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name dm.blazestar.net;
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
|
|
||||||
# X-Frame-Options is to prevent from clickJacking attack
|
|
||||||
add_header X-Frame-Options SAMEORIGIN;
|
|
||||||
|
|
||||||
# disable content-type sniffing on some browsers.
|
|
||||||
add_header X-Content-Type-Options nosniff;
|
|
||||||
|
|
||||||
# This header enables the Cross-site scripting (XSS) filter
|
|
||||||
add_header X-XSS-Protection "1; mode=block";
|
|
||||||
|
|
||||||
add_header Referrer-Policy "no-referrer-when-downgrade";
|
|
||||||
|
|
||||||
# Enables response header of "Vary: Accept-Encoding"
|
|
||||||
# This lets the cache have different entries depending on the encoding, e.g. compression
|
|
||||||
gzip_vary on;
|
|
||||||
|
|
||||||
# Serve static files separately.
|
|
||||||
location ~ ^/(robots.txt|manifest.json) {
|
|
||||||
expires modified 1y;
|
|
||||||
add_header Cache-Control "public";
|
|
||||||
access_log off;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
try_files $uri $uri/ /index.html;
|
|
||||||
index index.html;
|
|
||||||
expires -1;
|
|
||||||
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
virtualisation.oci-containers.containers = {
|
|
||||||
dm-companion-pocketbase =
|
|
||||||
let
|
|
||||||
hostName = "dm-pocketbase";
|
|
||||||
in
|
|
||||||
mkContainer {
|
|
||||||
inherit hostName;
|
|
||||||
image = "docker.havenisms.com/lazy-dm/pocketbase";
|
|
||||||
domain = terakoda;
|
|
||||||
port = 8080;
|
|
||||||
volumes = [
|
|
||||||
"/tank/web/dm.terakoda.com/pb_data:/pb/pb_data"
|
|
||||||
"/tank/web/dm.terakoda.com/pb_migrations:/pb/pb_migrations:ro"
|
|
||||||
];
|
|
||||||
environment = { };
|
|
||||||
extraLabels = {
|
|
||||||
"traefik.http.routers.${hostName}-api.rule" =
|
|
||||||
"PathPrefix(`/api`) && ${localHostRule "dm" terakoda}";
|
|
||||||
"traefik.http.routers.${hostName}-api.service" = "${hostName}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
dm-companion = mkContainer {
|
|
||||||
image = "nginx:alpine";
|
|
||||||
hostName = "dm";
|
|
||||||
domain = terakoda;
|
|
||||||
port = 80;
|
|
||||||
dependsOn = [
|
|
||||||
"dm-companion-pocketbase"
|
|
||||||
];
|
|
||||||
volumes = [
|
|
||||||
"/tank/web/dm.terakoda.com/deployed:/usr/share/nginx/html:ro"
|
|
||||||
"${nginxConf}:/etc/nginx/nginx.conf:ro"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let
|
let
|
||||||
inherit (import ./lib.nix config) mkContainer mkPostgresContainer terakoda;
|
inherit (import ./lib.nix config) mkContainer mkPostgresContainer terakoda;
|
||||||
in
|
in {
|
||||||
{
|
|
||||||
imports = [
|
imports = [
|
||||||
(mkPostgresContainer {
|
(mkPostgresContainer {
|
||||||
name = "focalboard";
|
name = "focalboard";
|
||||||
@@ -15,26 +14,21 @@ in
|
|||||||
|
|
||||||
sops.secrets = {
|
sops.secrets = {
|
||||||
"focalboard/database" = {
|
"focalboard/database" = {
|
||||||
restartUnits = [
|
restartUnits = [ "podman-focalboard.service" "podman-focalboard-postgres.service" ];
|
||||||
"${config.local.container-backend}-focalboard.service"
|
|
||||||
"${config.local.container-backend}-focalboard-postgres.service"
|
|
||||||
];
|
|
||||||
mode = "0400";
|
mode = "0400";
|
||||||
owner = config.users.users.focalboard.name;
|
owner = config.users.users.focalboard.name;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
sops.templates."focalboard-config.json" = {
|
sops.templates."focalboard-config.json" = {
|
||||||
restartUnits = [ "${config.local.container-backend}-focalboard.service" ];
|
restartUnits = [ "podman-focalboard.service" ];
|
||||||
owner = config.users.users.focalboard.name;
|
owner = config.users.users.focalboard.name;
|
||||||
content = builtins.toJSON {
|
content = builtins.toJSON {
|
||||||
# Defaults from https://github.com/mattermost-community/focalboard/blob/main/config.json
|
# Defaults from https://github.com/mattermost-community/focalboard/blob/main/config.json
|
||||||
"serverRoot" = "https://focalboard.terakoda.com";
|
"serverRoot" = "https://focalboard.terakoda.com";
|
||||||
"port" = 8000;
|
"port" = 8000;
|
||||||
"dbtype" = "postgres";
|
"dbtype" = "postgres";
|
||||||
"dbconfig" = "postgres://focalboard:${
|
"dbconfig" = "postgres://focalboard:${config.sops.placeholder."focalboard/database"}@focalboard-postgres/focalboard?sslmode=disable&connect_timeout=10";
|
||||||
config.sops.placeholder."focalboard/database"
|
|
||||||
}@focalboard-postgres/focalboard?sslmode=disable&connect_timeout=10";
|
|
||||||
"useSSL" = true;
|
"useSSL" = true;
|
||||||
"prometheus_address" = ":9092";
|
"prometheus_address" = ":9092";
|
||||||
"session_expire_time" = 2592000;
|
"session_expire_time" = 2592000;
|
||||||
@@ -56,7 +50,7 @@ in
|
|||||||
domain = terakoda;
|
domain = terakoda;
|
||||||
dependsOn = [ "focalboard-postgres" ];
|
dependsOn = [ "focalboard-postgres" ];
|
||||||
port = 8000;
|
port = 8000;
|
||||||
user = "${toString config.users.users.focalboard.uid}:${toString config.users.groups.focalboard.gid}";
|
user = "${toString config.users.users.focalboard.name}:${config.users.groups.focalboard.name}";
|
||||||
volumes = [
|
volumes = [
|
||||||
"/tank/focalboard/data/files:/opt/focalboard/data/files"
|
"/tank/focalboard/data/files:/opt/focalboard/data/files"
|
||||||
"${config.sops.templates."focalboard-config.json".path}:/opt/focalboard/config.json:ro"
|
"${config.sops.templates."focalboard-config.json".path}:/opt/focalboard/config.json:ro"
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ./lib.nix config) mkContainer havenisms;
|
|
||||||
in {
|
|
||||||
virtualisation.oci-containers.containers.freshrss = mkContainer {
|
|
||||||
image = "lscr.io/linuxserver/freshrss:latest";
|
|
||||||
hostName = "freshrss";
|
|
||||||
domain = havenisms;
|
|
||||||
port = "80";
|
|
||||||
homepageOpts = {
|
|
||||||
group = "Apps";
|
|
||||||
name = "FreshRSS";
|
|
||||||
icon = "freshrss.svg";
|
|
||||||
description = "Feed aggregator";
|
|
||||||
};
|
|
||||||
volumes = [
|
|
||||||
"/tank/config/freshrss:/config"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,40 +1,24 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let
|
let
|
||||||
inherit (import ./lib.nix config) mkContainer blazestar;
|
inherit (import ./lib.nix config) hostRule blazestar;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
sops.secrets = {
|
virtualisation.oci-containers.containers.gitea = {
|
||||||
"gitea/db_password" = {
|
|
||||||
restartUnits = [ "${config.local.container-backend}-gitea.service" ];
|
|
||||||
};
|
|
||||||
"gitea/registration_token" = {
|
|
||||||
restartUnits = [ "${config.local.container-backend}-gitea-runner.service" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.templates."gitea.env".content = ''
|
|
||||||
GITEA__database__DB_TYPE="postgres"
|
|
||||||
GITEA__database__HOST="db"
|
|
||||||
GITEA__database__NAME="gitea"
|
|
||||||
GITEA__database__USER="gitea"
|
|
||||||
GITEA__database__PASSWD="${config.sops.placeholder."gitea/db_password"}"
|
|
||||||
'';
|
|
||||||
|
|
||||||
virtualisation.oci-containers.containers.gitea = mkContainer {
|
|
||||||
image = "gitea/gitea:latest-rootless";
|
image = "gitea/gitea:latest-rootless";
|
||||||
|
autoStart = true;
|
||||||
dependsOn = [
|
dependsOn = [
|
||||||
"db"
|
"db"
|
||||||
];
|
];
|
||||||
hostName = "git";
|
extraOptions = [
|
||||||
domain = blazestar;
|
"-l=traefik.enable=true"
|
||||||
public = true;
|
"-l=traefik.http.routers.gitea.rule=${hostRule "git" blazestar}"
|
||||||
port = 3000;
|
"-l=traefik.http.services.gitea.loadbalancer.server.port=3000"
|
||||||
homepageOpts = {
|
"-l=homepage.group=Apps"
|
||||||
name = "Gitea";
|
"-l=homepage.name=Gitea"
|
||||||
icon = "gitea.png";
|
"-l=homepage.icon=gitea.png"
|
||||||
description = "Git Server";
|
"-l=homepage.href=https://git.${blazestar}"
|
||||||
group = "Apps";
|
"-l=homepage.description=Git Server"
|
||||||
};
|
];
|
||||||
ports = [
|
ports = [
|
||||||
"2222:2222"
|
"2222:2222"
|
||||||
];
|
];
|
||||||
@@ -52,21 +36,14 @@ in
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
sops.templates."gitea-runner.env".content = ''
|
sops.secrets."gitea_db_password" = {
|
||||||
GITEA_RUNNER_NAME=MCP
|
restartUnits = [ "podman-gitea.service" ];
|
||||||
GITEA_INSTANCE_URL=https://git.${blazestar}
|
|
||||||
GITEA_RUNNER_REGISTRATION_TOKEN=${config.sops.placeholder."gitea/registration_token"}
|
|
||||||
'';
|
|
||||||
|
|
||||||
virtualisation.oci-containers.containers.gitea-runner = {
|
|
||||||
image = "gitea/act_runner:latest";
|
|
||||||
autoStart = true;
|
|
||||||
environmentFiles = [
|
|
||||||
config.sops.templates."gitea-runner.env".path
|
|
||||||
];
|
|
||||||
volumes = [
|
|
||||||
# The runner will spawn new containers to run the actions
|
|
||||||
"${config.local.container-socket}:/var/run/docker.sock:ro"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
sops.templates."gitea.env".content = ''
|
||||||
|
GITEA__database__DB_TYPE="postgres"
|
||||||
|
GITEA__database__HOST="db"
|
||||||
|
GITEA__database__NAME="gitea"
|
||||||
|
GITEA__database__USER="gitea"
|
||||||
|
GITEA__database__PASSWD="${config.sops.placeholder."gitea_db_password"}"
|
||||||
|
'';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ./lib.nix config)
|
|
||||||
terakoda
|
|
||||||
blazestar
|
|
||||||
hostRule
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
../../../features/web-containers.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
virtualisation.web-containers = {
|
|
||||||
enable = true;
|
|
||||||
containers = {
|
|
||||||
goatcounter-terakoda = {
|
|
||||||
image = "arp242/goatcounter";
|
|
||||||
hostname = "goatcounter";
|
|
||||||
domain = terakoda;
|
|
||||||
public = true;
|
|
||||||
port = 8080;
|
|
||||||
volumes = [
|
|
||||||
"goatcounter-data:/home/goatcounter/goatcounter-data"
|
|
||||||
];
|
|
||||||
extraLabels = {
|
|
||||||
# "traefik.http.middlewares.strip-analytics.stripprefix.prefixes" = "/analytics";
|
|
||||||
# "traefik.http.routers.www-terakoda-com-goatcounter.middlewares" = "strip-analytics";
|
|
||||||
# Host the script on www.terakoda.com so that it is easy to fetch
|
|
||||||
"traefik.http.routers.www-terakoda-com-goatcounter.rule" =
|
|
||||||
"PathPrefix(`/count`) && ${hostRule "www" terakoda}";
|
|
||||||
"traefik.http.routers.www-terakoda-com-goatcounter.entrypoints" = "websecure";
|
|
||||||
"traefik.http.routers.www-terakoda-com-goatcounter.service" = "goatcounter-terakoda-com";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
goatcounter-blazestar = {
|
|
||||||
image = "arp242/goatcounter";
|
|
||||||
hostname = "goatcounter";
|
|
||||||
domain = blazestar;
|
|
||||||
public = true;
|
|
||||||
port = 8080;
|
|
||||||
volumes = [
|
|
||||||
"goatcounter-data-blazestar:/home/goatcounter/goatcounter-data"
|
|
||||||
];
|
|
||||||
extraLabels = {
|
|
||||||
# "traefik.http.middlewares.strip-analytics.stripprefix.prefixes" = "/analytics";
|
|
||||||
# "traefik.http.routers.www-blazestar-net-goatcounter.middlewares" = "strip-analytics";
|
|
||||||
# Host the script on www.blazestar.net so that it is easy to fetch
|
|
||||||
"traefik.http.routers.www-blazestar-net-goatcounter.rule" =
|
|
||||||
"PathPrefix(`/count`) && ${hostRule "www" blazestar}";
|
|
||||||
"traefik.http.routers.www-blazestar-net-goatcounter.entrypoints" = "websecure";
|
|
||||||
"traefik.http.routers.www-blazestar-net-goatcounter.service" = "goatcounter-blazestar-net@docker";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ../lib.nix config) hostRule havenisms;
|
|
||||||
syncRule = "(PathPrefix(`/client/`) || PathPrefix(`/_matrix/client/unstable/org.matrix.msc3575/sync`))";
|
|
||||||
wellKnownRule = "(Host(`havenisms.com`) || Host(`chat.havenisms.com`)) && PathPrefix(`/.well-known`)";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
|
|
||||||
sops.secrets = {
|
|
||||||
"matrix/syncv3/db-password" = {
|
|
||||||
restartUnits = [ "${config.local.container-backend}-matrix-sliding-sync.service" ];
|
|
||||||
};
|
|
||||||
"matrix/syncv3/secret" = {
|
|
||||||
restartUnits = [ "${config.local.container-backend}-matrix-sliding-sync.service" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.templates."matrix-sliding-sync.env".content = ''
|
|
||||||
SYNCV3_SERVER=http://synapse:8008
|
|
||||||
SYNCV3_DB=postgres://syncv3:${
|
|
||||||
config.sops.placeholder."matrix/syncv3/db-password"
|
|
||||||
}@db:5432/syncv3?sslmode=disable
|
|
||||||
SYNCV3_SECRET=${config.sops.placeholder."matrix/syncv3/secret"}
|
|
||||||
SYNCV3_BINDADDR=:8009
|
|
||||||
'';
|
|
||||||
|
|
||||||
virtualisation.oci-containers.containers = {
|
|
||||||
synapse = {
|
|
||||||
image = "docker.io/matrixdotorg/synapse:latest";
|
|
||||||
autoStart = true;
|
|
||||||
dependsOn = [
|
|
||||||
"db"
|
|
||||||
];
|
|
||||||
|
|
||||||
volumes = [
|
|
||||||
"/tank/config/synapse/data:/data"
|
|
||||||
];
|
|
||||||
extraOptions = [
|
|
||||||
"-l=traefik.enable=true"
|
|
||||||
"-l=traefik.http.routers.synapse.rule=${hostRule "chat" havenisms} && !(${syncRule} || ${wellKnownRule})"
|
|
||||||
"-l=traefik.http.routers.synapse.service=synapse"
|
|
||||||
"-l=traefik.http.services.synapse.loadbalancer.server.port=8008"
|
|
||||||
|
|
||||||
# Federation forwarding
|
|
||||||
"-l=traefik.http.routers.synapse-federation.rule=${hostRule "chat" havenisms}"
|
|
||||||
"-l=traefik.http.routers.synapse-federation.service=synapse-federation"
|
|
||||||
"-l=traefik.http.routers.synapse-federation.entrypoints=matrix-federation"
|
|
||||||
"-l=traefik.http.services.synapse-federation.loadbalancer.server.port=8448"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
matrix-sliding-sync = {
|
|
||||||
image = "ghcr.io/matrix-org/sliding-sync:latest";
|
|
||||||
dependsOn = [
|
|
||||||
"db"
|
|
||||||
"synapse"
|
|
||||||
];
|
|
||||||
environmentFiles = [
|
|
||||||
config.sops.templates."matrix-sliding-sync.env".path
|
|
||||||
];
|
|
||||||
extraOptions = [
|
|
||||||
"-l=traefik.enable=true"
|
|
||||||
"-l=traefik.http.routers.syncv3.rule=${hostRule "chat" havenisms} && ${syncRule}"
|
|
||||||
"-l=traefik.http.services.syncv3.loadbalancer.server.port=8009"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# This server helps to serve the .well-known files that are required by clients to find the sync server.
|
|
||||||
matrix-well-known = {
|
|
||||||
image = "nginx";
|
|
||||||
dependsOn = [ "synapse" ];
|
|
||||||
volumes = [
|
|
||||||
"/tank/config/synapse/static-files:/usr/share/nginx/html:ro"
|
|
||||||
];
|
|
||||||
extraOptions = [
|
|
||||||
"-l=traefik.enable=true"
|
|
||||||
"-l=traefik.http.middlewares.strip-well-known.stripprefix.prefixes=/.well-known"
|
|
||||||
"-l=traefik.http.routers.matrix-well-known.rule=${wellKnownRule}"
|
|
||||||
"-l=traefik.http.routers.matrix-well-known.middlewares=strip-well-known"
|
|
||||||
"-l=traefik.http.services.matrix-well-known.loadbalancer.server.port=80"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./chat.nix
|
|
||||||
# Currently disabled because it doesn't start up properly
|
|
||||||
# ./immich.nix
|
|
||||||
./storyden.nix
|
|
||||||
./tandoor.nix
|
|
||||||
./wallabag.nix
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ../lib.nix config) havenisms mkPostgresContainer;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
(mkPostgresContainer {
|
|
||||||
# Immich wants a custom build of postgres with the vectors extensions.
|
|
||||||
image = "ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:c44be5f2871c59362966d71eab4268170eb6f5653c0e6170184e72b38ffdf107";
|
|
||||||
name = "immich";
|
|
||||||
directory = "/tank/immich/db";
|
|
||||||
uid = config.users.users.immich.uid;
|
|
||||||
gid = config.users.groups.immich.gid;
|
|
||||||
passwordSecret = "immich/database";
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
sops.secrets = {
|
|
||||||
"immich/database" = {
|
|
||||||
restartUnits = [
|
|
||||||
"${config.local.container-backend}-immich-db.service"
|
|
||||||
];
|
|
||||||
mode = "0400";
|
|
||||||
owner = config.users.users.immich.name;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.templates."immich.env" = {
|
|
||||||
restartUnits = [ "${config.local.container-backend}-immich.service" ];
|
|
||||||
owner = config.users.users.immich.name;
|
|
||||||
content = ''
|
|
||||||
DB_HOSTNAME=immich-postgres
|
|
||||||
DB_PASSWORD=${config.sops.placeholder."immich/database"}
|
|
||||||
DB_USERNAME=immich
|
|
||||||
DB_DATABASE_NAME=immich
|
|
||||||
REDIS_HOSTNAME=immich-redis
|
|
||||||
IMMICH_LOG_LEVEL=verbose
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualisation.web-containers.containers.immich = {
|
|
||||||
image = "ghcr.io/immich-app/immich-server:release";
|
|
||||||
hostname = "immich";
|
|
||||||
domain = havenisms;
|
|
||||||
port = 2283;
|
|
||||||
volumes = [
|
|
||||||
"/tank/photos/immich:/data"
|
|
||||||
"/etc/localtime:/etc/localtime:ro"
|
|
||||||
];
|
|
||||||
dependsOn = [
|
|
||||||
"immich-redis"
|
|
||||||
"immich-postgres"
|
|
||||||
];
|
|
||||||
environmentFiles = [
|
|
||||||
"${config.sops.templates."immich.env".path}"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualisation.oci-containers.containers = {
|
|
||||||
"immich-redis" = {
|
|
||||||
image = "docker.io/valkey/valkey";
|
|
||||||
};
|
|
||||||
"immich-machine-learning" = {
|
|
||||||
image = "ghcr.io/immich-app/immich-machine-learning:release";
|
|
||||||
volumes = [
|
|
||||||
"model-cache:/cache"
|
|
||||||
];
|
|
||||||
environmentFiles = [
|
|
||||||
"${config.sops.templates."immich.env".path}"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ../lib.nix config) havenisms;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
|
|
||||||
virtualisation.web-containers.containers.storyden = {
|
|
||||||
image = "ghcr.io/southclaws/storyden";
|
|
||||||
port = 8000;
|
|
||||||
hostname = "storyden";
|
|
||||||
domain = havenisms;
|
|
||||||
environment = {
|
|
||||||
PUBLIC_WEB_ADDRESS = "https://storyden.${havenisms}";
|
|
||||||
PUBLIC_API_ADDRESS = "https://storyden.${havenisms}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ../lib.nix config) havenisms;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sops.secrets = {
|
|
||||||
"tandoor/secret_key" = {
|
|
||||||
restartUnits = [ "${config.local.container-backend}-tandoor.service" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.templates."tandoor.env".content = ''
|
|
||||||
SECRET_KEY="${config.sops.placeholder."tandoor/secret_key"}"
|
|
||||||
DB_ENGINE=django.db.backends.sqlite3
|
|
||||||
'';
|
|
||||||
|
|
||||||
virtualisation.web-containers.containers.tandoor = {
|
|
||||||
image = "vabene1111/recipes";
|
|
||||||
hostname = "recipes";
|
|
||||||
domain = havenisms;
|
|
||||||
port = 80;
|
|
||||||
volumes = [
|
|
||||||
"/tank/tandoor-recipes/mediafiles:/opt/recipes/mediafiles"
|
|
||||||
"/tank/tandoor-recipes/staticfiles:/opt/recipes/staticfiles"
|
|
||||||
];
|
|
||||||
environmentFiles = [
|
|
||||||
config.sops.templates."tandoor.env".path
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ../lib.nix config) havenisms;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
virtualisation.web-containers.containers.wallabag = {
|
|
||||||
image = "wallabag/wallabag";
|
|
||||||
hostname = "wallabag";
|
|
||||||
domain = havenisms;
|
|
||||||
port = 80;
|
|
||||||
volumes = [
|
|
||||||
"wallabag-data:/var/www/wallabag/data"
|
|
||||||
"wallabag-images:/var/www/wallabag/web/assets/images"
|
|
||||||
];
|
|
||||||
environment = {
|
|
||||||
SYMFONY__ENV__DOMAIN_NAME = "https://wallabag.${havenisms}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -21,63 +21,41 @@ in
|
|||||||
havenisms
|
havenisms
|
||||||
blazestar
|
blazestar
|
||||||
terakoda
|
terakoda
|
||||||
terakoda_net
|
terakoda_net;
|
||||||
;
|
|
||||||
|
|
||||||
mkContainer =
|
mkContainer = {
|
||||||
{
|
image,
|
||||||
image,
|
hostName,
|
||||||
hostName,
|
port,
|
||||||
port,
|
homepageOpts ? {},
|
||||||
homepageOpts ? { },
|
dependsOn ? [],
|
||||||
dependsOn ? [ ],
|
domain ? havenisms,
|
||||||
domain ? havenisms,
|
ports ? [],
|
||||||
ports ? [ ],
|
volumes ? [],
|
||||||
volumes ? [ ],
|
environment ? {},
|
||||||
environment ? { },
|
environmentFiles ? [],
|
||||||
environmentFiles ? [ ],
|
public ? false,
|
||||||
public ? false,
|
user ? null,
|
||||||
user ? null,
|
extraOptions ? [],
|
||||||
extraOptions ? [ ],
|
}:
|
||||||
oauthProxy ? false,
|
|
||||||
extraLabels ? { },
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
routerRule = if public then hostRule hostName domain else localHostRule hostName domain;
|
routerRule = if public then hostRule hostName domain else localHostRule hostName domain;
|
||||||
homepageLabels =
|
homepageLabels = if homepageOpts == {} then {} else {
|
||||||
if homepageOpts == { } then
|
"homepage.group" = "${homepageOpts.group}";
|
||||||
{ }
|
"homepage.name" = "${homepageOpts.name}";
|
||||||
else
|
"homepage.icon" = "${homepageOpts.icon}";
|
||||||
{
|
"homepage.href" = "https://${hostName}.${domain}";
|
||||||
"homepage.group" = "${homepageOpts.group}";
|
"homepage.description" = "${homepageOpts.description}";
|
||||||
"homepage.name" = "${homepageOpts.name}";
|
};
|
||||||
"homepage.icon" = "${homepageOpts.icon}";
|
|
||||||
"homepage.href" = "https://${hostName}.${domain}";
|
|
||||||
"homepage.description" = "${homepageOpts.description}";
|
|
||||||
};
|
|
||||||
oauthLabels =
|
|
||||||
if oauthProxy then { "traefik.http.routers.${hostName}.middlewares" = "oidc-auth@file"; } else { };
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit
|
inherit image dependsOn volumes environment environmentFiles ports user extraOptions;
|
||||||
image
|
|
||||||
dependsOn
|
|
||||||
volumes
|
|
||||||
environment
|
|
||||||
environmentFiles
|
|
||||||
ports
|
|
||||||
user
|
|
||||||
extraOptions
|
|
||||||
;
|
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
labels = {
|
labels = {
|
||||||
"traefik.enable" = "true";
|
"traefik.enable" = "true";
|
||||||
"traefik.http.routers.${hostName}.rule" = "${routerRule}";
|
"traefik.http.routers.${hostName}.rule" = "${routerRule}";
|
||||||
"traefik.http.services.${hostName}.loadbalancer.server.port" = "${toString port}";
|
"traefik.http.services.${hostName}.loadbalancer.server.port" = "${toString port}";
|
||||||
}
|
} // homepageLabels;
|
||||||
// oauthLabels
|
|
||||||
// homepageLabels
|
|
||||||
// extraLabels;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Creates a MariaDB container for a specific app. It should be safe to give
|
# Creates a MariaDB container for a specific app. It should be safe to give
|
||||||
@@ -86,65 +64,60 @@ in
|
|||||||
# user.
|
# user.
|
||||||
#
|
#
|
||||||
# Note that this returns a _module_ so that it can be imported and provide many different config values.
|
# Note that this returns a _module_ so that it can be imported and provide many different config values.
|
||||||
mkMariaDbContainer =
|
mkMariaDbContainer = {
|
||||||
{
|
name,
|
||||||
name,
|
uid,
|
||||||
uid,
|
gid,
|
||||||
gid,
|
passwordSecret,
|
||||||
passwordSecret,
|
directory,
|
||||||
directory,
|
}:
|
||||||
}:
|
{ config, ... }:
|
||||||
{ config, ... }:
|
{
|
||||||
{
|
virtualisation.oci-containers.containers."${name}-mariadb" = {
|
||||||
virtualisation.oci-containers.containers."${name}-mariadb" = {
|
image = "lscr.io/linuxserver/mariadb:latest";
|
||||||
image = "lscr.io/linuxserver/mariadb:latest";
|
autoStart = true;
|
||||||
autoStart = true;
|
ports = [ "3306:3306" ];
|
||||||
ports = [ "3306:3306" ];
|
volumes = [
|
||||||
volumes = [
|
"${directory}:/config"
|
||||||
"${directory}:/config"
|
"${config.sops.secrets.mariadb_root_password.path}:/run/secrets/mariadb_root_password"
|
||||||
"${config.sops.secrets.mariadb_root_password.path}:/run/secrets/mariadb_root_password"
|
"${config.sops.secrets."${passwordSecret}".path}:/run/secrets/mariadb_password"
|
||||||
"${config.sops.secrets."${passwordSecret}".path}:/run/secrets/mariadb_password"
|
];
|
||||||
];
|
environment = {
|
||||||
environment = {
|
PUID = "${toString uid}";
|
||||||
PUID = "${toString uid}";
|
PGID = "${toString gid}";
|
||||||
PGID = "${toString gid}";
|
MYSQL_USER = name;
|
||||||
MYSQL_USER = name;
|
MYSQL_DATABASE = name;
|
||||||
MYSQL_DATABASE = name;
|
FILE__MYSQL_ROOT_PASSWORD = "/run/secrets/mariadb_root_password";
|
||||||
FILE__MYSQL_ROOT_PASSWORD = "/run/secrets/mariadb_root_password";
|
FILE__MYSQL_PASSWORD = "/run/secrets/mariadb_password";
|
||||||
FILE__MYSQL_PASSWORD = "/run/secrets/mariadb_password";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
mkPostgresContainer =
|
mkPostgresContainer = {
|
||||||
{
|
name,
|
||||||
name,
|
uid,
|
||||||
uid,
|
gid,
|
||||||
gid,
|
passwordSecret,
|
||||||
passwordSecret,
|
directory,
|
||||||
directory,
|
containerName ? "${name}-postgres",
|
||||||
containerName ? "${name}-postgres",
|
databaseName ? name,
|
||||||
databaseName ? name,
|
username ? name,
|
||||||
username ? name,
|
}: { config, ... }: {
|
||||||
image ? "postgres",
|
virtualisation.oci-containers.containers."${containerName}" = {
|
||||||
}:
|
image = "postgres";
|
||||||
{ config, ... }:
|
autoStart = true;
|
||||||
{
|
volumes = [
|
||||||
virtualisation.oci-containers.containers."${containerName}" = {
|
# Note that data must be mounted at this location to persist.
|
||||||
inherit image;
|
# See https://github.com/docker-library/docs/blob/master/postgres/README.md#pgdata
|
||||||
autoStart = true;
|
"${directory}:/var/lib/postgresql/data"
|
||||||
volumes = [
|
"${config.sops.secrets."${passwordSecret}".path}:/run/secrets/postgres_password"
|
||||||
# Note that data must be mounted at this location to persist.
|
];
|
||||||
# See https://github.com/docker-library/docs/blob/master/postgres/README.md#pgdata
|
user = "${toString uid}:${toString gid}";
|
||||||
"${directory}:/var/lib/postgresql/data"
|
environment = {
|
||||||
"${config.sops.secrets."${passwordSecret}".path}:/run/secrets/postgres_password"
|
POSTGRES_USER = username;
|
||||||
];
|
POSTGRES_DB = databaseName;
|
||||||
user = "${toString uid}:${toString gid}";
|
POSTGRES_PASSWORD_FILE = "/run/secrets/postgres_password";
|
||||||
environment = {
|
|
||||||
POSTGRES_USER = username;
|
|
||||||
POSTGRES_DB = databaseName;
|
|
||||||
POSTGRES_PASSWORD_FILE = "/run/secrets/postgres_password";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Common config for all mariadb containers
|
# Common config for all mariadb containers
|
||||||
{ config, ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
sops.secrets."mariadb_root_password" = {
|
sops.secrets."mariadb_root_password" = {
|
||||||
restartUnits = [ "${config.local.container-backend}-mariadb.service" ];
|
restartUnits = [ "podman-mariadb.service" ];
|
||||||
mode = "0440";
|
mode = "0440";
|
||||||
group = "mariadb";
|
group = "mariadb";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,280 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ./lib.nix config)
|
|
||||||
hostRuleHavenisms
|
|
||||||
localHostRuleHavenisms
|
|
||||||
havenisms
|
|
||||||
mkContainer
|
|
||||||
;
|
|
||||||
gluetun_env = "gluetun-proton-vpn-wireguard.env";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
|
|
||||||
sops.secrets = {
|
|
||||||
"protonvpn/private_key" = {
|
|
||||||
restartUnits = [ "${config.local.container-backend}-gluetun.service" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Example Wireguard config file:
|
|
||||||
# # Key for MCP Wireguard
|
|
||||||
# # Bouncing = 13
|
|
||||||
# # NetShield = 1
|
|
||||||
# # Moderate NAT = off
|
|
||||||
# # NAT-PMP (Port Forwarding) = on
|
|
||||||
# # VPN Accelerator = on
|
|
||||||
# PrivateKey = ${config.sops.placeholder."protonvpn/private_key"}
|
|
||||||
# Address = 10.2.0.2/32
|
|
||||||
# DNS = 10.2.0.1
|
|
||||||
#
|
|
||||||
# [Peer]
|
|
||||||
# # US-CA#906
|
|
||||||
# PublicKey = 2xvxhMK0AalXOMq6Dh0QMVJ0Cl3WQTmWT5tdeb8SpR0=
|
|
||||||
# AllowedIPs = 0.0.0.0/0, ::/0
|
|
||||||
# Endpoint = 79.127.185.166:51820
|
|
||||||
#
|
|
||||||
# PersistentKeepalive = 25
|
|
||||||
sops.templates.${gluetun_env}.content = ''
|
|
||||||
VPN_SERVICE_PROVIDER=protonvpn
|
|
||||||
VPN_TYPE=wireguard
|
|
||||||
WIREGUARD_PRIVATE_KEY="${config.sops.placeholder."protonvpn/private_key"}"
|
|
||||||
SERVER_COUNTRIES="United States,United Kingdom,Netherlands,Switzerland,Sweden"
|
|
||||||
VPN_PORT_FORWARDING=on
|
|
||||||
'';
|
|
||||||
|
|
||||||
virtualisation.oci-containers.containers = {
|
|
||||||
jellyfin = {
|
|
||||||
image = "lscr.io/linuxserver/jellyfin:10.11.6";
|
|
||||||
autoStart = true;
|
|
||||||
extraOptions = [
|
|
||||||
"--device=/dev/dri:/dev/dri"
|
|
||||||
"-l=traefik.enable=true"
|
|
||||||
"-l=traefik.http.routers.jellyfin.rule=${hostRuleHavenisms "jellyfin"}"
|
|
||||||
"-l=traefik.http.services.jellyfin.loadbalancer.server.port=8096"
|
|
||||||
"-l=homepage.group=Apps"
|
|
||||||
"-l=homepage.name=Jellyfin"
|
|
||||||
"-l=homepage.icon=jellyfin.svg"
|
|
||||||
"-l=homepage.href=https://jellyfin.${havenisms}"
|
|
||||||
"-l=homepage.description=Media player"
|
|
||||||
"-l=homepage.widget.type=jellyfin"
|
|
||||||
"-l=homepage.widget.key={{HOMEPAGE_FILE_JELLYFIN_KEY}}"
|
|
||||||
"-l=homepage.widget.url=http://jellyfin:8096"
|
|
||||||
"-l=homepage.widget.enableBlocks=true"
|
|
||||||
];
|
|
||||||
volumes = [
|
|
||||||
"/tank/media/collection:/data"
|
|
||||||
"/tank/config/jellyfin:/config"
|
|
||||||
];
|
|
||||||
# environment = {
|
|
||||||
# TZ = vars.timeZone;
|
|
||||||
# PUID = "994";
|
|
||||||
# UMASK = "002";
|
|
||||||
# GUID = "993";
|
|
||||||
# };
|
|
||||||
};
|
|
||||||
deluge = {
|
|
||||||
image = "lscr.io/linuxserver/deluge:latest";
|
|
||||||
autoStart = true;
|
|
||||||
dependsOn = [
|
|
||||||
"gluetun"
|
|
||||||
];
|
|
||||||
extraOptions = [
|
|
||||||
"--network=container:gluetun"
|
|
||||||
"-l=homepage.group=Arr"
|
|
||||||
"-l=homepage.name=Deluge"
|
|
||||||
"-l=homepage.icon=deluge.svg"
|
|
||||||
"-l=homepage.href=https://deluge.${havenisms}"
|
|
||||||
"-l=homepage.description=Torrent client"
|
|
||||||
"-l=homepage.widget.type=deluge"
|
|
||||||
"-l=homepage.widget.password={{HOMEPAGE_FILE_DELUGE_PASSWORD}}"
|
|
||||||
"-l=homepage.widget.url=http://gluetun:8112"
|
|
||||||
];
|
|
||||||
volumes = [
|
|
||||||
"/tank/media:/data"
|
|
||||||
"/tank/config/deluge:/config"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
qbittorrent = {
|
|
||||||
image = "lscr.io/linuxserver/qbittorrent:latest";
|
|
||||||
autoStart = true;
|
|
||||||
dependsOn = [
|
|
||||||
"gluetun"
|
|
||||||
];
|
|
||||||
extraOptions = [
|
|
||||||
"--network=container:gluetun"
|
|
||||||
"-l=homepage.group=Arr"
|
|
||||||
"-l=homepage.name=qBitTorrent"
|
|
||||||
"-l=homepage.icon=qbittorrent.svg"
|
|
||||||
"-l=homepage.href=https://torrents.${havenisms}"
|
|
||||||
"-l=homepage.description=Torrent client"
|
|
||||||
"-l=homepage.widget.type=qbittorrent"
|
|
||||||
"-l=homepage.widget.url=http://torrents.${havenisms}"
|
|
||||||
];
|
|
||||||
volumes = [
|
|
||||||
"/tank/media/Downloads:/downloads"
|
|
||||||
"/tank/config/qbittorrent:/config"
|
|
||||||
];
|
|
||||||
environment = {
|
|
||||||
PUID = "911";
|
|
||||||
PGID = "911";
|
|
||||||
UMASK = "002";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
gluetun = {
|
|
||||||
image = "qmcgaw/gluetun:latest";
|
|
||||||
autoStart = true;
|
|
||||||
extraOptions = [
|
|
||||||
# add network admin capability.
|
|
||||||
"--cap-add=NET_ADMIN"
|
|
||||||
"--device=/dev/net/tun:/dev/net/tun"
|
|
||||||
"-l=traefik.enable=true"
|
|
||||||
"-l=traefik.http.routers.torrents.rule=${localHostRuleHavenisms "torrents"}"
|
|
||||||
"-l=traefik.http.routers.torrents.service=torrents"
|
|
||||||
"-l=traefik.http.services.torrents.loadbalancer.server.port=8080"
|
|
||||||
"-l=homepage.group=Infra"
|
|
||||||
"-l=homepage.name=GlueTun"
|
|
||||||
"-l=homepage.icon=gluetun.svg"
|
|
||||||
"-l=homepage.href=https://torrents.${havenisms}"
|
|
||||||
"-l=homepage.description=VPN killswitch"
|
|
||||||
"-l=homepage.widget.type=gluetun"
|
|
||||||
"-l=homepage.widget.url=http://gluetun:8000"
|
|
||||||
];
|
|
||||||
ports = [
|
|
||||||
"127.0.0.1:8083:8000"
|
|
||||||
];
|
|
||||||
environmentFiles = [
|
|
||||||
config.sops.templates.${gluetun_env}.path
|
|
||||||
];
|
|
||||||
};
|
|
||||||
prowlarr = {
|
|
||||||
image = "lscr.io/linuxserver/prowlarr";
|
|
||||||
autoStart = true;
|
|
||||||
extraOptions = [
|
|
||||||
"-l=traefik.enable=true"
|
|
||||||
"-l=traefik.http.routers.prowlarr.rule=${localHostRuleHavenisms "prowlarr"}"
|
|
||||||
"-l=traefik.http.services.prowlarr.loadbalancer.server.port=9696"
|
|
||||||
"-l=homepage.group=Arr"
|
|
||||||
"-l=homepage.name=Prowlarr"
|
|
||||||
"-l=homepage.icon=prowlarr.svg"
|
|
||||||
"-l=homepage.href=https://prowlarr.${havenisms}"
|
|
||||||
"-l=homepage.description=Torrent indexer"
|
|
||||||
];
|
|
||||||
volumes = [
|
|
||||||
"/tank/config/prowlarr:/config"
|
|
||||||
];
|
|
||||||
environment = {
|
|
||||||
UMASK = "002";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# Currently broken and doesn't work. :(
|
|
||||||
# flaresolverr = {
|
|
||||||
# image = "ghcr.io/flaresolverr/flaresolverr:latest";
|
|
||||||
# autoStart = true;
|
|
||||||
# extraOptions = [
|
|
||||||
# "-l=homepage.group=Infra"
|
|
||||||
# "-l=homepage.name=FlareSolverr"
|
|
||||||
# "-l=homepage.icon=flaresolverr.svg"
|
|
||||||
# "-l=homepage.href=https://flaresolverr.${domain}"
|
|
||||||
# "-l=homepage.description=Cloudflare bypass"
|
|
||||||
# ];
|
|
||||||
# volumes = [
|
|
||||||
# "/tank/config/flaresolverr:/config"
|
|
||||||
# ];
|
|
||||||
# environment = {
|
|
||||||
# UMASK = "002";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
radarr = {
|
|
||||||
image = "lscr.io/linuxserver/radarr";
|
|
||||||
autoStart = true;
|
|
||||||
extraOptions = [
|
|
||||||
"-l=traefik.enable=true"
|
|
||||||
"-l=traefik.http.routers.radarr.rule=${localHostRuleHavenisms "radarr"}"
|
|
||||||
"-l=traefik.http.services.radarr.loadbalancer.server.port=7878"
|
|
||||||
"-l=homepage.group=Arr"
|
|
||||||
"-l=homepage.name=Radarr"
|
|
||||||
"-l=homepage.icon=radarr.svg"
|
|
||||||
"-l=homepage.href=https://radarr.${havenisms}"
|
|
||||||
"-l=homepage.description=Movie acquisition"
|
|
||||||
"-l=homepage.widget.type=radarr"
|
|
||||||
"-l=homepage.widget.url=http://radarr:7878"
|
|
||||||
"-l=homepage.widget.key={{HOMEPAGE_FILE_RADARR_KEY}}"
|
|
||||||
];
|
|
||||||
volumes = [
|
|
||||||
"/tank/media:/data"
|
|
||||||
"/tank/config/radarr:/config"
|
|
||||||
];
|
|
||||||
environment = {
|
|
||||||
UMASK = "002";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
sonarr = {
|
|
||||||
image = "lscr.io/linuxserver/sonarr";
|
|
||||||
autoStart = true;
|
|
||||||
extraOptions = [
|
|
||||||
"-l=traefik.enable=true"
|
|
||||||
"-l=traefik.http.routers.sonarr.rule=${localHostRuleHavenisms "sonarr"}"
|
|
||||||
"-l=traefik.http.services.sonarr.loadbalancer.server.port=8989"
|
|
||||||
"-l=homepage.group=Arr"
|
|
||||||
"-l=homepage.name=Sonarr"
|
|
||||||
"-l=homepage.icon=sonarr.svg"
|
|
||||||
"-l=homepage.href=https://sonarr.${havenisms}"
|
|
||||||
"-l=homepage.description=Show acquisition"
|
|
||||||
"-l=homepage.widget.type=sonarr"
|
|
||||||
"-l=homepage.widget.url=http://sonarr:8989"
|
|
||||||
"-l=homepage.widget.key={{HOMEPAGE_FILE_SONARR_KEY}}"
|
|
||||||
];
|
|
||||||
volumes = [
|
|
||||||
"/tank/media:/data"
|
|
||||||
"/tank/config/sonarr:/config"
|
|
||||||
];
|
|
||||||
environment = {
|
|
||||||
UMASK = "002";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
readarr = {
|
|
||||||
# The Linuxserver version of this image doesn't have a latest tag. Odd.
|
|
||||||
image = "lscr.io/linuxserver/readarr:develop";
|
|
||||||
autoStart = true;
|
|
||||||
extraOptions = [
|
|
||||||
"-l=traefik.enable=true"
|
|
||||||
"-l=traefik.http.routers.readarr.rule=${localHostRuleHavenisms "readarr"}"
|
|
||||||
"-l=traefik.http.services.readarr.loadbalancer.server.port=8787"
|
|
||||||
"-l=homepage.group=Arr"
|
|
||||||
"-l=homepage.name=Readarr"
|
|
||||||
"-l=homepage.icon=readarr.svg"
|
|
||||||
"-l=homepage.href=https://readarr.${havenisms}"
|
|
||||||
"-l=homepage.description=E-book acquisition"
|
|
||||||
"-l=homepage.widget.type=readarr"
|
|
||||||
"-l=homepage.widget.url=http://readarr.havenisms.com:8787"
|
|
||||||
"-l=homepage.widget.key={{HOMEPAGE_FILE_READARR_KEY}}"
|
|
||||||
];
|
|
||||||
volumes = [
|
|
||||||
"/tank/media:/data"
|
|
||||||
"/tank/config/readarr:/config"
|
|
||||||
];
|
|
||||||
environment = {
|
|
||||||
UMASK = "002";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
bazarr = mkContainer {
|
|
||||||
# The Linuxserver version of this image doesn't have a latest tag. Odd.
|
|
||||||
image = "lscr.io/linuxserver/bazarr:latest";
|
|
||||||
port = 6767;
|
|
||||||
hostName = "bazarr";
|
|
||||||
homepageOpts = {
|
|
||||||
group = "Arr";
|
|
||||||
name = "Bazarr";
|
|
||||||
icon = "bazarr.svg";
|
|
||||||
description = "Subtitles";
|
|
||||||
};
|
|
||||||
volumes = [
|
|
||||||
"/tank/media:/data"
|
|
||||||
"/tank/config/bazarr:/config"
|
|
||||||
];
|
|
||||||
environment = {
|
|
||||||
UMASK = "002";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
virtualisation.oci-containers.containers.nextcloud = {
|
virtualisation.oci-containers.containers.nextcloud = {
|
||||||
image = "docker.io/library/nextcloud:31";
|
image = "docker.io/library/nextcloud:latest";
|
||||||
extraOptions = [
|
extraOptions = [
|
||||||
"-l=traefik.enable=true"
|
"-l=traefik.enable=true"
|
||||||
"-l=traefik.http.routers.nextcloud.rule=${hostRule "cloud" havenisms}"
|
"-l=traefik.http.routers.nextcloud.rule=${hostRule "cloud" havenisms}"
|
||||||
@@ -20,5 +20,13 @@ in
|
|||||||
volumes = [
|
volumes = [
|
||||||
"/tank/nextcloud:/var/www/html"
|
"/tank/nextcloud:/var/www/html"
|
||||||
];
|
];
|
||||||
|
environment = {
|
||||||
|
POSTGRES_HOST = "db";
|
||||||
|
POSTGRES_DB = "nextcloud";
|
||||||
|
POSTGRES_USER = "nextcloud";
|
||||||
|
# TODO: Secrets
|
||||||
|
POSTGRES_PASSWORD = "nextcloud123";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ./lib.nix config) mkContainer blazestar havenisms;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sops.secrets = {
|
|
||||||
"oauth2-proxy/cookie-secret" = {
|
|
||||||
restartUnits = [ "${config.local.container-backend}-oauth2-proxy.service" ];
|
|
||||||
mode = "0400";
|
|
||||||
};
|
|
||||||
"oauth2-proxy/client-secret" = {
|
|
||||||
restartUnits = [ "${config.local.container-backend}-oauth2-proxy.service" ];
|
|
||||||
mode = "0400";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.templates."oauth2-proxy.env".content = ''
|
|
||||||
OAUTH2_PROXY_HTTP_ADDRESS='0.0.0.0:4180'
|
|
||||||
OAUTH2_PROXY_COOKIE_SECRET='${config.sops.placehoder."oauth2-proxy/cookie-secret"}'
|
|
||||||
OAUTH2_PROXY_COOKIE_DOMAINS='.${blazestar} .${havenisms}'
|
|
||||||
OAUTH2_PROXY_WHITELIST_DOMAINS='.${blazestar} .${havenisms}'
|
|
||||||
OAUTH2_PROXY_PROVIDER='oidc'
|
|
||||||
OAUTH2_PROXY_CLIENT_ID='oauth2-proxy'
|
|
||||||
OAUTH2_PROXY_CLIENT_SECRET='${config.sops.placehoder."oauth2-proxy/client-secret"}'
|
|
||||||
OAUTH2_PROXY_EMAIL_DOMAINS='*'
|
|
||||||
OAUTH2_PROXY_OIDC_ISSUER_URL='https://auth.${blazestar}/realms/master'
|
|
||||||
OAUTH2_PROXY_REDIRECT_URL='https://auth.${blazestar}/oauth2/callback'
|
|
||||||
OAUTH2_PROXY_COOKIE_CSRF_PER_REQUEST=true
|
|
||||||
OAUTH2_PROXY_COOKIE_CSRF_EXPIRE='5m'
|
|
||||||
OAUTH2_PROXY_CUSTOM_TEMPLATES_DIR="/templates"
|
|
||||||
OAUTH2_PROXY_REVERSE_PROXY=true
|
|
||||||
'';
|
|
||||||
|
|
||||||
virtualisation.oci-containers.containers.oauth2-proxy = mkContainer {
|
|
||||||
image = "quay.io/oauth2-proxy/oauth2-proxy";
|
|
||||||
hostName = "oauth";
|
|
||||||
domain = blazestar;
|
|
||||||
port = "4180";
|
|
||||||
homepageOpts = {
|
|
||||||
group = "Infra";
|
|
||||||
name = "OAuth2-Proxy";
|
|
||||||
icon = "oauth2-proxy.png";
|
|
||||||
description = "An OAuth2 Reverse Proxy";
|
|
||||||
};
|
|
||||||
volumes = [
|
|
||||||
];
|
|
||||||
environment = {
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,20 +1,19 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let
|
let
|
||||||
inherit (import ./lib.nix config) mkContainer havenisms;
|
inherit (import ./lib.nix config) mkContainer havenisms;
|
||||||
hostName = "projects";
|
hostName = "projects";
|
||||||
in
|
in {
|
||||||
{
|
|
||||||
|
|
||||||
sops.secrets = {
|
sops.secrets = {
|
||||||
"openproject/secret-key-base" = {
|
"openproject/secret-key-base" = {
|
||||||
restartUnits = [ "${config.local.container-backend}-openproject.service" ];
|
restartUnits = [ "podman-openproject.service" ];
|
||||||
mode = "0400";
|
mode = "0400";
|
||||||
owner = config.users.users.bookstack.name;
|
owner = config.users.users.bookstack.name;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
sops.templates."openproject.env" = {
|
sops.templates."openproject.env" = {
|
||||||
restartUnits = [ "${config.local.container-backend}-openproject.service" ];
|
restartUnits = [ "podman-openproject.service" ];
|
||||||
content = ''
|
content = ''
|
||||||
OPENPROJECT_SECRET_KEY_BASE=${config.sops.placeholder."openproject/secret-key-base"}
|
OPENPROJECT_SECRET_KEY_BASE=${config.sops.placeholder."openproject/secret-key-base"}
|
||||||
OPENPROJECT_HOST__NAME=${hostName}.${havenisms}
|
OPENPROJECT_HOST__NAME=${hostName}.${havenisms}
|
||||||
|
|||||||
@@ -1,64 +1,30 @@
|
|||||||
# Static websites
|
# Static websites
|
||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
let
|
let
|
||||||
inherit (import ./lib.nix config)
|
inherit (import ./lib.nix config) terakoda havenisms blazestar;
|
||||||
terakoda
|
mkStaticSite = domain: let
|
||||||
havenisms
|
cleanDomain = lib.strings.stringAsChars (c: if c == "." then "-" else c) domain;
|
||||||
blazestar
|
in {
|
||||||
;
|
"${cleanDomain}-static" = {
|
||||||
mkStaticSite =
|
image = "nginx:alpine";
|
||||||
{
|
autoStart = true;
|
||||||
host,
|
volumes = [
|
||||||
dir ? "public",
|
"/tank/web/${domain}/public:/usr/share/nginx/html:ro"
|
||||||
redirectWww ? true,
|
];
|
||||||
}:
|
labels = {
|
||||||
let
|
"traefik.enable" = "true";
|
||||||
cleanHost = lib.strings.stringAsChars (c: if c == "." then "-" else c) host;
|
"traefik.http.routers.${cleanDomain}.rule" = "Host(`${domain}`) || Host(`www.${domain}`)";
|
||||||
wwwLabels =
|
"traefik.http.routers.${cleanDomain}.middlewares" = "${cleanDomain}-add-www@docker";
|
||||||
if redirectWww then
|
"traefik.http.services.${cleanDomain}.loadbalancer.server.port" = "80";
|
||||||
{
|
"traefik.http.middlewares.${cleanDomain}-add-www.redirectregex.regex" = "^https://${domain}/(.*)";
|
||||||
"traefik.http.routers.${cleanHost}.middlewares" = "${cleanHost}-add-www@docker";
|
"traefik.http.middlewares.${cleanDomain}-add-www.redirectregex.replacement" = "https://www.${domain}/\${1}";
|
||||||
"traefik.http.middlewares.${cleanHost}-add-www.redirectregex.regex" = "^https://${host}/(.*)";
|
"traefik.http.middlewares.${cleanDomain}-add-www.redirectregex.permanent" = "true";
|
||||||
"traefik.http.middlewares.${cleanHost}-add-www.redirectregex.replacement" =
|
|
||||||
"https://www.${host}/\${1}";
|
|
||||||
"traefik.http.middlewares.${cleanHost}-add-www.redirectregex.permanent" = "true";
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ };
|
|
||||||
in
|
|
||||||
{
|
|
||||||
"${cleanHost}-static" = {
|
|
||||||
image = "nginx:alpine";
|
|
||||||
autoStart = true;
|
|
||||||
volumes = [
|
|
||||||
"/tank/web/${host}/${dir}:/usr/share/nginx/html:ro"
|
|
||||||
];
|
|
||||||
labels = {
|
|
||||||
"traefik.enable" = "true";
|
|
||||||
"traefik.http.routers.${cleanHost}.rule" = "Host(`${host}`) || Host(`www.${host}`)";
|
|
||||||
"traefik.http.services.${cleanHost}.loadbalancer.server.port" = "80";
|
|
||||||
} // wwwLabels;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
};
|
||||||
{
|
in {
|
||||||
virtualisation.oci-containers.containers =
|
virtualisation.oci-containers.containers =
|
||||||
mkStaticSite {
|
mkStaticSite terakoda //
|
||||||
host = terakoda;
|
mkStaticSite havenisms //
|
||||||
dir = "deployed";
|
mkStaticSite blazestar;
|
||||||
}
|
|
||||||
// mkStaticSite {
|
|
||||||
host = blazestar;
|
|
||||||
dir = "deployed";
|
|
||||||
}
|
|
||||||
// mkStaticSite {
|
|
||||||
host = "wow.${blazestar}";
|
|
||||||
dir = "deployed";
|
|
||||||
redirectWww = false;
|
|
||||||
}
|
|
||||||
// mkStaticSite {
|
|
||||||
host = havenisms;
|
|
||||||
dir = "public";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
60
system/hosts/mcp/containers/synapse.nix
Normal file
60
system/hosts/mcp/containers/synapse.nix
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
let inherit (import ./lib.nix config) hostRule havenisms;
|
||||||
|
syncRule = "(PathPrefix(`/client/`) || PathPrefix(`/_matrix/client/unstable/org.matrix.msc3575/sync`))";
|
||||||
|
wellKnownRule = "PathPrefix(`/.well-known`)";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
virtualisation.oci-containers.containers = {
|
||||||
|
synapse = {
|
||||||
|
image = "docker.io/matrixdotorg/synapse:latest";
|
||||||
|
autoStart = true;
|
||||||
|
dependsOn = [
|
||||||
|
"db"
|
||||||
|
];
|
||||||
|
volumes = [
|
||||||
|
"/tank/config/synapse/data:/data"
|
||||||
|
];
|
||||||
|
ports = [
|
||||||
|
"8008:8008/tcp"
|
||||||
|
];
|
||||||
|
extraOptions = [
|
||||||
|
"-l=traefik.enable=true"
|
||||||
|
"-l=traefik.http.routers.synapse.rule=${hostRule "chat" havenisms} && !(${syncRule} || ${wellKnownRule})"
|
||||||
|
"-l=traefik.http.services.synapse.loadbalancer.server.port=8008"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
matrix_sliding_sync = {
|
||||||
|
image = "ghcr.io/matrix-org/sliding-sync:latest";
|
||||||
|
dependsOn = ["db"];
|
||||||
|
ports = [
|
||||||
|
"8009:8009"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
SYNCV3_SERVER = "http://synapse:8008";
|
||||||
|
# TODO: Store password securely
|
||||||
|
SYNCV3_DB = "postgres://syncv3:TZKr3RNmVx@db:5432/syncv3?sslmode=disable";
|
||||||
|
# TODO: Store secret securely
|
||||||
|
SYNCV3_SECRET = "4917590296b90910ec31ba355af6c7731409fd5f284d24912b852c3f928fa162";
|
||||||
|
SYNCV3_BINDADDR = ":8009";
|
||||||
|
};
|
||||||
|
extraOptions = [
|
||||||
|
"-l=traefik.enable=true"
|
||||||
|
"-l=traefik.http.routers.syncv3.rule=${hostRule "chat" havenisms} && ${syncRule}"
|
||||||
|
"-l=traefik.http.services.syncv3.loadbalancer.server.port=8009"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
# This server helps to serve the .well-known files that are required by clients to find the sync server.
|
||||||
|
matrix_well_known = {
|
||||||
|
image = "nginx";
|
||||||
|
ports = [ "80" ];
|
||||||
|
volumes = [
|
||||||
|
"/tank/config/synapse/static-files:/usr/share/nginx/html:ro"
|
||||||
|
];
|
||||||
|
extraOptions = [
|
||||||
|
"-l=traefik.enable=true"
|
||||||
|
"-l=traefik.http.routers.matrix-static.rule=${hostRule "chat" havenisms} && ${wellKnownRule}"
|
||||||
|
"-l=traefik.http.services.matrix-static.loadbalancer.server.port=80"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (import ./lib.nix config) mkContainer;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
virtualisation.oci-containers.containers.timetagger = mkContainer {
|
|
||||||
image = "ghcr.io/almarklein/timetagger:v24.12.2";
|
|
||||||
hostName = "time";
|
|
||||||
port = "80";
|
|
||||||
oauthProxy = true;
|
|
||||||
homepageOpts = {
|
|
||||||
group = "Apps";
|
|
||||||
name = "TimeTagger";
|
|
||||||
icon = "timetagger.png";
|
|
||||||
description = "Time tracker";
|
|
||||||
|
|
||||||
};
|
|
||||||
volumes = [
|
|
||||||
"/tank/config/timetagger:/data"
|
|
||||||
];
|
|
||||||
environment = {
|
|
||||||
TIMETAGGER_BIND = "0.0.0.0:80";
|
|
||||||
TIMETAGGER_DATADIR = "/data";
|
|
||||||
TIMETAGGER_LOG_LEVEL = "debug";
|
|
||||||
TIMETAGGER_PROXY_AUTH_ENABLED = "True";
|
|
||||||
TIMETAGGER_PROXY_AUTH_TRUSTED = "10.88.0.0/16";
|
|
||||||
TIMETAGGER_PROXY_AUTH_HEADER = "X-Remote-User";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -5,77 +5,28 @@ let
|
|||||||
name = "traefik-config";
|
name = "traefik-config";
|
||||||
path = ./traefik;
|
path = ./traefik;
|
||||||
};
|
};
|
||||||
in
|
in {
|
||||||
{
|
|
||||||
|
|
||||||
sops.secrets = {
|
|
||||||
"traefik/oauth2-client-secret" = {
|
|
||||||
restartUnits = [ "${config.local.container-backend}-traefik.service" ];
|
|
||||||
mode = "0400";
|
|
||||||
};
|
|
||||||
"traefik/oauth2-plugin-secret" = {
|
|
||||||
restartUnits = [ "${config.local.container-backend}-traefik.service" ];
|
|
||||||
mode = "0400";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.templates."traefik/oauth2-config.yaml".content = ''
|
|
||||||
http:
|
|
||||||
middlewares:
|
|
||||||
oidc-auth:
|
|
||||||
plugin:
|
|
||||||
traefik-oidc-auth:
|
|
||||||
LogLevel: DEBUG
|
|
||||||
Secret: "${config.sops.placeholder."traefik/oauth2-plugin-secret"}"
|
|
||||||
# Omitting the Callback URL means it will use the current domain for the callback.
|
|
||||||
# CallbackUri: "https://oidc.blazestar.net/oidc/callback"
|
|
||||||
Provider:
|
|
||||||
Url: "https://auth.blazestar.net/"
|
|
||||||
ClientId: "3e3f7d9a-a684-4412-866c-ea7281954a9f"
|
|
||||||
ClientSecret: "${config.sops.placeholder."traefik/oauth2-client-secret"}"
|
|
||||||
TokenValidation: "IdToken"
|
|
||||||
UsePkce: false
|
|
||||||
Scopes: ["openid", "profile", "email"]
|
|
||||||
Headers:
|
|
||||||
- Name: "X-Oidc-Username"
|
|
||||||
Value: "{{`{{ .claims.preferred_username }}`}}"
|
|
||||||
- Name: "X-Oidc-Email"
|
|
||||||
Value: "{{`{{ .claims.email }}`}}"
|
|
||||||
- Name: "X-Oidc-Subject"
|
|
||||||
Value: "sub"
|
|
||||||
- Name: "Authorization"
|
|
||||||
Value: "{{`Bearer {{ .accessToken }}`}}"
|
|
||||||
- Name: "IdToken"
|
|
||||||
Value: "{{`Bearer {{ .idToken }}`}}"
|
|
||||||
'';
|
|
||||||
|
|
||||||
virtualisation.oci-containers.containers.traefik = mkContainer {
|
virtualisation.oci-containers.containers.traefik = mkContainer {
|
||||||
image = "traefik";
|
image = "traefik";
|
||||||
hostName = "proxy";
|
hostName = "proxy";
|
||||||
port = 8080;
|
port = 8080;
|
||||||
domain = blazestar;
|
domain = blazestar;
|
||||||
public = false;
|
public = false;
|
||||||
ports = [
|
ports = [
|
||||||
"80:80"
|
"80:80"
|
||||||
"443:443"
|
"443:443"
|
||||||
"8448:8448"
|
];
|
||||||
];
|
volumes =
|
||||||
volumes = [
|
[
|
||||||
"${config.local.container-socket}:/var/run/docker.sock:ro"
|
"/var/run/podman/podman.sock:/var/run/docker.sock:ro"
|
||||||
# All the configs from the config directory
|
"${traefikConfigDir}:/etc/traefik"
|
||||||
"${traefikConfigDir}:/etc/traefik"
|
"/tank/config/traefik/acme:/etc/traefik/acme"
|
||||||
# Oauth2 config containing secrets
|
];
|
||||||
"${config.sops.templates."traefik/oauth2-config.yaml".path}:/etc/traefik/dynamic/oauth2-config.yaml"
|
homepageOpts = {
|
||||||
# Persistent storage for acme certificates
|
name = "Traefik";
|
||||||
# TODO: It may be possible to just use docker storage because persistence
|
icon = "traefik.svg";
|
||||||
# is not critical when the cert can just be renewed.
|
group = "Infra";
|
||||||
"/tank/config/traefik/acme:/etc/traefik/acme"
|
description = "Reverse Proxy";
|
||||||
];
|
};
|
||||||
homepageOpts = {
|
|
||||||
name = "Traefik";
|
|
||||||
icon = "traefik.svg";
|
|
||||||
group = "Infra";
|
|
||||||
description = "Reverse Proxy";
|
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -13,13 +13,6 @@ entryPoints:
|
|||||||
certResolver: letsencrypt
|
certResolver: letsencrypt
|
||||||
metrics:
|
metrics:
|
||||||
address: ":8082"
|
address: ":8082"
|
||||||
asDefault: false
|
|
||||||
matrix-federation:
|
|
||||||
address: ":8448"
|
|
||||||
asDefault: false
|
|
||||||
http:
|
|
||||||
tls:
|
|
||||||
certResolver: letsencrypt
|
|
||||||
|
|
||||||
api:
|
api:
|
||||||
insecure: true
|
insecure: true
|
||||||
@@ -28,7 +21,7 @@ providers:
|
|||||||
docker:
|
docker:
|
||||||
exposedByDefault: false
|
exposedByDefault: false
|
||||||
file:
|
file:
|
||||||
directory: /etc/traefik/dynamic
|
directory: /etc/traefik/static
|
||||||
watch: true
|
watch: true
|
||||||
|
|
||||||
certificatesResolvers:
|
certificatesResolvers:
|
||||||
@@ -44,13 +37,3 @@ metrics:
|
|||||||
addEntryPointsLabels: true
|
addEntryPointsLabels: true
|
||||||
addServicesLabels: true
|
addServicesLabels: true
|
||||||
entryPoint: "metrics"
|
entryPoint: "metrics"
|
||||||
|
|
||||||
# Plugins must be defined in static config
|
|
||||||
# Configuration of the plugin is in traefik.nix because it contains secrets.
|
|
||||||
# TODO: Convert this whole file to a template in Nix
|
|
||||||
experimental:
|
|
||||||
plugins:
|
|
||||||
traefik-oidc-auth:
|
|
||||||
moduleName: "github.com/sevensolutions/traefik-oidc-auth"
|
|
||||||
version: "v0.13.0"
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }: let
|
||||||
let
|
|
||||||
systemUsers = {
|
systemUsers = {
|
||||||
gitea = {
|
gitea = {
|
||||||
uid = 2001;
|
uid = 2001;
|
||||||
@@ -13,14 +12,12 @@ let
|
|||||||
offen = 2007;
|
offen = 2007;
|
||||||
public-html = {
|
public-html = {
|
||||||
uid = 2008;
|
uid = 2008;
|
||||||
shell = pkgs.zsh;
|
shell = "${pkgs.git}/bin/git-shell";
|
||||||
authorizedKeys = [
|
authorizedKeys = [
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKPiqbLAXpBkjXnHLvz3VCd5i+VmYdd9dAcRt+8E1OQX drew@vega"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKPiqbLAXpBkjXnHLvz3VCd5i+VmYdd9dAcRt+8E1OQX drew@vega"
|
||||||
];
|
];
|
||||||
home = "/tank/web";
|
home = "/tank/web";
|
||||||
packages = [ pkgs.git ];
|
|
||||||
};
|
};
|
||||||
immich = 2009;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mkUser = name: value: {
|
mkUser = name: value: {
|
||||||
@@ -29,30 +26,24 @@ let
|
|||||||
description = "System User for ${name}";
|
description = "System User for ${name}";
|
||||||
group = "${name}";
|
group = "${name}";
|
||||||
shell = value.shell or null;
|
shell = value.shell or null;
|
||||||
extraGroups = value.extraGroups or [ ];
|
extraGroups = value.extraGroups or [];
|
||||||
openssh.authorizedKeys.keys = value.authorizedKeys or [ ];
|
openssh.authorizedKeys.keys = value.authorizedKeys or [];
|
||||||
home = value.home or "/var/empty";
|
home = value.home or "/var/empty";
|
||||||
packages = value.packages or [ ];
|
|
||||||
};
|
};
|
||||||
mkGroup =
|
mkGroup = name: value: let
|
||||||
name: value:
|
# 1. Value if int
|
||||||
let
|
# 2. "gid" if present
|
||||||
# 1. Value if int
|
# 3. "uid"
|
||||||
# 2. "gid" if present
|
gid =
|
||||||
# 3. "uid"
|
if builtins.isInt value
|
||||||
gid =
|
then value
|
||||||
if builtins.isInt value then
|
else if builtins.hasAttr "gid" value
|
||||||
value
|
then value.gid
|
||||||
else if builtins.hasAttr "gid" value then
|
else value.uid;
|
||||||
value.gid
|
in {
|
||||||
else
|
inherit gid;
|
||||||
value.uid;
|
};
|
||||||
in
|
in {
|
||||||
{
|
|
||||||
inherit gid;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
users.users = builtins.mapAttrs mkUser systemUsers;
|
users.users = builtins.mapAttrs mkUser systemUsers;
|
||||||
users.groups = (builtins.mapAttrs mkGroup systemUsers) // {
|
users.groups = (builtins.mapAttrs mkGroup systemUsers) // {
|
||||||
# Legacy groups.
|
# Legacy groups.
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user