Compare commits
53 Commits
63bd01d083
...
c02dafd0d1
| Author | SHA1 | Date | |
|---|---|---|---|
| c02dafd0d1 | |||
| 9128bf3d66 | |||
| 042787770e | |||
| afb451d3cc | |||
| 1d1a13d9ce | |||
| ba38794ef4 | |||
| 30302af17b | |||
| 2f627902f3 | |||
| 3b2460f97a | |||
| c73adbe26f | |||
| 59476285df | |||
| 68ee7894a0 | |||
| dc5c5038b9 | |||
| 61e8436dd9 | |||
| cae85ef2e6 | |||
| 6226177c08 | |||
| 593449d0c3 | |||
| c1e56790c5 | |||
| 3acd59d938 | |||
| 758ab5beb1 | |||
| 39c108b3ee | |||
| cd55d1d7cf | |||
| f76c6862ba | |||
| abcad5c9f2 | |||
| b89c6a14cc | |||
| 86582c0dcc | |||
| 460d79c107 | |||
| 394d12a7b2 | |||
| 2cc42a5800 | |||
| 4c6f6ee68d | |||
| 15d82a44fb | |||
| 5168f5fc3e | |||
| d58262a043 | |||
| 2db7081bfc | |||
| bad309eb60 | |||
| 6ca3f8fedc | |||
| cd4cd68e96 | |||
| f6379435b8 | |||
| 36213c47c9 | |||
| ff096a520a | |||
| 00ab2ae68c | |||
| b4bf817c5e | |||
| 2b3b12b6a1 | |||
| 87ed8a6337 | |||
| c2a543f83b | |||
| fcbf908b15 | |||
| 1657efcae7 | |||
| ee51577189 | |||
| 6609922170 | |||
| 35be9990ba | |||
| cacb342117 | |||
| 23384e35ed | |||
| 0897deae29 |
@@ -1,173 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# --- SUDO CHECK ---
|
|
||||||
if [ "$EUID" -ne 0 ]; then
|
|
||||||
echo "This script requires root privileges. Re-running with sudo..."
|
|
||||||
exec sudo "$0" "$@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --- HANDLE -k OPTION FOR KEY FILE ---
|
|
||||||
BORG_PASSPHRASE=""
|
|
||||||
|
|
||||||
while getopts "k:" opt; do
|
|
||||||
case "$opt" in
|
|
||||||
k)
|
|
||||||
BORG_PASSPHRASE=$(<"$OPTARG")
|
|
||||||
if [ -z "$BORG_PASSPHRASE" ]; then
|
|
||||||
echo "Error: The key file is empty."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Using passphrase from key file: $OPTARG"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Usage: $0 [-k passphrase_file] <repo>"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
shift $((OPTIND - 1))
|
|
||||||
|
|
||||||
# --- FALLBACK TO /run/secrets/borg_passwd IF NO KEY FILE ---
|
|
||||||
if [ -z "$BORG_PASSPHRASE" ]; then
|
|
||||||
if [ -f "/run/secrets/borg_passwd" ]; then
|
|
||||||
BORG_PASSPHRASE=$(<"/run/secrets/borg_passwd")
|
|
||||||
echo "Using passphrase from /run/secrets/borg_passwd"
|
|
||||||
else
|
|
||||||
# Prompt user for passphrase if neither -k nor /run/secrets/borg_passwd is available
|
|
||||||
read -s -p "Enter Borg repository passphrase: " BORG_PASSPHRASE
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
export BORG_PASSPHRASE
|
|
||||||
|
|
||||||
# --- DEFAULT REPO ---
|
|
||||||
REPO="${1:-/holocron/backups}"
|
|
||||||
|
|
||||||
# --- CHECK REQUIRED COMMANDS ---
|
|
||||||
for cmd in borg fzf find tree cp mkdir; do
|
|
||||||
command -v "$cmd" >/dev/null || { echo "Error: '$cmd' is required but not installed."; exit 1; }
|
|
||||||
done
|
|
||||||
|
|
||||||
# --- LIST ARCHIVES (sorted, newest last) ---
|
|
||||||
mapfile -t archives < <(borg list --format="{archive}{NL}" "$REPO" | sort)
|
|
||||||
if [ ${#archives[@]} -eq 0 ]; then
|
|
||||||
echo "No archives found in $REPO"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --- FZF ARCHIVE SELECT ---
|
|
||||||
selected=$(printf '%s\n' "${archives[@]}" | fzf --prompt="Select archive: " --height=40% --border --reverse)
|
|
||||||
if [ -z "$selected" ]; then
|
|
||||||
echo "No archive selected."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Selected archive: $selected"
|
|
||||||
|
|
||||||
# --- GENERATE A UNIQUE, SHORTER MOUNT POINT ---
|
|
||||||
MOUNT_POINT="/tmp/borg-mount-${selected}-$(uuidgen | sha256sum | head -c 6)"
|
|
||||||
mkdir -p "$MOUNT_POINT"
|
|
||||||
|
|
||||||
# --- MOUNT ARCHIVE ---
|
|
||||||
echo "Mounting '$selected' to $MOUNT_POINT..."
|
|
||||||
borg mount "$REPO::$selected" "$MOUNT_POINT"
|
|
||||||
|
|
||||||
if [ ! -d "$MOUNT_POINT" ]; then
|
|
||||||
echo "Error: mount failed."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --- LIST FILES AND DIRECTORIES ---
|
|
||||||
echo "Scanning files and directories..."
|
|
||||||
if command -v fd >/dev/null 2>&1; then
|
|
||||||
# List files and directories using fd (can handle both files and dirs)
|
|
||||||
files=$(fd --type f --type d . "$MOUNT_POINT" | sort)
|
|
||||||
else
|
|
||||||
# Fall back to find if fd is not available
|
|
||||||
files=$(find "$MOUNT_POINT" -type f -o -type d | sort)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$files" ]; then
|
|
||||||
echo "No files or directories found in archive."
|
|
||||||
borg umount "$MOUNT_POINT"
|
|
||||||
rm -rf "$MOUNT_POINT"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --- HIERARCHICAL FZF FILE/DIRECTORY SELECTION (REVERSED) ---
|
|
||||||
# We reverse the order of files to display the latest (newest) files/folders at the top.
|
|
||||||
selected_files=$(printf '%s\n' "$files" | sed "s|$MOUNT_POINT/||" | tac | fzf \
|
|
||||||
--multi \
|
|
||||||
--height=50% \
|
|
||||||
--border \
|
|
||||||
--prompt="Select files or directories to restore: " \
|
|
||||||
--preview "tree -C -L 5 $MOUNT_POINT/$(dirname {})" \
|
|
||||||
--preview-window=right:50% \
|
|
||||||
--delimiter='/' \
|
|
||||||
--with-nth=1..)
|
|
||||||
|
|
||||||
if [ -z "$selected_files" ]; then
|
|
||||||
echo "No files or directories selected. Exiting."
|
|
||||||
borg umount "$MOUNT_POINT"
|
|
||||||
rm -rf "$MOUNT_POINT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --- SUMMARY OF SELECTED FILES/DIRECTORIES ---
|
|
||||||
echo "Selected files and directories:"
|
|
||||||
for file in $selected_files; do
|
|
||||||
echo " $file"
|
|
||||||
done
|
|
||||||
|
|
||||||
# --- OPTIONS MENU (concise) ---
|
|
||||||
# Default to option 1 if no input is given
|
|
||||||
echo "Select restore destination: 1) Restore to ./${selected}_restore 2) Restore to original dirs 3) Quit"
|
|
||||||
read -p "Enter your choice (1/2/3) [default: 1]: " choice
|
|
||||||
# Default to option 1 if user presses Enter without providing input
|
|
||||||
choice="${choice:-1}"
|
|
||||||
|
|
||||||
# --- SET RESTORE DESTINATION BASED ON USER CHOICE ---
|
|
||||||
case "$choice" in
|
|
||||||
1)
|
|
||||||
DEST="./${selected}_restore"
|
|
||||||
;;
|
|
||||||
2)
|
|
||||||
DEST="$MOUNT_POINT"
|
|
||||||
;;
|
|
||||||
3)
|
|
||||||
echo "Quitting. No files restored."
|
|
||||||
borg umount "$MOUNT_POINT"
|
|
||||||
rm -rf "$MOUNT_POINT"
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid choice. Exiting."
|
|
||||||
borg umount "$MOUNT_POINT"
|
|
||||||
rm -rf "$MOUNT_POINT"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
mkdir -p "$DEST"
|
|
||||||
|
|
||||||
# --- RESTORE FILES AND DIRECTORIES ---
|
|
||||||
echo "Restoring selected files and directories..."
|
|
||||||
while IFS= read -r file; do
|
|
||||||
# Path is already stripped of /tmp, so no need for further modification
|
|
||||||
dest_path="$DEST/$file"
|
|
||||||
mkdir -p "$(dirname "$dest_path")"
|
|
||||||
# If it's a directory, we use cp -r to ensure the directory structure is restored
|
|
||||||
if [ -d "$MOUNT_POINT/$file" ]; then
|
|
||||||
cp -r "$MOUNT_POINT/$file" "$dest_path"
|
|
||||||
else
|
|
||||||
cp -a "$MOUNT_POINT/$file" "$dest_path"
|
|
||||||
fi
|
|
||||||
echo "Restored: $file"
|
|
||||||
done <<< "$selected_files"
|
|
||||||
|
|
||||||
# --- CLEANUP ---
|
|
||||||
borg umount "$MOUNT_POINT"
|
|
||||||
rm -rf "$MOUNT_POINT"
|
|
||||||
echo "Restore complete."
|
|
||||||
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# borg-browser.sh — fzf-based Borg archive browser with passphrase prompt
|
|
||||||
|
|
||||||
[ "$EUID" -ne 0 ] && { echo "Please run as root."; exec sudo "$0" "$@"; }
|
|
||||||
|
|
||||||
REPO="/holocron/backups"
|
|
||||||
|
|
||||||
# Prompt once for Borg passphrase
|
|
||||||
read -rs -p "Borg passphrase: " BORG_PASSPHRASE
|
|
||||||
echo
|
|
||||||
export BORG_PASSPHRASE
|
|
||||||
|
|
||||||
# Pick an archive
|
|
||||||
ARCHIVE=$(borg list --short "$REPO" | fzf --prompt="Select archive: ") || {
|
|
||||||
unset BORG_PASSPHRASE
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
[ -z "$ARCHIVE" ] && { unset BORG_PASSPHRASE; exit; }
|
|
||||||
|
|
||||||
# Function to browse directories hierarchically
|
|
||||||
browse_borg_dir() {
|
|
||||||
local prefix="$1"
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
# Get immediate children of the current path
|
|
||||||
ITEMS=$(borg list --format='{path}{NL}' "$REPO::$ARCHIVE" \
|
|
||||||
| awk -v p="$prefix" -F/ '
|
|
||||||
BEGIN{n=split(p,a,"/")}
|
|
||||||
index($0,p)==1 && NF>n {
|
|
||||||
if (NF==n+1) print $NF;
|
|
||||||
else print $(n+1)"/";
|
|
||||||
}' \
|
|
||||||
| sort -u)
|
|
||||||
|
|
||||||
[ -z "$ITEMS" ] && { echo "No items found in $prefix"; return; }
|
|
||||||
|
|
||||||
SELECTION=$(echo -e "../\n$ITEMS" | fzf --prompt="${prefix:-/}> ")
|
|
||||||
case "$SELECTION" in
|
|
||||||
"../")
|
|
||||||
prefix="${prefix%/*}"
|
|
||||||
prefix="${prefix%/}"
|
|
||||||
;;
|
|
||||||
"")
|
|
||||||
return
|
|
||||||
;;
|
|
||||||
*/)
|
|
||||||
prefix="${prefix:+$prefix/}${SELECTION%/}"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
local fullpath="${prefix:+$prefix/}$SELECTION"
|
|
||||||
echo "Selected file: $fullpath"
|
|
||||||
read -rp "Extract it here? [y/N]: " yn
|
|
||||||
if [[ $yn =~ ^[Yy]$ ]]; then
|
|
||||||
borg extract "$REPO::$ARCHIVE" "$fullpath"
|
|
||||||
fi
|
|
||||||
return
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
browse_borg_dir ""
|
|
||||||
unset BORG_PASSPHRASE
|
|
||||||
|
|
||||||
@@ -17,6 +17,10 @@ TARGET=""
|
|||||||
# Parse arguments
|
# Parse arguments
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
-m|--media)
|
||||||
|
OWNER=":media"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
-o|--owner)
|
-o|--owner)
|
||||||
OWNER="$2"
|
OWNER="$2"
|
||||||
shift 2
|
shift 2
|
||||||
|
|||||||
@@ -1,26 +1,44 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -euo pipefail
|
||||||
pushd ~/.nix
|
|
||||||
# nvim flake.nix
|
|
||||||
# alejandra . &>/dev/null
|
|
||||||
# git diff -U0 *.nix
|
|
||||||
|
|
||||||
# add generation comment to flake.nix
|
#echo "searching generations"
|
||||||
gen=$(nixos-rebuild list-generations | grep current)
|
# your hostname (flake target)
|
||||||
if sed -n '3p' flake.nix | grep -q '^# generation:'; then
|
hostname="$(hostname)"
|
||||||
# replace the comment on line 3
|
#old_gen=$(nixos-rebuild list-generations | grep current | awk '{print $1}')
|
||||||
sed -i "3s/^# generation:.*/# generation: $gen/" flake.nix
|
#gen=$((old_gen + 1))
|
||||||
else
|
#echo "gen $old_gen --> gen $gen"
|
||||||
# insert comment on line 3
|
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
sed -i "3i# generation: $gen" flake.nix
|
nix_dir="$HOME/.nix"
|
||||||
|
logfile="$nix_dir/.nixos-switch-log"
|
||||||
|
|
||||||
|
|
||||||
|
pushd "$nix_dir" >/dev/null
|
||||||
|
|
||||||
|
# function to get current nixos generation
|
||||||
|
#get_current_generation() {
|
||||||
|
# nixos-rebuild list-generations
|
||||||
|
#}
|
||||||
|
|
||||||
|
echo "diffs:"
|
||||||
|
git diff
|
||||||
|
echo ""
|
||||||
|
echo "files:"
|
||||||
|
git status --short
|
||||||
|
read -rp "commit message: " commit_msg
|
||||||
|
echo "rebuilding nixos with flake.nix..."
|
||||||
|
if ! sudo nixos-rebuild switch --flake .#"$hostname" 2>&1 | tee "$logfile"; then
|
||||||
|
echo "rebuild failed; exited with no commit"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
#if sed -n '3p' flake.nix | grep -q '^# generation:'; then
|
||||||
|
# # replace the comment on line 3
|
||||||
|
# sed -i "3s|^# generation:.*|# generation: $gen, timestamp: $timestamp|" flake.nix
|
||||||
|
#else
|
||||||
|
# # insert comment on line 3
|
||||||
|
# sed -i "3i# generation: $gen, timestamp: $timestamp" flake.nix
|
||||||
|
#fi
|
||||||
|
echo "committing..."
|
||||||
|
git add $nix_dir
|
||||||
|
git commit -m "$commit_msg"
|
||||||
|
echo "flake rebuild and commit fin"
|
||||||
|
|
||||||
git diff -U0 $(find . -name '*.nix')
|
|
||||||
|
|
||||||
echo "nixos rebuilding..."
|
|
||||||
#sudo nixos-rebuild switch --flake ~/.nix#snowbelle &>.nixos-switch-log || (
|
|
||||||
# cat .nixos-switch-log | grep --color error && false)
|
|
||||||
sudo nixos-rebuild switch --flake ~/.nix#snowbelle 2>&1 | tee .nixos-switch-log | grep --color=always -E "error|$" && true
|
|
||||||
|
|
||||||
git commit -am "$gen"
|
|
||||||
popd
|
|
||||||
|
|||||||
26
bin/rebuild_legacy.sh
Executable file
26
bin/rebuild_legacy.sh
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
pushd ~/.nix
|
||||||
|
# nvim flake.nix
|
||||||
|
# alejandra . &>/dev/null
|
||||||
|
# git diff -U0 *.nix
|
||||||
|
|
||||||
|
# add generation comment to flake.nix
|
||||||
|
gen=$(nixos-rebuild list-generations | grep current)
|
||||||
|
if sed -n '3p' flake.nix | grep -q '^# generation:'; then
|
||||||
|
# replace the comment on line 3
|
||||||
|
sed -i "3s/^# generation:.*/# generation: $gen/" flake.nix
|
||||||
|
else
|
||||||
|
# insert comment on line 3
|
||||||
|
sed -i "3i# generation: $gen" flake.nix
|
||||||
|
fi
|
||||||
|
|
||||||
|
git diff -U0 $(find . -name '*.nix')
|
||||||
|
|
||||||
|
echo "nixos rebuilding..."
|
||||||
|
#sudo nixos-rebuild switch --flake ~/.nix#snowbelle &>.nixos-switch-log || (
|
||||||
|
# cat .nixos-switch-log | grep --color error && false)
|
||||||
|
sudo nixos-rebuild switch --flake ~/.nix#snowbelle 2>&1 | tee .nixos-switch-log | grep --color=always -E "error|$" && true
|
||||||
|
|
||||||
|
git commit -am "$gen"
|
||||||
|
popd
|
||||||
110
flake.lock
generated
110
flake.lock
generated
@@ -1,5 +1,42 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"flake-compat": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1751685974,
|
||||||
|
"narHash": "sha256-NKw96t+BgHIYzHUjkTK95FqYRVKB8DHpVhefWSz/kTw=",
|
||||||
|
"ref": "refs/heads/main",
|
||||||
|
"rev": "549f2762aebeff29a2e5ece7a7dc0f955281a1d1",
|
||||||
|
"revCount": 92,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.lix.systems/lix-project/flake-compat.git"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.lix.systems/lix-project/flake-compat.git"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"nvf",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1759362264,
|
||||||
|
"narHash": "sha256-wfG0S7pltlYyZTM+qqlhJ7GMw2fTF4mLKCIVhLii/4M=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "758cf7296bee11f1706a574c77d072b8a7baa881",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"home-manager": {
|
"home-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -21,13 +58,28 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mnw": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1758834834,
|
||||||
|
"narHash": "sha256-Y7IvY4F8vajZyp3WGf+KaiIVwondEkMFkt92Cr9NZmg=",
|
||||||
|
"owner": "Gerg-L",
|
||||||
|
"repo": "mnw",
|
||||||
|
"rev": "cfbc7d1cc832e318d0863a5fc91d940a96034001",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "Gerg-L",
|
||||||
|
"repo": "mnw",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1759735786,
|
"lastModified": 1760139962,
|
||||||
"narHash": "sha256-a0+h02lyP2KwSNrZz4wLJTu9ikujNsTWIC874Bv7IJ0=",
|
"narHash": "sha256-4xggC56Rub3WInz5eD7EZWXuLXpNvJiUPahGtMkwtuc=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "20c4598c84a671783f741e02bf05cbfaf4907cff",
|
"rev": "7e297ddff44a3cc93673bb38d0374df8d0ad73e4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -38,11 +90,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1759831965,
|
"lastModified": 1760284886,
|
||||||
"narHash": "sha256-vgPm2xjOmKdZ0xKA6yLXPJpjOtQPHfaZDRtH+47XEBo=",
|
"narHash": "sha256-TK9Kr0BYBQ/1P5kAsnNQhmWWKgmZXwUQr4ZMjCzWf2c=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "c9b6fb798541223bbb396d287d16f43520250518",
|
"rev": "cf3f5c4def3c7b5f1fc012b3d839575dbe552d43",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -51,11 +103,36 @@
|
|||||||
"type": "indirect"
|
"type": "indirect"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nvf": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"mnw": "mnw",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1760153667,
|
||||||
|
"narHash": "sha256-F7KmXT/Izse6Q6CkD5GCImoGPaDJxl03Kd7eD+eY/bU=",
|
||||||
|
"owner": "NotAShelf",
|
||||||
|
"repo": "nvf",
|
||||||
|
"rev": "9df9d51fd9fc8f9a8fc377f984ea3b7ae796172d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NotAShelf",
|
||||||
|
"repo": "nvf",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||||
|
"nvf": "nvf",
|
||||||
"sops-nix": "sops-nix",
|
"sops-nix": "sops-nix",
|
||||||
"vpn-confinement": "vpn-confinement"
|
"vpn-confinement": "vpn-confinement"
|
||||||
}
|
}
|
||||||
@@ -67,11 +144,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1759635238,
|
"lastModified": 1760240450,
|
||||||
"narHash": "sha256-UvzKi02LMFP74csFfwLPAZ0mrE7k6EiYaKecplyX9Qk=",
|
"narHash": "sha256-sa9bS9jSyc4vH0jSWrUsPGdqtMvDwmkLg971ntWOo2U=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "6e5a38e08a2c31ae687504196a230ae00ea95133",
|
"rev": "41fd1f7570c89f645ee0ada0be4e2d3c4b169549",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -80,6 +157,21 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"vpn-confinement": {
|
"vpn-confinement": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1759956062,
|
"lastModified": 1759956062,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# flake for blakes nixos config
|
# flake for blakes nixos config
|
||||||
# define new devices in outputs
|
# define new devices in outputs
|
||||||
# generation: 341 current 2025-10-12 10:38:28 25.05.20251006.20c4598 6.12.50 *
|
# generation: 378, timestamp: 2025-10-12 19:57:35
|
||||||
{
|
{
|
||||||
description = "blakes nix config";
|
description = "blakes nix config";
|
||||||
inputs = {
|
inputs = {
|
||||||
@@ -17,6 +17,10 @@
|
|||||||
vpn-confinement = {
|
vpn-confinement = {
|
||||||
url = "github:Maroka-chan/VPN-Confinement";
|
url = "github:Maroka-chan/VPN-Confinement";
|
||||||
};
|
};
|
||||||
|
nvf = {
|
||||||
|
url = "github:NotAShelf/nvf";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
outputs = { self, nixpkgs, nixpkgs-unstable, ... }@inputs:
|
outputs = { self, nixpkgs, nixpkgs-unstable, ... }@inputs:
|
||||||
let
|
let
|
||||||
|
|||||||
@@ -25,30 +25,31 @@ in
|
|||||||
tailscale.enable = true;
|
tailscale.enable = true;
|
||||||
nvidia.enable = true;
|
nvidia.enable = true;
|
||||||
};
|
};
|
||||||
homelab = {
|
fileshare = {
|
||||||
enable = true;
|
|
||||||
zfs.enable = true;
|
zfs.enable = true;
|
||||||
smb.enable = true;
|
smb.enable = true;
|
||||||
nfs.enable = true;
|
nfs.enable = true;
|
||||||
nginx-proxy.enable = true;
|
|
||||||
};
|
};
|
||||||
|
homelab.enable = true;
|
||||||
services = {
|
services = {
|
||||||
jellyfin.enable = true;
|
|
||||||
audiobookshelf.enable = true;
|
|
||||||
vaultwarden.enable = true;
|
|
||||||
gitea.enable = true;
|
gitea.enable = true;
|
||||||
glance.enable = true;
|
glance.enable = true;
|
||||||
qbittorrent.enable = true;
|
|
||||||
immich.enable = true;
|
immich.enable = true;
|
||||||
hass.enable = true;
|
hass.enable = true;
|
||||||
zigbee2mqtt.enable = true;
|
jellyfin.enable = true;
|
||||||
mosquitto.enable = true;
|
audiobookshelf.enable = true;
|
||||||
|
yacreader.enable = true;
|
||||||
|
qbittorrent.enable = true;
|
||||||
|
sonarr.enable = true;
|
||||||
|
radarr.enable = true;
|
||||||
|
bazarr.enable = true;
|
||||||
prowlarr.enable = true;
|
prowlarr.enable = true;
|
||||||
flaresolverr.enable = true;
|
flaresolverr.enable = true;
|
||||||
bazarr.enable = true;
|
zigbee2mqtt.enable = true;
|
||||||
radarr.enable = true;
|
mosquitto.enable = true;
|
||||||
sonarr.enable = true;
|
caddy.enable = true;
|
||||||
uptime-kuma.enable = true;
|
uptime-kuma.enable = true;
|
||||||
|
vaultwarden.enable = true;
|
||||||
};
|
};
|
||||||
gameservers = {
|
gameservers = {
|
||||||
minecraft_recpro.enable = true;
|
minecraft_recpro.enable = true;
|
||||||
@@ -111,6 +112,7 @@ in
|
|||||||
curl
|
curl
|
||||||
fzf
|
fzf
|
||||||
fd
|
fd
|
||||||
|
alejandra
|
||||||
tree
|
tree
|
||||||
vim
|
vim
|
||||||
lf
|
lf
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ in
|
|||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
home = cfg.data_dir;
|
home = cfg.data_dir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
group = "${service}";
|
group = service;
|
||||||
extraGroups = [ "media" ];
|
extraGroups = [ "media" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,8 +58,8 @@ in
|
|||||||
services.${service} = {
|
services.${service} = {
|
||||||
enable = true;
|
enable = true;
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
user = "${service}";
|
user = service;
|
||||||
group = "${service}";
|
group = service;
|
||||||
listenPort = cfg.port;
|
listenPort = cfg.port;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,14 +71,12 @@ in
|
|||||||
# # open firewall
|
# # open firewall
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
extraConfig = ''
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
locations."/" = {
|
'';
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# add to glance
|
# add to glance
|
||||||
@@ -48,7 +48,7 @@ in
|
|||||||
description = "${service} server user";
|
description = "${service} server user";
|
||||||
uid = lib.mkForce cfg.ids;
|
uid = lib.mkForce cfg.ids;
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
group = "${service}";
|
group = service;
|
||||||
};
|
};
|
||||||
|
|
||||||
# enable the ${service} service
|
# enable the ${service} service
|
||||||
@@ -60,21 +60,19 @@ in
|
|||||||
|
|
||||||
# override umask to make permissions work out
|
# override umask to make permissions work out
|
||||||
systemd.services.${service}.serviceConfig = {
|
systemd.services.${service}.serviceConfig = {
|
||||||
User = "${service}";
|
User = service;
|
||||||
Group = "${service}";
|
Group = service;
|
||||||
};
|
};
|
||||||
|
|
||||||
# # open firewall
|
# # open firewall
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
extraConfig = ''
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
locations."/" = {
|
'';
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ in
|
|||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
home = cfg.data_dir;
|
home = cfg.data_dir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
group = "${service}";
|
group = service;
|
||||||
extraGroups = [ "media" ];
|
extraGroups = [ "media" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -66,21 +66,19 @@ in
|
|||||||
# override umask to make permissions work out
|
# override umask to make permissions work out
|
||||||
systemd.services.${service}.serviceConfig = {
|
systemd.services.${service}.serviceConfig = {
|
||||||
UMask = lib.mkForce "0007";
|
UMask = lib.mkForce "0007";
|
||||||
User = "${service}";
|
User = service;
|
||||||
Group = "${service}";
|
Group = service;
|
||||||
};
|
};
|
||||||
|
|
||||||
# # open firewall
|
# # open firewall
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
extraConfig = ''
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
locations."/" = {
|
'';
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# add to glance
|
# add to glance
|
||||||
@@ -50,7 +50,7 @@ in
|
|||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
home = cfg.data_dir;
|
home = cfg.data_dir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
group = "${service}";
|
group = service;
|
||||||
extraGroups = [ "media" ];
|
extraGroups = [ "media" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,8 +58,8 @@ in
|
|||||||
services.${service} = {
|
services.${service} = {
|
||||||
enable = true;
|
enable = true;
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
user = "${service}";
|
user = service;
|
||||||
group = "${service}";
|
group = service;
|
||||||
dataDir = cfg.data_dir;
|
dataDir = cfg.data_dir;
|
||||||
settings = {
|
settings = {
|
||||||
server.port = cfg.port;
|
server.port = cfg.port;
|
||||||
@@ -69,21 +69,19 @@ in
|
|||||||
# override umask to make permissions work out
|
# override umask to make permissions work out
|
||||||
systemd.services.${service}.serviceConfig = {
|
systemd.services.${service}.serviceConfig = {
|
||||||
UMask = lib.mkForce "0007";
|
UMask = lib.mkForce "0007";
|
||||||
# User = "${service}";
|
# User = service;
|
||||||
# Group = "${service}";
|
# Group = service;
|
||||||
};
|
};
|
||||||
|
|
||||||
# # open firewall
|
# # open firewall
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
extraConfig = ''
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
locations."/" = {
|
'';
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# add to glance
|
# add to glance
|
||||||
@@ -50,7 +50,7 @@ in
|
|||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
home = cfg.data_dir;
|
home = cfg.data_dir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
group = "${service}";
|
group = service;
|
||||||
extraGroups = [ "media" ];
|
extraGroups = [ "media" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,8 +58,8 @@ in
|
|||||||
services.${service} = {
|
services.${service} = {
|
||||||
enable = true;
|
enable = true;
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
user = "${service}";
|
user = service;
|
||||||
group = "${service}";
|
group = service;
|
||||||
dataDir = cfg.data_dir;
|
dataDir = cfg.data_dir;
|
||||||
settings = {
|
settings = {
|
||||||
server.port = cfg.port;
|
server.port = cfg.port;
|
||||||
@@ -74,14 +74,12 @@ in
|
|||||||
# # open firewall
|
# # open firewall
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
extraConfig = ''
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
locations."/" = {
|
'';
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# add to glance
|
# add to glance
|
||||||
101
modules/homelab/audiobookshelf/default.nix
Normal file
101
modules/homelab/audiobookshelf/default.nix
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
service = "audiobookshelf";
|
||||||
|
cfg = config.modules.services.${service};
|
||||||
|
sec = config.sops.secrets;
|
||||||
|
homelab = config.modules.homelab;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.modules.services.${service} = {
|
||||||
|
enable = lib.mkEnableOption "enables ${service}";
|
||||||
|
|
||||||
|
# set port options
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 7101;
|
||||||
|
description = "set port for ${service} (default: ${toString cfg.port}";
|
||||||
|
};
|
||||||
|
url = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "abs.${homelab.base_domain}";
|
||||||
|
description = "set domain for ${service}";
|
||||||
|
};
|
||||||
|
data_dir = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/var/lib/${service}";
|
||||||
|
description = "set data directory for ${service}";
|
||||||
|
};
|
||||||
|
ids = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = cfg.port;
|
||||||
|
description = "set uid and pid of ${service} user (matches port by default)";
|
||||||
|
};
|
||||||
|
backup = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "enable backups for ${service}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
|
# declare ${service} group
|
||||||
|
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||||
|
|
||||||
|
# declare ${service} user
|
||||||
|
users.users.${service} = {
|
||||||
|
description = "${service} server user";
|
||||||
|
uid = lib.mkForce cfg.ids;
|
||||||
|
isSystemUser = true;
|
||||||
|
# home = cfg.data_dir;
|
||||||
|
createHome = true;
|
||||||
|
group = service;
|
||||||
|
extraGroups = [ "media" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# enable the ${service} service
|
||||||
|
services.${service} = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
user = service;
|
||||||
|
group = service;
|
||||||
|
# dataDir = cfg.data_dir;
|
||||||
|
host = "0.0.0.0";
|
||||||
|
port = cfg.port;
|
||||||
|
};
|
||||||
|
|
||||||
|
# override umask to make permissions work out
|
||||||
|
systemd.services.${service}.serviceConfig = {
|
||||||
|
UMask = lib.mkForce "0007";
|
||||||
|
# User = service;
|
||||||
|
# Group = service;
|
||||||
|
};
|
||||||
|
|
||||||
|
# # open firewall
|
||||||
|
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
|
# add to caddy for reverse proxy
|
||||||
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
|
serverAliases = [ "abs.${homelab.public_domain}" ];
|
||||||
|
extraConfig = ''
|
||||||
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
|
reverse_proxy 127.0.0.1:${toString cfg.port} {
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# add to glance public service
|
||||||
|
modules.services.glance.links.mediastack = [{
|
||||||
|
title = service;
|
||||||
|
url = "https://abs.${homelab.public_domain}";
|
||||||
|
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
||||||
|
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
||||||
|
icon = "di:${service}"; }];
|
||||||
|
|
||||||
|
# add to backups
|
||||||
|
modules.system.backups.baks = {
|
||||||
|
${service} = { paths = [ cfg.data_dir ]; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
98
modules/homelab/caddy/default.nix
Normal file
98
modules/homelab/caddy/default.nix
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
service = "caddy";
|
||||||
|
cfg = config.modules.services.${service};
|
||||||
|
sec = config.sops.secrets;
|
||||||
|
homelab = config.modules.homelab;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.modules.services.${service} = {
|
||||||
|
enable = lib.mkEnableOption "enables ${service}";
|
||||||
|
|
||||||
|
# set port options
|
||||||
|
data_dir = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/var/lib/${service}";
|
||||||
|
description = "set data directory for ${service}";
|
||||||
|
};
|
||||||
|
backup = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "enable backups for ${service}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
|
# declare ${service} group
|
||||||
|
users.groups.${service} = {};
|
||||||
|
|
||||||
|
# declare ${service} user
|
||||||
|
users.users.${service} = {
|
||||||
|
description = "${service} server user";
|
||||||
|
isSystemUser = true;
|
||||||
|
home = cfg.data_dir;
|
||||||
|
createHome = true;
|
||||||
|
group = service;
|
||||||
|
extraGroups = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
# enable the ${service} service
|
||||||
|
services.${service} = {
|
||||||
|
enable = true;
|
||||||
|
user = service;
|
||||||
|
group = service;
|
||||||
|
dataDir = cfg.data_dir;
|
||||||
|
email = "me@blakedheld.xyz";
|
||||||
|
globalConfig = ''
|
||||||
|
auto_https ignore_loaded_certs
|
||||||
|
'';
|
||||||
|
|
||||||
|
virtualHosts."key.${homelab.public_domain}" = {
|
||||||
|
extraConfig = ''
|
||||||
|
root * /var/www/keys
|
||||||
|
file_server
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# enable acme for auto ssl certs with lets encrypt
|
||||||
|
security.acme = {
|
||||||
|
acceptTerms = true;
|
||||||
|
defaults.email = "me@blakedheld.xyz";
|
||||||
|
};
|
||||||
|
|
||||||
|
# override umask to make permissions work out
|
||||||
|
systemd.services.${service}.serviceConfig = {
|
||||||
|
UMask = lib.mkForce "0007";
|
||||||
|
};
|
||||||
|
|
||||||
|
# open firewall
|
||||||
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
|
|
||||||
|
sops.secrets = {
|
||||||
|
"ssl_blakedheld_crt" = {
|
||||||
|
owner = "caddy";
|
||||||
|
group = "caddy";
|
||||||
|
path = "/etc/ssl/blakedheld.xyz.crt";
|
||||||
|
};
|
||||||
|
"ssl_blakedheld_key" = {
|
||||||
|
owner = "caddy";
|
||||||
|
group = "caddy";
|
||||||
|
path = "/etc/ssl/blakedheld.xyz.key";
|
||||||
|
};
|
||||||
|
"klefki_pub.asc" = {
|
||||||
|
owner = "caddy";
|
||||||
|
group = "caddy";
|
||||||
|
path = "/var/www/keys/klefki_pub.asc";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# add to backups
|
||||||
|
modules.system.backups.baks = {
|
||||||
|
${service} = { paths = [ cfg.data_dir ]; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -39,11 +39,27 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# the order determines the order in glance :3
|
||||||
imports = [
|
imports = [
|
||||||
./services
|
./fileshare
|
||||||
./shares/nfs.nix
|
./caddy
|
||||||
./shares/smb.nix
|
./home/zigbee2mqtt
|
||||||
./shares/zfs.nix
|
./vaultwarden
|
||||||
|
./gitea
|
||||||
|
./home/homeassistant
|
||||||
|
./immich
|
||||||
|
./arr/bazarr
|
||||||
|
./arr/prowlarr
|
||||||
|
./arr/radarr
|
||||||
|
./qbittorrent
|
||||||
|
./arr/sonarr
|
||||||
|
./yacreader
|
||||||
|
./audiobookshelf
|
||||||
|
./jellyfin
|
||||||
|
./arr/flaresolverr
|
||||||
|
./home/mosquitto
|
||||||
|
./uptime-kuma
|
||||||
|
./glance
|
||||||
];
|
];
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
|||||||
13
modules/homelab/fileshare/default.nix
Normal file
13
modules/homelab/fileshare/default.nix
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
# services show up in glance in reverse import order lmao
|
||||||
|
imports = [
|
||||||
|
./shares/nfs.nix
|
||||||
|
./shares/smb.nix
|
||||||
|
./shares/zfs.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -1,14 +1,17 @@
|
|||||||
{ pkgs, config, lib, ... }:
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
# define nfs exports
|
# define nfs exports
|
||||||
let
|
let
|
||||||
cfg = config.modules.homelab.nfs;
|
cfg = config.modules.fileshare.nfs;
|
||||||
nfs_exports = ''
|
nfs_exports = ''
|
||||||
/holocron/vault *(rw,sync,no_subtree_check,no_root_squash)
|
|
||||||
/holocron/media *(ro,sync,no_subtree_check)
|
/holocron/media *(ro,sync,no_subtree_check)
|
||||||
'';
|
'';
|
||||||
in
|
#/holocron/vault *(rw,sync,no_subtree_check,no_root_squash)
|
||||||
{
|
in {
|
||||||
options.modules.homelab.nfs = {
|
options.modules.homelab.nfs = {
|
||||||
enable = lib.mkEnableOption "enables nfs";
|
enable = lib.mkEnableOption "enables nfs";
|
||||||
};
|
};
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
{ pkgs, config, lib, ... }:
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
# define smb shares
|
# define smb shares
|
||||||
let
|
let
|
||||||
cfg = config.modules.homelab.smb;
|
cfg = config.modules.fileshare.smb;
|
||||||
smb_shares = {
|
smb_shares = {
|
||||||
vault = {
|
vault = {
|
||||||
path = "/holocron/vault";
|
path = "/holocron/vault";
|
||||||
@@ -17,8 +21,7 @@ let
|
|||||||
guestOk = false;
|
guestOk = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
in {
|
||||||
{
|
|
||||||
options.modules.homelab.smb = {
|
options.modules.homelab.smb = {
|
||||||
enable = lib.mkEnableOption "enables smb";
|
enable = lib.mkEnableOption "enables smb";
|
||||||
};
|
};
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
{ pkgs, config, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.modules.homelab.zfs;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
cfg = config.modules.fileshare.zfs;
|
||||||
|
in {
|
||||||
options.modules.homelab.zfs = {
|
options.modules.homelab.zfs = {
|
||||||
enable = lib.mkEnableOption "enables zfs";
|
enable = lib.mkEnableOption "enables zfs";
|
||||||
};
|
};
|
||||||
@@ -13,8 +15,8 @@ in
|
|||||||
networking.hostId = "3e6e7055";
|
networking.hostId = "3e6e7055";
|
||||||
|
|
||||||
# enable zfs support
|
# enable zfs support
|
||||||
boot.kernelModules = [ "zfs" ];
|
boot.kernelModules = ["zfs"];
|
||||||
boot.supportedFilesystems = [ "zfs" ];
|
boot.supportedFilesystems = ["zfs"];
|
||||||
|
|
||||||
# enable smart monitoring
|
# enable smart monitoring
|
||||||
services.smartd.enable = true;
|
services.smartd.enable = true;
|
||||||
@@ -28,8 +30,7 @@ in
|
|||||||
fileSystems."/holocron" = {
|
fileSystems."/holocron" = {
|
||||||
device = "holocron";
|
device = "holocron";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
options = [ "nofail" ];
|
options = ["nofail"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ in
|
|||||||
shell = pkgs.bash;
|
shell = pkgs.bash;
|
||||||
home = cfg.data_dir;
|
home = cfg.data_dir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
group = "${service}";
|
group = service;
|
||||||
extraGroups = [];
|
extraGroups = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,7 +69,8 @@ in
|
|||||||
appName = "gitea";
|
appName = "gitea";
|
||||||
settings = {
|
settings = {
|
||||||
server = {
|
server = {
|
||||||
DOMAIN = "https://git.blakedheld.xyz";
|
ROOT_URL = "https://git.blakedheld.xyz";
|
||||||
|
DOMAIN = "git.blakedheld.xyz";
|
||||||
HTTP_PORT = cfg.port;
|
HTTP_PORT = cfg.port;
|
||||||
SSH_PORT = cfg.ssh_port;
|
SSH_PORT = cfg.ssh_port;
|
||||||
START_SSH_SERVER = true;
|
START_SSH_SERVER = true;
|
||||||
@@ -90,41 +91,15 @@ in
|
|||||||
# open firewall
|
# open firewall
|
||||||
networking.firewall.allowedTCPPorts = [ cfg.port cfg.ssh_port ];
|
networking.firewall.allowedTCPPorts = [ cfg.port cfg.ssh_port ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
serverAliases = [ "git.${homelab.public_domain}" ];
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
client_max_body_size 512M;
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
proxy_set_header Connection $http_connection;
|
reverse_proxy localhost:${toString cfg.port} {
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
}
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
|
||||||
# external reverse proxy entry
|
|
||||||
services.nginx.virtualHosts."git.blakedheld.xyz" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
extraConfig = ''
|
|
||||||
client_max_body_size 512M;
|
|
||||||
proxy_set_header Connection $http_connection;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# add to glance
|
# add to glance
|
||||||
modules.services.glance.links.services = [{
|
modules.services.glance.links.services = [{
|
||||||
@@ -134,10 +109,11 @@ in
|
|||||||
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
||||||
icon = "di:${service}"; }];
|
icon = "di:${service}"; }];
|
||||||
|
|
||||||
|
# manage secrets with sops
|
||||||
sops.secrets = {
|
sops.secrets = {
|
||||||
"${service}_database_password" = {
|
"${service}_database_password" = {
|
||||||
owner = "${service}";
|
owner = service;
|
||||||
group = "${service}";
|
group = service;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
306
modules/homelab/glance/default.nix
Normal file
306
modules/homelab/glance/default.nix
Normal file
@@ -0,0 +1,306 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
/*
|
||||||
|
this is a wrapper module for glance that allows you to
|
||||||
|
to pass monitor entries in with nix, all declaratively!
|
||||||
|
|
||||||
|
| <8yy> |
|
||||||
|
V V
|
||||||
|
# add to glance
|
||||||
|
modules.services.glance.links.mediastack = [{
|
||||||
|
title = service;
|
||||||
|
url = "https://${cfg.url}";
|
||||||
|
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
||||||
|
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
||||||
|
icon = "di:${service}";
|
||||||
|
allow-insecure = true; }];
|
||||||
|
*/
|
||||||
|
|
||||||
|
let
|
||||||
|
service = "glance";
|
||||||
|
cfg = config.modules.services.${service};
|
||||||
|
sec = config.sops.secrets;
|
||||||
|
homelab = config.modules.homelab;
|
||||||
|
|
||||||
|
uptimekuma_url = "localhost:7901";
|
||||||
|
uptimekuma_page = "glance";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.modules.services.${service} = {
|
||||||
|
enable = lib.mkEnableOption "enables ${service}";
|
||||||
|
|
||||||
|
# set port options
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 7700;
|
||||||
|
description = "set port for ${service} (default: ${toString cfg.port}";
|
||||||
|
};
|
||||||
|
url = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "${homelab.base_domain}";
|
||||||
|
description = "set domain for ${service}";
|
||||||
|
};
|
||||||
|
data_dir = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/var/lib/${service}";
|
||||||
|
description = "set data directory for ${service}";
|
||||||
|
};
|
||||||
|
ids = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = cfg.port;
|
||||||
|
description = "set uid and pid of ${service} user (matches port by default)";
|
||||||
|
};
|
||||||
|
backup = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "enable backups for ${service}";
|
||||||
|
};
|
||||||
|
links = {
|
||||||
|
services = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.attrs;
|
||||||
|
default = [ ];
|
||||||
|
description = "list of links for ${service}";
|
||||||
|
};
|
||||||
|
mediastack = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.attrs;
|
||||||
|
default = [ ];
|
||||||
|
description = "list of links for ${service}";
|
||||||
|
};
|
||||||
|
system = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.attrs;
|
||||||
|
default = [ ];
|
||||||
|
description = "list of links for ${service}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
|
# declare ${service} group
|
||||||
|
users.groups.${service} = {
|
||||||
|
gid = lib.mkForce cfg.ids;
|
||||||
|
};
|
||||||
|
|
||||||
|
# declare ${service} user
|
||||||
|
users.users.${service} = {
|
||||||
|
description = "${service} server user";
|
||||||
|
uid = lib.mkForce cfg.ids;
|
||||||
|
isSystemUser = true;
|
||||||
|
home = cfg.data_dir;
|
||||||
|
createHome = true;
|
||||||
|
group = service;
|
||||||
|
extraGroups = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.${service} = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
host = "0.0.0.0";
|
||||||
|
port = cfg.port;
|
||||||
|
assets-path = "${cfg.data_dir}/assets";
|
||||||
|
};
|
||||||
|
# theme = {custom-css-file = "/assets/user.css";};
|
||||||
|
auth = {
|
||||||
|
secret-key = "+mYVAc1uO85hUUz5Ij6Lpelv1RqiLlneYqZD5Jv45buoF2+LZtIt2okRrbFCppiRQbqXkGoRMtSI0bROg4uFUw==";
|
||||||
|
users = {
|
||||||
|
blake = {
|
||||||
|
password-hash = "$2a$10$RwPCkcto35DCp4vNTDpH6.G3TpecPJ/zUL1jI93uzr.lg6v233Sie";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
branding = {
|
||||||
|
logo-url = "/assets/icons/snowbelle.png";
|
||||||
|
favicon-url = "/assets/icons/favicon.ico";
|
||||||
|
};
|
||||||
|
pages = [
|
||||||
|
{
|
||||||
|
name = "snowbelle";
|
||||||
|
hide-desktop-navigation = true;
|
||||||
|
columns = [
|
||||||
|
{
|
||||||
|
size = "small";
|
||||||
|
widgets = [
|
||||||
|
{
|
||||||
|
type = "calendar";
|
||||||
|
first-day-of-week = "monday";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "server-stats";
|
||||||
|
servers = [
|
||||||
|
{
|
||||||
|
type = "local";
|
||||||
|
name = "snowbelle";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "clock";
|
||||||
|
hour-format = "24h";
|
||||||
|
timezones = [
|
||||||
|
{
|
||||||
|
timezone = "America/Chicago";
|
||||||
|
label = "HTX";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
timezone = "America/Denver";
|
||||||
|
label = "AF";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "twitch-channels";
|
||||||
|
channels = [
|
||||||
|
"mang0"
|
||||||
|
"SaltSSBM"
|
||||||
|
"thewaffle77"
|
||||||
|
"ironmouse"
|
||||||
|
"linustech"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
size = "full";
|
||||||
|
widgets = [
|
||||||
|
{
|
||||||
|
type = "search";
|
||||||
|
autofocus = true;
|
||||||
|
search-engine = "https://www.ecosia.org/search?q={QUERY}";
|
||||||
|
new-tab = true;
|
||||||
|
bangs = [
|
||||||
|
{
|
||||||
|
title = "YouTube";
|
||||||
|
shortcut = "!y";
|
||||||
|
url = "https://www.youtube.com/results?search_query={QUERY}";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
title = "Google";
|
||||||
|
shortcut = "!g";
|
||||||
|
url = "https://www.google.com/search?q={QUERY}";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
title = "Github";
|
||||||
|
shortcut = "!gh";
|
||||||
|
url = "https://github.com/search?q={QUERY}&type=repositories";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "monitor";
|
||||||
|
cache = "1m";
|
||||||
|
title = "services";
|
||||||
|
sites = cfg.links.services;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "monitor";
|
||||||
|
cache = "1m";
|
||||||
|
title = "mediastack";
|
||||||
|
sites = cfg.links.mediastack;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "monitor";
|
||||||
|
cache = "1m";
|
||||||
|
title = "system";
|
||||||
|
sites = cfg.links.system;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "custom-api";
|
||||||
|
title = "recpro";
|
||||||
|
url = "https://api.mcstatus.io/v2/status/java/mc.recoil.pro";
|
||||||
|
cache = "5s";
|
||||||
|
template = "<div style=\"display:flex; align-items:center; gap:12px;\">\n <div style=\"width:40px; height:40px; flex-shrink:0; border-radius:4px; display:flex; justify-content:center; align-items:center; overflow:hidden;\">\n {{ if .JSON.Bool \"online\" }}\n <img src=\"{{ .JSON.String \"icon\" | safeURL }}\" width=\"64\" height=\"64\" style=\"object-fit:contain;\">\n {{ else }}\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" style=\"width:32px; height:32px; opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M1 5.25A2.25 2.25 0 0 1 3.25 3h13.5A2.25 2.25 0 0 1 19 5.25v9.5A2.25 2.25 0 0 1 16.75 17H3.25A2.25 2.25 0 0 1 1 14.75v-9.5Zm1.5 5.81v3.69c0 .414.336.75.75.75h13.5a.75.75 0 0 0 .75-.75v-2.69l-2.22-2.219a.75.75 0 0 0-1.06 0l-1.91 1.909.47.47a.75.75 0 1 1-1.06 1.06L6.53 8.091a.75.75 0 0 0-1.06 0l-2.97 2.97ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ end }}\n </div>\n\n <div style=\"flex-grow:1; min-width:0;\">\n <a class=\"size-h4 block text-truncate color-highlight\">\n {{ .JSON.String \"host\" }}\n {{ if .JSON.Bool \"online\" }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-positive); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Online\"\n ></span>\n {{ else }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-negative); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Offline\"\n ></span>\n {{ end }}\n </a>\n\n <ul class=\"list-horizontal-text\">\n <li>\n {{ if .JSON.Bool \"online\" }}\n <span>{{ .JSON.String \"version.name_clean\" }}</span>\n {{ else }}\n <span>Offline</span>\n {{ end }}\n </li>\n {{ if .JSON.Bool \"online\" }}\n <li data-popover-type=\"html\">\n <div data-popover-html>\n {{ range .JSON.Array \"players.list\" }}{{ .String \"name_clean\" }}<br>{{ end }}\n </div>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ .JSON.Int \"players.online\" | formatNumber }}/{{ .JSON.Int \"players.max\" | formatNumber }} players\n </p>\n </li>\n {{ else }}\n <li>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n 0 players\n </p>\n </li>\n {{ end }}\n </ul>\n </div>\n</div>";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
size = "small";
|
||||||
|
widgets = [
|
||||||
|
{
|
||||||
|
type = "weather";
|
||||||
|
location = "Pearland, Texas, United States";
|
||||||
|
units = "imperial";
|
||||||
|
hour-format = "24h";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "markets";
|
||||||
|
markets = [
|
||||||
|
{
|
||||||
|
symbol = "SPY";
|
||||||
|
name = "S&P 500";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
symbol = "XMR-USD";
|
||||||
|
name = "Monero";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
symbol = "NVDA";
|
||||||
|
name = "NVIDIA";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
symbol = "AAPL";
|
||||||
|
name = "Apple";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
symbol = "MSFT";
|
||||||
|
name = "Microsoft";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "releases";
|
||||||
|
cache = "1d";
|
||||||
|
repositories = [
|
||||||
|
"glanceapp/glance"
|
||||||
|
"go-gitea/gitea"
|
||||||
|
"immich-app/immich"
|
||||||
|
"syncthing/syncthing"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# override umask to make permissions work out
|
||||||
|
systemd.services.${service}.serviceConfig = {
|
||||||
|
UMask = lib.mkForce "0007";
|
||||||
|
User = service;
|
||||||
|
Group = service;
|
||||||
|
};
|
||||||
|
|
||||||
|
# add to caddy for reverse proxy
|
||||||
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
|
# serverAliases = [ "${homelab.public_domain}" ];
|
||||||
|
extraConfig = ''
|
||||||
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# add to backups
|
||||||
|
modules.system.backups.baks = {
|
||||||
|
${service} = {
|
||||||
|
paths = [ cfg.data_dir ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# add to udr to glance
|
||||||
|
modules.services.glance.links.system = [{
|
||||||
|
title = "bebe";
|
||||||
|
url = "https://bebe.lan";
|
||||||
|
error-url = "https://10.10.0.1";
|
||||||
|
check-url = "https://10.10.0.1";
|
||||||
|
icon = "di:unifi";
|
||||||
|
allow-insecure = true; }];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -87,37 +87,13 @@ in
|
|||||||
# open firewall
|
# open firewall
|
||||||
networking.firewall.allowedTCPPorts = [ cfg.port 8123 ];
|
networking.firewall.allowedTCPPorts = [ cfg.port 8123 ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
serverAliases = [ "${service}.${homelab.public_domain}" ];
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
proxy_buffering off;
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
'';
|
'';
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
extraConfig =
|
|
||||||
"proxy_set_header Upgrade $http_upgrade;" +
|
|
||||||
"proxy_set_header Connection upgrade;"
|
|
||||||
;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# external reverse proxy entry
|
|
||||||
services.nginx.virtualHosts."${service}.blakedheld.xyz" = {
|
|
||||||
forceSSL = true;
|
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_buffering off;
|
|
||||||
'';
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
extraConfig =
|
|
||||||
"proxy_set_header Upgrade $http_upgrade;" +
|
|
||||||
"proxy_set_header Connection upgrade;"
|
|
||||||
;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# add to glance
|
# add to glance
|
||||||
@@ -137,9 +113,6 @@ in
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# here lies my tough, and I mean fucking tough, swing at
|
# here lies my tough, and I mean fucking tough, swing at
|
||||||
# getting this to work bare metal, ggs ill see you again
|
# getting this to work bare metal, ggs ill see you again
|
||||||
# - didnt take long
|
# - didnt take long
|
||||||
@@ -50,7 +50,7 @@ in
|
|||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
home = cfg.data_dir;
|
home = cfg.data_dir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
group = "${service}";
|
group = service;
|
||||||
extraGroups = [];
|
extraGroups = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -73,8 +73,8 @@ in
|
|||||||
# override umask to make permissions work out
|
# override umask to make permissions work out
|
||||||
systemd.services.${service}.serviceConfig = {
|
systemd.services.${service}.serviceConfig = {
|
||||||
UMask = lib.mkForce "0007";
|
UMask = lib.mkForce "0007";
|
||||||
User = "${service}";
|
User = service;
|
||||||
Group = "${service}";
|
Group = service;
|
||||||
};
|
};
|
||||||
|
|
||||||
# open firewall
|
# open firewall
|
||||||
@@ -82,8 +82,8 @@ in
|
|||||||
|
|
||||||
sops.secrets = {
|
sops.secrets = {
|
||||||
"${service}_hashed_passwd" = {
|
"${service}_hashed_passwd" = {
|
||||||
owner = "${service}";
|
owner = service;
|
||||||
group = "${service}";
|
group = service;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ in
|
|||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
home = cfg.data_dir;
|
home = cfg.data_dir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
group = "${service}";
|
group = service;
|
||||||
extraGroups = [];
|
extraGroups = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -87,38 +87,20 @@ in
|
|||||||
# override umask to make permissions work out
|
# override umask to make permissions work out
|
||||||
systemd.services.${service}.serviceConfig = {
|
systemd.services.${service}.serviceConfig = {
|
||||||
UMask = lib.mkForce "0007";
|
UMask = lib.mkForce "0007";
|
||||||
User = "${service}";
|
User = service;
|
||||||
Group = "${service}";
|
Group = service;
|
||||||
};
|
};
|
||||||
|
|
||||||
# # open firewall
|
# # open firewall
|
||||||
networking.firewall.allowedTCPPorts = [ cfg.port ];
|
networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
serverAliases = [ "z2m.${homelab.public_domain}" ];
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
proxy_buffering off;
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
'';
|
'';
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
locations."/api" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}/api";
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection upgrade;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# add to glance
|
# add to glance
|
||||||
@@ -131,8 +113,8 @@ in
|
|||||||
|
|
||||||
sops.secrets = {
|
sops.secrets = {
|
||||||
"mosquitto_passwd.yaml" = {
|
"mosquitto_passwd.yaml" = {
|
||||||
owner = "${service}";
|
owner = service;
|
||||||
group = "${service}";
|
group = service;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ in
|
|||||||
};
|
};
|
||||||
url = lib.mkOption {
|
url = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "$=photos.${homelab.base_domain}";
|
default = "photos.${homelab.base_domain}";
|
||||||
description = "set domain for ${service}";
|
description = "set domain for ${service}";
|
||||||
};
|
};
|
||||||
data_dir = lib.mkOption {
|
data_dir = lib.mkOption {
|
||||||
@@ -50,7 +50,7 @@ in
|
|||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
home = cfg.data_dir;
|
home = cfg.data_dir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
group = "${service}";
|
group = service;
|
||||||
extraGroups = [ "video" "render" ];
|
extraGroups = [ "video" "render" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -59,8 +59,8 @@ in
|
|||||||
enable = true;
|
enable = true;
|
||||||
package = inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.immich;
|
package = inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.immich;
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
user = "${service}";
|
user = service;
|
||||||
group = "${service}";
|
group = service;
|
||||||
mediaLocation = cfg.data_dir;
|
mediaLocation = cfg.data_dir;
|
||||||
host = "0.0.0.0";
|
host = "0.0.0.0";
|
||||||
port = cfg.port;
|
port = cfg.port;
|
||||||
@@ -75,25 +75,13 @@ in
|
|||||||
# # open firewall
|
# # open firewall
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
serverAliases = [ "photos.${homelab.public_domain}" ];
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
extraConfig = ''
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
locations."/" = {
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
'';
|
||||||
proxyWebsockets = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# external reverse proxy entry
|
|
||||||
services.nginx.virtualHosts."photos.blakedheld.xyz" = {
|
|
||||||
forceSSL = true;
|
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# add to glance
|
# add to glance
|
||||||
@@ -50,7 +50,7 @@ in
|
|||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
home = cfg.data_dir;
|
home = cfg.data_dir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
group = "${service}";
|
group = service;
|
||||||
extraGroups = [ "media" "video" "render" ];
|
extraGroups = [ "media" "video" "render" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,8 +58,8 @@ in
|
|||||||
services.${service} = {
|
services.${service} = {
|
||||||
enable = true;
|
enable = true;
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
user = "${service}";
|
user = service;
|
||||||
group = "${service}";
|
group = service;
|
||||||
dataDir = cfg.data_dir;
|
dataDir = cfg.data_dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,23 +71,13 @@ in
|
|||||||
# # open firewall
|
# # open firewall
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
serverAliases = [ "media.${homelab.public_domain}" ];
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
extraConfig = ''
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
locations."/" = {
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
'';
|
||||||
};
|
|
||||||
};
|
|
||||||
# external reverse proxy entry
|
|
||||||
services.nginx.virtualHosts."media.blakedheld.xyz" = {
|
|
||||||
forceSSL = true;
|
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# add to glance
|
# add to glance
|
||||||
@@ -50,8 +50,10 @@ in
|
|||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
# declare ${service} group
|
# ensure media dirs existence
|
||||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /holocron/media/downloads 2775 qbittorrent media -"
|
||||||
|
];
|
||||||
|
|
||||||
# declare ${service} user
|
# declare ${service} user
|
||||||
users.users.${service} = {
|
users.users.${service} = {
|
||||||
@@ -60,16 +62,15 @@ in
|
|||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
home = cfg.data_dir;
|
home = cfg.data_dir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
group = "${service}";
|
group = "media";
|
||||||
extraGroups = [ "media" ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# enable the qbittorrent service
|
# enable the qbittorrent service
|
||||||
services.${service} = {
|
services.${service} = {
|
||||||
enable = true;
|
enable = true;
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
user = "${service}";
|
user = service;
|
||||||
group = "${service}";
|
group = lib.mkForce "media"; # override for permissions
|
||||||
profileDir = cfg.data_dir;
|
profileDir = cfg.data_dir;
|
||||||
webuiPort = cfg.port;
|
webuiPort = cfg.port;
|
||||||
# torrentingPort = cfg.torrenting_port;
|
# torrentingPort = cfg.torrenting_port;
|
||||||
@@ -109,14 +110,12 @@ in
|
|||||||
# # open firewall
|
# # open firewall
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
extraConfig = ''
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
locations."/" = {
|
'';
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# add to glance
|
# add to glance
|
||||||
127
modules/homelab/services/.default.nix.template.nix
Normal file
127
modules/homelab/services/.default.nix.template.nix
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
service = "";
|
||||||
|
cfg = config.modules.services.${service};
|
||||||
|
sec = config.sops.secrets;
|
||||||
|
homelab = config.modules.homelab;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.modules.services.${service} = {
|
||||||
|
enable = lib.mkEnableOption "enables ${service}";
|
||||||
|
|
||||||
|
# set port options
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = <port>;
|
||||||
|
description = "set port for ${service} (default: ${toString cfg.port}";
|
||||||
|
};
|
||||||
|
url = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "${service}.${homelab.base_domain}";
|
||||||
|
description = "set domain for ${service}";
|
||||||
|
};
|
||||||
|
data_dir = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/var/lib/${service}";
|
||||||
|
description = "set data directory for ${service}";
|
||||||
|
};
|
||||||
|
ids = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = cfg.port;
|
||||||
|
description = "set uid and pid of ${service} user (matches port by default)";
|
||||||
|
};
|
||||||
|
backup = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "enable backups for ${service}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
|
# declare ${service} group
|
||||||
|
users.groups.${service} = {
|
||||||
|
gid = lib.mkForce cfg.ids;
|
||||||
|
};
|
||||||
|
|
||||||
|
# declare ${service} user
|
||||||
|
users.users.${service} = {
|
||||||
|
description = "${service} server user";
|
||||||
|
uid = lib.mkForce cfg.ids;
|
||||||
|
isSystemUser = true;
|
||||||
|
home = cfg.data_dir;
|
||||||
|
createHome = true;
|
||||||
|
group = service;
|
||||||
|
extraGroups = [ "media" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# enable the ${service} service
|
||||||
|
services.${service} = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
user = service;
|
||||||
|
group = service;
|
||||||
|
dataDir = cfg.data_dir;
|
||||||
|
settings = {
|
||||||
|
server.port = cfg.port;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# override umask to make permissions work out
|
||||||
|
systemd.services.${service}.serviceConfig = {
|
||||||
|
UMask = lib.mkForce "0007";
|
||||||
|
# User = service;
|
||||||
|
# Group = service;
|
||||||
|
};
|
||||||
|
|
||||||
|
# # open firewall
|
||||||
|
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
|
# add to caddy for reverse proxy
|
||||||
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
|
serverAliases = [ "${service}.${homelab.public_domain}" ];
|
||||||
|
extraConfig = ''
|
||||||
|
tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
|
||||||
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# # add to glance (public service)
|
||||||
|
# modules.services.glance.links.<category> = [{
|
||||||
|
# title = service;
|
||||||
|
# url = "https://${service}.${homelab.public_domain}";
|
||||||
|
# error-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
||||||
|
# check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
||||||
|
# icon = "di:${service}"; }];
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# # add to glance (local service)
|
||||||
|
# modules.services.glance.links.<category> = [{
|
||||||
|
# title = service;
|
||||||
|
# url = "https://${cfg.url}";
|
||||||
|
# error-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
||||||
|
# check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
||||||
|
# icon = "di:${service}"; }];
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# sops.secrets = {
|
||||||
|
# "${service}_" = {
|
||||||
|
# owner = ;
|
||||||
|
# group = ;
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
|
||||||
|
# add to backups
|
||||||
|
modules.system.backups.baks = {
|
||||||
|
${service} = {
|
||||||
|
paths = [ cfg.data_dir ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,5 +1,31 @@
|
|||||||
{ pkgs, config, lib, ... }:
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
/*
|
||||||
|
no longer in use, replaced by caddy if
|
||||||
|
wanting to use again here is the boilerplate
|
||||||
|
for whatt o put in for each service
|
||||||
|
|
||||||
|
# internal reverse proxy entry
|
||||||
|
services.nginx.virtualHosts."${cfg.url}" = {
|
||||||
|
forceSSL = true;
|
||||||
|
sslCertificate = sec."ssl_blakedheld_crt".path;
|
||||||
|
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# external reverse proxy entry
|
||||||
|
services.nginx.virtualHosts."${service}.blakedheld.xyz" = {
|
||||||
|
forceSSL = true;
|
||||||
|
sslCertificate = sec."ssl_blakedheld_crt".path;
|
||||||
|
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.modules.homelab.nginx-proxy;
|
cfg = config.modules.homelab.nginx-proxy;
|
||||||
sec = config.sops.secrets;
|
sec = config.sops.secrets;
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
{ pkgs, config, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
service = "audiobookshelf";
|
|
||||||
cfg = config.modules.services.${service};
|
|
||||||
sec = config.sops.secrets;
|
|
||||||
homelab = config.modules.homelab;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.modules.services.${service} = {
|
|
||||||
enable = lib.mkEnableOption "enables ${service}";
|
|
||||||
|
|
||||||
# set port options
|
|
||||||
port = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 7101;
|
|
||||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
|
||||||
};
|
|
||||||
url = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "abs.${homelab.base_domain}";
|
|
||||||
description = "set domain for ${service}";
|
|
||||||
};
|
|
||||||
data_dir = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "/var/lib/${service}";
|
|
||||||
description = "set data directory for ${service}";
|
|
||||||
};
|
|
||||||
ids = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = cfg.port;
|
|
||||||
description = "set uid and pid of ${service} user (matches port by default)";
|
|
||||||
};
|
|
||||||
backup = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "enable backups for ${service}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
|
|
||||||
# declare ${service} group
|
|
||||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
|
||||||
|
|
||||||
# declare ${service} user
|
|
||||||
users.users.${service} = {
|
|
||||||
description = "${service} server user";
|
|
||||||
uid = lib.mkForce cfg.ids;
|
|
||||||
isSystemUser = true;
|
|
||||||
# home = cfg.data_dir;
|
|
||||||
createHome = true;
|
|
||||||
group = "${service}";
|
|
||||||
extraGroups = [ "media" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# enable the ${service} service
|
|
||||||
services.${service} = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
user = "${service}";
|
|
||||||
group = "${service}";
|
|
||||||
# dataDir = cfg.data_dir;
|
|
||||||
host = "0.0.0.0";
|
|
||||||
port = cfg.port;
|
|
||||||
};
|
|
||||||
|
|
||||||
# override umask to make permissions work out
|
|
||||||
systemd.services.${service}.serviceConfig = {
|
|
||||||
UMask = lib.mkForce "0007";
|
|
||||||
# User = "${service}";
|
|
||||||
# Group = "${service}";
|
|
||||||
};
|
|
||||||
|
|
||||||
# # open firewall
|
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
|
||||||
|
|
||||||
# internal reverse proxy entry
|
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
|
||||||
forceSSL = true;
|
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
client_max_body_size 10240M;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# external reverse proxy entry
|
|
||||||
services.nginx.virtualHosts."$abs.blakedheld.xyz" = {
|
|
||||||
forceSSL = true;
|
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# add to glance public service
|
|
||||||
modules.services.glance.links.mediastack = [{
|
|
||||||
title = service;
|
|
||||||
url = "https://abs.${homelab.public_domain}";
|
|
||||||
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
|
||||||
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
|
||||||
icon = "di:${service}"; }];
|
|
||||||
|
|
||||||
#
|
|
||||||
# sops.secrets = {
|
|
||||||
# "${service}_" = {
|
|
||||||
# owner = "${service}";
|
|
||||||
# group = "${service}";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
|
|
||||||
# add to backups
|
|
||||||
modules.system.backups.baks = {
|
|
||||||
${service} = { paths = [ cfg.data_dir ]; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -5,33 +5,8 @@
|
|||||||
|
|
||||||
# services show up in glance in reverse import order lmao
|
# services show up in glance in reverse import order lmao
|
||||||
imports = [
|
imports = [
|
||||||
./home/zigbee2mqtt
|
|
||||||
./vaultwarden
|
|
||||||
./gitea
|
|
||||||
./home/homeassistant
|
|
||||||
./immich
|
|
||||||
./arr/prowlarr
|
|
||||||
./arr/bazarr
|
|
||||||
./arr/radarr
|
|
||||||
./arr/sonarr
|
|
||||||
./audiobookshelf
|
|
||||||
./qbittorrent
|
|
||||||
./jellyfin
|
|
||||||
./nginx-proxy
|
|
||||||
./arr/flaresolverr
|
|
||||||
./home/mosquitto
|
|
||||||
./uptime-kuma
|
|
||||||
./glance
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# add to udr to glance
|
|
||||||
modules.services.glance.links.system = [{
|
|
||||||
title = "bebe";
|
|
||||||
url = "https://bebe.lan";
|
|
||||||
error-url = "https://10.10.0.1";
|
|
||||||
check-url = "https://10.10.0.1";
|
|
||||||
icon = "di:unifi";
|
|
||||||
allow-insecure = true; }];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,129 +0,0 @@
|
|||||||
{ pkgs, config, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
service = "";
|
|
||||||
cfg = config.modules.services.${service};
|
|
||||||
sec = config.sops.secrets;
|
|
||||||
homelab = config.modules.homelab;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.modules.services.${service} = {
|
|
||||||
enable = lib.mkEnableOption "enables ${service}";
|
|
||||||
|
|
||||||
# set port options
|
|
||||||
port = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = <port>;
|
|
||||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
|
||||||
};
|
|
||||||
url = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "${service}.${homelab.base_domain}";
|
|
||||||
description = "set domain for ${service}";
|
|
||||||
};
|
|
||||||
data_dir = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "/var/lib/${service}";
|
|
||||||
description = "set data directory for ${service}";
|
|
||||||
};
|
|
||||||
ids = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = cfg.port;
|
|
||||||
description = "set uid and pid of ${service} user (matches port by default)";
|
|
||||||
};
|
|
||||||
backup = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "enable backups for ${service}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
|
|
||||||
# declare ${service} group
|
|
||||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
|
||||||
|
|
||||||
# declare ${service} user
|
|
||||||
users.users.${service} = {
|
|
||||||
description = "${service} server user";
|
|
||||||
uid = lib.mkForce cfg.ids;
|
|
||||||
isSystemUser = true;
|
|
||||||
home = cfg.data_dir;
|
|
||||||
createHome = true;
|
|
||||||
group = "${service}";
|
|
||||||
extraGroups = [ "media" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# enable the ${service} service
|
|
||||||
services.${service} = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
user = "${service}";
|
|
||||||
group = "${service}";
|
|
||||||
dataDir = cfg.data_dir;
|
|
||||||
settings = {
|
|
||||||
server.port = cfg.port;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# override umask to make permissions work out
|
|
||||||
systemd.services.${service}.serviceConfig = {
|
|
||||||
UMask = lib.mkForce "0007";
|
|
||||||
# User = "${service}";
|
|
||||||
# Group = "${service}";
|
|
||||||
};
|
|
||||||
|
|
||||||
# # open firewall
|
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
|
||||||
|
|
||||||
# internal reverse proxy entry
|
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
|
||||||
forceSSL = true;
|
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# uncomment for service hosted publicly
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# # external reverse proxy entry
|
|
||||||
# services.nginx.virtualHosts."${service}.blakedheld.xyz" = {
|
|
||||||
# forceSSL = true;
|
|
||||||
# sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
# sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
# locations."/" = {
|
|
||||||
# proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# # add to glance public service
|
|
||||||
# modules.services.glance.links.<category> = [{
|
|
||||||
# title = service;
|
|
||||||
# url = "https://${service}.${homelab.public_domain}";
|
|
||||||
# error-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
|
||||||
# check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
|
||||||
# icon = "di:${service}"; }];
|
|
||||||
#---------------------------------------------------------------------------
|
|
||||||
# # add to glance local service
|
|
||||||
# modules.services.glance.links.<category> = [{
|
|
||||||
# title = service;
|
|
||||||
# url = "https://${cfg.url}";
|
|
||||||
# error-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
|
||||||
# check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
|
||||||
# icon = "di:${service}"; }];
|
|
||||||
#
|
|
||||||
# sops.secrets = {
|
|
||||||
# "${service}_" = {
|
|
||||||
# owner = "${service}";
|
|
||||||
# group = "${service}";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
|
|
||||||
# add to backups
|
|
||||||
modules.system.backups.baks = {
|
|
||||||
${service} = { paths = [ cfg.data_dir ]; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,257 +0,0 @@
|
|||||||
{ pkgs, config, lib, ... }:
|
|
||||||
|
|
||||||
/*
|
|
||||||
this is a wrapper module for glance that allows you to
|
|
||||||
to pass monitor entries in with nix, all declaratively!
|
|
||||||
|
|
||||||
| <8yy> |
|
|
||||||
V V
|
|
||||||
# add to glance
|
|
||||||
modules.services.glance.links.mediastack = [{
|
|
||||||
title = service;
|
|
||||||
url = "https://${cfg.url}";
|
|
||||||
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
|
||||||
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
|
||||||
icon = "di:${service}";
|
|
||||||
allow-insecure = true; }];
|
|
||||||
*/
|
|
||||||
|
|
||||||
let
|
|
||||||
service = "glance";
|
|
||||||
cfg = config.modules.services.${service};
|
|
||||||
sec = config.sops.secrets;
|
|
||||||
homelab = config.modules.homelab;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.modules.services.${service} = {
|
|
||||||
enable = lib.mkEnableOption "enables ${service}";
|
|
||||||
|
|
||||||
# set port options
|
|
||||||
port = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 7700;
|
|
||||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
|
||||||
};
|
|
||||||
url = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "${homelab.base_domain}";
|
|
||||||
description = "set domain for ${service}";
|
|
||||||
};
|
|
||||||
data_dir = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "/var/lib/${service}";
|
|
||||||
description = "set data directory for ${service}";
|
|
||||||
};
|
|
||||||
ids = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = cfg.port;
|
|
||||||
description = "set uid and pid of ${service} user (matches port by default)";
|
|
||||||
};
|
|
||||||
backup = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "enable backups for ${service}";
|
|
||||||
};
|
|
||||||
links = {
|
|
||||||
services = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.attrs;
|
|
||||||
default = [];
|
|
||||||
description = "list of links for ${service}";
|
|
||||||
};
|
|
||||||
mediastack = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.attrs;
|
|
||||||
default = [];
|
|
||||||
description = "list of links for ${service}";
|
|
||||||
};
|
|
||||||
system = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.attrs;
|
|
||||||
default = [];
|
|
||||||
description = "list of links for ${service}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
|
|
||||||
|
|
||||||
# declare ${service} group
|
|
||||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
|
||||||
|
|
||||||
# declare ${service} user
|
|
||||||
users.users.${service} = {
|
|
||||||
description = "${service} server user";
|
|
||||||
uid = lib.mkForce cfg.ids;
|
|
||||||
isSystemUser = true;
|
|
||||||
home = cfg.data_dir;
|
|
||||||
createHome = true;
|
|
||||||
group = "${service}";
|
|
||||||
extraGroups = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.${service} = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
settings = {
|
|
||||||
server = {
|
|
||||||
host = "0.0.0.0";
|
|
||||||
port = cfg.port;
|
|
||||||
};
|
|
||||||
pages = [
|
|
||||||
{
|
|
||||||
name = "violet";
|
|
||||||
hide-desktop-navigation = true;
|
|
||||||
columns = [
|
|
||||||
{
|
|
||||||
size = "small";
|
|
||||||
widgets = [
|
|
||||||
{ type = "calendar"; first-day-of-week = "monday"; }
|
|
||||||
{ type = "server-stats"; servers = [ { type = "local"; name = "violet"; } ]; }
|
|
||||||
{
|
|
||||||
type = "clock";
|
|
||||||
hour-format = "24h";
|
|
||||||
timezones = [
|
|
||||||
{ timezone = "America/Chicago"; label = "HTX"; }
|
|
||||||
{ timezone = "America/Denver"; label = "AF"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{ type = "twitch-channels"; channels = [ "mang0" "SaltSSBM" "thewaffle77" "ironmouse" "linustech" ]; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
size = "full";
|
|
||||||
widgets = [
|
|
||||||
{
|
|
||||||
type = "search";
|
|
||||||
autofocus = true;
|
|
||||||
search-engine = "https://www.ecosia.org/search?q={QUERY}";
|
|
||||||
new-tab = true;
|
|
||||||
bangs = [
|
|
||||||
{ title = "YouTube"; shortcut = "!y"; url = "https://www.youtube.com/results?search_query={QUERY}"; }
|
|
||||||
{ title = "Google"; shortcut = "!g"; url = "https://www.google.com/search?q={QUERY}"; }
|
|
||||||
{ title = "Github"; shortcut = "!gh"; url = "https://github.com/search?q={QUERY}&type=repositories"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "monitor";
|
|
||||||
cache = "1m";
|
|
||||||
title = "services";
|
|
||||||
sites = cfg.links.services;
|
|
||||||
# sites = [
|
|
||||||
# { title = "jellyfin"; url = "https://media.blakedheld.xyz"; icon = "di:jellyfin"; }
|
|
||||||
# { title = "audiobookshelf"; url = "https://audiobooks.blakedheld.xyz"; icon = "di:audiobookshelf"; }
|
|
||||||
# { title = "yacreader"; url = "http://10.10.0.30:3434"; icon = "/assets/icons/yacreader.png"; }
|
|
||||||
# { title = "sonarr"; url = "http://10.10.0.30:3636"; icon = "di:sonarr"; }
|
|
||||||
# { title = "qbittorrent"; url = "http://10.10.0.40:3333"; icon = "di:qbittorrent"; }
|
|
||||||
# { title = "radarr"; url = "http://10.10.0.30:3737"; icon = "di:radarr"; }
|
|
||||||
# { title = "kiwix"; url = "http://10.10.0.30:5050"; icon = "di:kiwix"; }
|
|
||||||
# { title = "prowlarr"; url = "http://10.10.0.30:3535"; icon = "di:prowlarr"; }
|
|
||||||
# { title = "bazarr"; url = "http://10.10.0.30:3838"; icon = "di:bazarr"; }
|
|
||||||
# ];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "monitor";
|
|
||||||
cache = "1m";
|
|
||||||
title = "mediastack";
|
|
||||||
sites = cfg.links.mediastack;
|
|
||||||
# [
|
|
||||||
# { title = "immich"; url = "https://pics.blakedheld.xyz"; icon = "di:immich"; }
|
|
||||||
# { title = "vaultwarden"; url = "https://pass.blakedheld.xyz"; icon = "di:vaultwarden"; }
|
|
||||||
# { title = "gitea"; url = "https://git.blakedheld.xyz"; icon = "di:gitea"; }
|
|
||||||
# { title = "home assistant"; url = "https://home.blakedheld.xyz"; icon = "di:home-assistant"; }
|
|
||||||
# { title = "zigbee2mqtt"; url = "http://10.10.0.30:4142"; icon = "di:zigbee2mqtt"; }
|
|
||||||
# { title = "syncthing"; url = "http://10.10.0.20:2222"; icon = "di:syncthing"; }
|
|
||||||
# { title = "archivebox"; url = "http://10.10.0.30:5656"; icon = "sh:archivebox"; }
|
|
||||||
# { title = "copyparty"; url = "http://10.10.0.20:3923"; icon = "sh:copyparty"; }
|
|
||||||
# ];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "monitor";
|
|
||||||
cache = "1m";
|
|
||||||
title = "system";
|
|
||||||
sites = cfg.links.system;
|
|
||||||
# [
|
|
||||||
# { title = "proxmox"; url = "http://10.10.0.10:8006"; icon = "di:proxmox"; allow-insecure = true; }
|
|
||||||
# { title = "nginx"; url = "http://10.10.0.30:8080"; icon = "di:nginx"; }
|
|
||||||
# { title = "uptime kuma"; url = "http://10.10.0.30:8181"; icon = "di:uptime-kuma"; }
|
|
||||||
# { title = "tn holocron"; url = "https://10.10.0.20"; icon = "di:truenas"; allow-insecure = true; }
|
|
||||||
# { title = "bebe"; url = "https://10.10.0.1"; icon = "di:unifi"; allow-insecure = true; }
|
|
||||||
# ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
size = "small";
|
|
||||||
widgets = [
|
|
||||||
{ type = "weather"; location = "Pearland, Texas, United States"; units = "imperial"; hour-format = "24h"; }
|
|
||||||
{
|
|
||||||
type = "markets";
|
|
||||||
markets = [
|
|
||||||
{ symbol = "SPY"; name = "S&P 500"; }
|
|
||||||
{ symbol = "XMR-USD"; name = "Monero"; }
|
|
||||||
{ symbol = "NVDA"; name = "NVIDIA"; }
|
|
||||||
{ symbol = "AAPL"; name = "Apple"; }
|
|
||||||
{ symbol = "MSFT"; name = "Microsoft"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "releases";
|
|
||||||
cache = "1d";
|
|
||||||
repositories = [
|
|
||||||
"glanceapp/glance"
|
|
||||||
"go-gitea/gitea"
|
|
||||||
"immich-app/immich"
|
|
||||||
"syncthing/syncthing"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# override umask to make permissions work out
|
|
||||||
systemd.services.${service}.serviceConfig = {
|
|
||||||
UMask = lib.mkForce "0007";
|
|
||||||
# User = "${service}";
|
|
||||||
# Group = "${service}";
|
|
||||||
};
|
|
||||||
|
|
||||||
# # open firewall
|
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
|
||||||
|
|
||||||
# internal reverse proxy entry
|
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
|
||||||
forceSSL = true;
|
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# # external reverse proxy entry
|
|
||||||
# services.nginx.virtualHosts."${service}.blakedheld.xyz" = {
|
|
||||||
# forceSSL = true;
|
|
||||||
# sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
# sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
# locations."/" = {
|
|
||||||
# proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# sops.secrets = {
|
|
||||||
# "${service}_" = {
|
|
||||||
# owner = "${service}";
|
|
||||||
# group = "${service}";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
|
|
||||||
# add to backups
|
|
||||||
modules.system.backups.baks = {
|
|
||||||
${service} = { paths = [ cfg.data_dir ]; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,230 +0,0 @@
|
|||||||
{ pkgs, config, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
service = "glance";
|
|
||||||
cfg = config.modules.services.${service};
|
|
||||||
sec = config.sops.secrets;
|
|
||||||
homelab = config.modules.homelab;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.modules.services.${service} = {
|
|
||||||
enable = lib.mkEnableOption "enables ${service}";
|
|
||||||
|
|
||||||
# set port options
|
|
||||||
port = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 7700;
|
|
||||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
|
||||||
};
|
|
||||||
url = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "${homelab.base_domain}";
|
|
||||||
description = "set domain for ${service}";
|
|
||||||
};
|
|
||||||
data_dir = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "/var/lib/${service}";
|
|
||||||
description = "set data directory for ${service}";
|
|
||||||
};
|
|
||||||
ids = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = cfg.port;
|
|
||||||
description = "set uid and pid of ${service} user (matches port by default)";
|
|
||||||
};
|
|
||||||
backup = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "enable backups for ${service}";
|
|
||||||
};
|
|
||||||
pages = lib.mkOption {
|
|
||||||
type = lib.types.attrsOf (lib.types.submodule {
|
|
||||||
options.description = lib.mkOption { type = lib.types.str; };
|
|
||||||
options.url = lib.mkOption { type = lib.types.str; };
|
|
||||||
options.icon = lib.mkOption { type = lib.types.str; };
|
|
||||||
options.category = lib.mkOption { type = lib.types.str; };
|
|
||||||
});
|
|
||||||
default = {};
|
|
||||||
description = "configure the service for use in ${service}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
|
|
||||||
# declare ${service} group
|
|
||||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
|
||||||
|
|
||||||
# declare ${service} user
|
|
||||||
users.users.${service} = {
|
|
||||||
description = "${service} server user";
|
|
||||||
uid = lib.mkForce cfg.ids;
|
|
||||||
isSystemUser = true;
|
|
||||||
home = cfg.data_dir;
|
|
||||||
createHome = true;
|
|
||||||
group = "${service}";
|
|
||||||
extraGroups = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.${service} = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
settings = {
|
|
||||||
server = {
|
|
||||||
host = "0.0.0.0";
|
|
||||||
port = cfg.port;
|
|
||||||
};
|
|
||||||
pages = [
|
|
||||||
{
|
|
||||||
name = "violet";
|
|
||||||
hide-desktop-navigation = true;
|
|
||||||
columns = [
|
|
||||||
{
|
|
||||||
size = "small";
|
|
||||||
widgets = [
|
|
||||||
{ type = "calendar"; first-day-of-week = "monday"; }
|
|
||||||
{ type = "server-stats"; servers = [ { type = "local"; name = "violet"; } ]; }
|
|
||||||
{
|
|
||||||
type = "clock";
|
|
||||||
hour-format = "24h";
|
|
||||||
timezones = [
|
|
||||||
{ timezone = "America/Chicago"; label = "HTX"; }
|
|
||||||
{ timezone = "America/Denver"; label = "AF"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{ type = "twitch-channels"; channels = [ "mang0" "SaltSSBM" "thewaffle77" "ironmouse" "linustech" ]; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
size = "full";
|
|
||||||
widgets = [
|
|
||||||
{
|
|
||||||
type = "search";
|
|
||||||
autofocus = true;
|
|
||||||
search-engine = "https://www.ecosia.org/search?q={QUERY}";
|
|
||||||
new-tab = true;
|
|
||||||
bangs = [
|
|
||||||
{ title = "YouTube"; shortcut = "!y"; url = "https://www.youtube.com/results?search_query={QUERY}"; }
|
|
||||||
{ title = "Google"; shortcut = "!g"; url = "https://www.google.com/search?q={QUERY}"; }
|
|
||||||
{ title = "Github"; shortcut = "!gh"; url = "https://github.com/search?q={QUERY}&type=repositories"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "monitor";
|
|
||||||
cache = "1m";
|
|
||||||
title = "mediastack";
|
|
||||||
sites = [
|
|
||||||
{ title = "jellyfin"; url = "https://media.blakedheld.xyz"; icon = "di:jellyfin"; }
|
|
||||||
{ title = "audiobookshelf"; url = "https://audiobooks.blakedheld.xyz"; icon = "di:audiobookshelf"; }
|
|
||||||
{ title = "yacreader"; url = "http://10.10.0.30:3434"; icon = "/assets/icons/yacreader.png"; }
|
|
||||||
{ title = "sonarr"; url = "http://10.10.0.30:3636"; icon = "di:sonarr"; }
|
|
||||||
{ title = "qbittorrent"; url = "http://10.10.0.40:3333"; icon = "di:qbittorrent"; }
|
|
||||||
{ title = "radarr"; url = "http://10.10.0.30:3737"; icon = "di:radarr"; }
|
|
||||||
{ title = "kiwix"; url = "http://10.10.0.30:5050"; icon = "di:kiwix"; }
|
|
||||||
{ title = "prowlarr"; url = "http://10.10.0.30:3535"; icon = "di:prowlarr"; }
|
|
||||||
{ title = "bazarr"; url = "http://10.10.0.30:3838"; icon = "di:bazarr"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "monitor";
|
|
||||||
cache = "1m";
|
|
||||||
title = "services";
|
|
||||||
sites = [
|
|
||||||
{ title = "immich"; url = "https://pics.blakedheld.xyz"; icon = "di:immich"; }
|
|
||||||
{ title = "vaultwarden"; url = "https://pass.blakedheld.xyz"; icon = "di:vaultwarden"; }
|
|
||||||
{ title = "gitea"; url = "https://git.blakedheld.xyz"; icon = "di:gitea"; }
|
|
||||||
{ title = "home assistant"; url = "https://home.blakedheld.xyz"; icon = "di:home-assistant"; }
|
|
||||||
{ title = "zigbee2mqtt"; url = "http://10.10.0.30:4142"; icon = "di:zigbee2mqtt"; }
|
|
||||||
{ title = "syncthing"; url = "http://10.10.0.20:2222"; icon = "di:syncthing"; }
|
|
||||||
{ title = "archivebox"; url = "http://10.10.0.30:5656"; icon = "sh:archivebox"; }
|
|
||||||
{ title = "copyparty"; url = "http://10.10.0.20:3923"; icon = "sh:copyparty"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "monitor";
|
|
||||||
cache = "1m";
|
|
||||||
title = "system";
|
|
||||||
sites = [
|
|
||||||
{ title = "proxmox"; url = "http://10.10.0.10:8006"; icon = "di:proxmox"; allow-insecure = true; }
|
|
||||||
{ title = "nginx"; url = "http://10.10.0.30:8080"; icon = "di:nginx"; }
|
|
||||||
{ title = "uptime kuma"; url = "http://10.10.0.30:8181"; icon = "di:uptime-kuma"; }
|
|
||||||
{ title = "tn holocron"; url = "https://10.10.0.20"; icon = "di:truenas"; allow-insecure = true; }
|
|
||||||
{ title = "bebe"; url = "https://10.10.0.1"; icon = "di:unifi"; allow-insecure = true; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
size = "small";
|
|
||||||
widgets = [
|
|
||||||
{ type = "weather"; location = "Pearland, Texas, United States"; units = "imperial"; hour-format = "24h"; }
|
|
||||||
{
|
|
||||||
type = "markets";
|
|
||||||
markets = [
|
|
||||||
{ symbol = "SPY"; name = "S&P 500"; }
|
|
||||||
{ symbol = "XMR-USD"; name = "Monero"; }
|
|
||||||
{ symbol = "NVDA"; name = "NVIDIA"; }
|
|
||||||
{ symbol = "AAPL"; name = "Apple"; }
|
|
||||||
{ symbol = "MSFT"; name = "Microsoft"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "releases";
|
|
||||||
cache = "1d";
|
|
||||||
repositories = [
|
|
||||||
"glanceapp/glance"
|
|
||||||
"go-gitea/gitea"
|
|
||||||
"immich-app/immich"
|
|
||||||
"syncthing/syncthing"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# override umask to make permissions work out
|
|
||||||
systemd.services.${service}.serviceConfig = {
|
|
||||||
UMask = lib.mkForce "0007";
|
|
||||||
# User = "${service}";
|
|
||||||
# Group = "${service}";
|
|
||||||
};
|
|
||||||
|
|
||||||
# # open firewall
|
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
|
||||||
|
|
||||||
# internal reverse proxy entry
|
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
|
||||||
forceSSL = true;
|
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# # external reverse proxy entry
|
|
||||||
# services.nginx.virtualHosts."${service}.blakedheld.xyz" = {
|
|
||||||
# forceSSL = true;
|
|
||||||
# sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
# sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
# locations."/" = {
|
|
||||||
# proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# sops.secrets = {
|
|
||||||
# "${service}_" = {
|
|
||||||
# owner = "${service}";
|
|
||||||
# group = "${service}";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
|
|
||||||
# add to backups
|
|
||||||
modules.system.backups.baks = {
|
|
||||||
${service} = { paths = [ cfg.data_dir ]; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,230 +0,0 @@
|
|||||||
{ pkgs, config, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
service = "glance";
|
|
||||||
cfg = config.modules.services.${service};
|
|
||||||
sec = config.sops.secrets;
|
|
||||||
homelab = config.modules.homelab;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.modules.services.${service} = {
|
|
||||||
enable = lib.mkEnableOption "enables ${service}";
|
|
||||||
|
|
||||||
# set port options
|
|
||||||
port = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 7700;
|
|
||||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
|
||||||
};
|
|
||||||
url = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "${homelab.base_domain}";
|
|
||||||
description = "set domain for ${service}";
|
|
||||||
};
|
|
||||||
data_dir = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "/var/lib/${service}";
|
|
||||||
description = "set data directory for ${service}";
|
|
||||||
};
|
|
||||||
ids = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = cfg.port;
|
|
||||||
description = "set uid and pid of ${service} user (matches port by default)";
|
|
||||||
};
|
|
||||||
backup = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "enable backups for ${service}";
|
|
||||||
};
|
|
||||||
pages = lib.mkOption {
|
|
||||||
type = lib.types.attrsOf (lib.types.submodule {
|
|
||||||
options.description = lib.mkOption { type = lib.types.str; };
|
|
||||||
options.url = lib.mkOption { type = lib.types.str; };
|
|
||||||
options.icon = lib.mkOption { type = lib.types.str; };
|
|
||||||
options.category = lib.mkOption { type = lib.types.str; };
|
|
||||||
});
|
|
||||||
default = {};
|
|
||||||
description = "configure the service for use in ${service}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
|
|
||||||
# declare ${service} group
|
|
||||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
|
||||||
|
|
||||||
# declare ${service} user
|
|
||||||
users.users.${service} = {
|
|
||||||
description = "${service} server user";
|
|
||||||
uid = lib.mkForce cfg.ids;
|
|
||||||
isSystemUser = true;
|
|
||||||
home = cfg.data_dir;
|
|
||||||
createHome = true;
|
|
||||||
group = "${service}";
|
|
||||||
extraGroups = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.${service} = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
settings = {
|
|
||||||
server = {
|
|
||||||
host = "0.0.0.0";
|
|
||||||
port = cfg.port;
|
|
||||||
};
|
|
||||||
pages = [
|
|
||||||
{
|
|
||||||
name = "violet";
|
|
||||||
hide-desktop-navigation = true;
|
|
||||||
columns = [
|
|
||||||
{
|
|
||||||
size = "small";
|
|
||||||
widgets = [
|
|
||||||
{ type = "calendar"; first-day-of-week = "monday"; }
|
|
||||||
{ type = "server-stats"; servers = [ { type = "local"; name = "violet"; } ]; }
|
|
||||||
{
|
|
||||||
type = "clock";
|
|
||||||
hour-format = "24h";
|
|
||||||
timezones = [
|
|
||||||
{ timezone = "America/Chicago"; label = "HTX"; }
|
|
||||||
{ timezone = "America/Denver"; label = "AF"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{ type = "twitch-channels"; channels = [ "mang0" "SaltSSBM" "thewaffle77" "ironmouse" "linustech" ]; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
size = "full";
|
|
||||||
widgets = [
|
|
||||||
{
|
|
||||||
type = "search";
|
|
||||||
autofocus = true;
|
|
||||||
search-engine = "https://www.ecosia.org/search?q={QUERY}";
|
|
||||||
new-tab = true;
|
|
||||||
bangs = [
|
|
||||||
{ title = "YouTube"; shortcut = "!y"; url = "https://www.youtube.com/results?search_query={QUERY}"; }
|
|
||||||
{ title = "Google"; shortcut = "!g"; url = "https://www.google.com/search?q={QUERY}"; }
|
|
||||||
{ title = "Github"; shortcut = "!gh"; url = "https://github.com/search?q={QUERY}&type=repositories"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "monitor";
|
|
||||||
cache = "1m";
|
|
||||||
title = "mediastack";
|
|
||||||
sites = [
|
|
||||||
{ title = "jellyfin"; url = "https://media.blakedheld.xyz"; icon = "di:jellyfin"; }
|
|
||||||
{ title = "audiobookshelf"; url = "https://audiobooks.blakedheld.xyz"; icon = "di:audiobookshelf"; }
|
|
||||||
{ title = "yacreader"; url = "http://10.10.0.30:3434"; icon = "/assets/icons/yacreader.png"; }
|
|
||||||
{ title = "sonarr"; url = "http://10.10.0.30:3636"; icon = "di:sonarr"; }
|
|
||||||
{ title = "qbittorrent"; url = "http://10.10.0.40:3333"; icon = "di:qbittorrent"; }
|
|
||||||
{ title = "radarr"; url = "http://10.10.0.30:3737"; icon = "di:radarr"; }
|
|
||||||
{ title = "kiwix"; url = "http://10.10.0.30:5050"; icon = "di:kiwix"; }
|
|
||||||
{ title = "prowlarr"; url = "http://10.10.0.30:3535"; icon = "di:prowlarr"; }
|
|
||||||
{ title = "bazarr"; url = "http://10.10.0.30:3838"; icon = "di:bazarr"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "monitor";
|
|
||||||
cache = "1m";
|
|
||||||
title = "services";
|
|
||||||
sites = [
|
|
||||||
{ title = "immich"; url = "https://pics.blakedheld.xyz"; icon = "di:immich"; }
|
|
||||||
{ title = "vaultwarden"; url = "https://pass.blakedheld.xyz"; icon = "di:vaultwarden"; }
|
|
||||||
{ title = "gitea"; url = "https://git.blakedheld.xyz"; icon = "di:gitea"; }
|
|
||||||
{ title = "home assistant"; url = "https://home.blakedheld.xyz"; icon = "di:home-assistant"; }
|
|
||||||
{ title = "zigbee2mqtt"; url = "http://10.10.0.30:4142"; icon = "di:zigbee2mqtt"; }
|
|
||||||
{ title = "syncthing"; url = "http://10.10.0.20:2222"; icon = "di:syncthing"; }
|
|
||||||
{ title = "archivebox"; url = "http://10.10.0.30:5656"; icon = "sh:archivebox"; }
|
|
||||||
{ title = "copyparty"; url = "http://10.10.0.20:3923"; icon = "sh:copyparty"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "monitor";
|
|
||||||
cache = "1m";
|
|
||||||
title = "system";
|
|
||||||
sites = [
|
|
||||||
{ title = "proxmox"; url = "http://10.10.0.10:8006"; icon = "di:proxmox"; allow-insecure = true; }
|
|
||||||
{ title = "nginx"; url = "http://10.10.0.30:8080"; icon = "di:nginx"; }
|
|
||||||
{ title = "uptime kuma"; url = "http://10.10.0.30:8181"; icon = "di:uptime-kuma"; }
|
|
||||||
{ title = "tn holocron"; url = "https://10.10.0.20"; icon = "di:truenas"; allow-insecure = true; }
|
|
||||||
{ title = "bebe"; url = "https://10.10.0.1"; icon = "di:unifi"; allow-insecure = true; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
size = "small";
|
|
||||||
widgets = [
|
|
||||||
{ type = "weather"; location = "Pearland, Texas, United States"; units = "imperial"; hour-format = "24h"; }
|
|
||||||
{
|
|
||||||
type = "markets";
|
|
||||||
markets = [
|
|
||||||
{ symbol = "SPY"; name = "S&P 500"; }
|
|
||||||
{ symbol = "XMR-USD"; name = "Monero"; }
|
|
||||||
{ symbol = "NVDA"; name = "NVIDIA"; }
|
|
||||||
{ symbol = "AAPL"; name = "Apple"; }
|
|
||||||
{ symbol = "MSFT"; name = "Microsoft"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "releases";
|
|
||||||
cache = "1d";
|
|
||||||
repositories = [
|
|
||||||
"glanceapp/glance"
|
|
||||||
"go-gitea/gitea"
|
|
||||||
"immich-app/immich"
|
|
||||||
"syncthing/syncthing"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# override umask to make permissions work out
|
|
||||||
systemd.services.${service}.serviceConfig = {
|
|
||||||
UMask = lib.mkForce "0007";
|
|
||||||
# User = "${service}";
|
|
||||||
# Group = "${service}";
|
|
||||||
};
|
|
||||||
|
|
||||||
# # open firewall
|
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
|
||||||
|
|
||||||
# internal reverse proxy entry
|
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
|
||||||
forceSSL = true;
|
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# # external reverse proxy entry
|
|
||||||
# services.nginx.virtualHosts."${service}.blakedheld.xyz" = {
|
|
||||||
# forceSSL = true;
|
|
||||||
# sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
# sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
# locations."/" = {
|
|
||||||
# proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# sops.secrets = {
|
|
||||||
# "${service}_" = {
|
|
||||||
# owner = "${service}";
|
|
||||||
# group = "${service}";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
|
|
||||||
# add to backups
|
|
||||||
modules.system.backups.baks = {
|
|
||||||
${service} = { paths = [ cfg.data_dir ]; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -67,31 +67,18 @@ in
|
|||||||
# override umask to make permissions work out
|
# override umask to make permissions work out
|
||||||
systemd.services.${service}.serviceConfig = {
|
systemd.services.${service}.serviceConfig = {
|
||||||
UMask = lib.mkForce "0007";
|
UMask = lib.mkForce "0007";
|
||||||
# User = "${service}";
|
|
||||||
# Group = "${service}";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# # open firewall
|
# # open firewall
|
||||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
extraConfig = ''
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
locations."/" = {
|
'';
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
# # external reverse proxy entry
|
|
||||||
# services.nginx.virtualHosts."up.blakedheld.xyz" = {
|
|
||||||
# forceSSL = true;
|
|
||||||
# sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
# sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
# locations."/" = {
|
|
||||||
# proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
|
|
||||||
# add to glance
|
# add to glance
|
||||||
modules.services.glance.links.system = [{
|
modules.services.glance.links.system = [{
|
||||||
@@ -101,14 +88,9 @@ in
|
|||||||
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
||||||
icon = "di:${service}"; }];
|
icon = "di:${service}"; }];
|
||||||
|
|
||||||
# sops.secrets = {
|
|
||||||
# "${service}_" = {
|
|
||||||
# owner = "${service}";
|
|
||||||
# group = "${service}";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
|
|
||||||
# add to backups
|
# add to backups
|
||||||
modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir ];
|
modules.system.backups.baks = {
|
||||||
|
${service} = { paths = [ cfg.data_dir ]; };
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ in
|
|||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
home = cfg.data_dir;
|
home = cfg.data_dir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
group = "${service}";
|
group = service;
|
||||||
extraGroups = [];
|
extraGroups = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -84,23 +84,13 @@ in
|
|||||||
# open firewall
|
# open firewall
|
||||||
networking.firewall.allowedTCPPorts = [ cfg.port ];
|
networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
# internal reverse proxy entry
|
# add to caddy for reverse proxy
|
||||||
services.nginx.virtualHosts."${cfg.url}" = {
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
forceSSL = true;
|
serverAliases = [ "pass.${homelab.public_domain}" ];
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
extraConfig = ''
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
|
||||||
locations."/" = {
|
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
'';
|
||||||
};
|
|
||||||
};
|
|
||||||
# external reverse proxy entry
|
|
||||||
services.nginx.virtualHosts."pass.blakedheld.xyz" = {
|
|
||||||
forceSSL = true;
|
|
||||||
sslCertificate = sec."ssl_blakedheld_crt".path;
|
|
||||||
sslCertificateKey = sec."ssl_blakedheld_key".path;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# add to glance
|
# add to glance
|
||||||
105
modules/homelab/yacreader/default.nix
Normal file
105
modules/homelab/yacreader/default.nix
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
service = "yacreader";
|
||||||
|
cfg = config.modules.services.${service};
|
||||||
|
sec = config.sops.secrets;
|
||||||
|
homelab = config.modules.homelab;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.modules.services.${service} = {
|
||||||
|
enable = lib.mkEnableOption "enables ${service}";
|
||||||
|
|
||||||
|
# set port options
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 7102;
|
||||||
|
description = "set port for ${service} (default: ${toString cfg.port}";
|
||||||
|
};
|
||||||
|
url = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "manga.${homelab.base_domain}";
|
||||||
|
description = "set domain for ${service}";
|
||||||
|
};
|
||||||
|
data_dir = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/var/lib/${service}";
|
||||||
|
description = "set data directory for ${service}";
|
||||||
|
};
|
||||||
|
ids = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = cfg.port;
|
||||||
|
description = "set uid and pid of ${service} user (matches port by default)";
|
||||||
|
};
|
||||||
|
backup = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "enable backups for ${service}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
|
# install the binary
|
||||||
|
environment.systemPackages = with pkgs; [ yacreader ];
|
||||||
|
|
||||||
|
# declare ${service} group
|
||||||
|
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||||
|
|
||||||
|
# declare ${service} user
|
||||||
|
users.users.${service} = {
|
||||||
|
description = "${service} server user";
|
||||||
|
uid = lib.mkForce cfg.ids;
|
||||||
|
isSystemUser = true;
|
||||||
|
home = cfg.data_dir;
|
||||||
|
createHome = true;
|
||||||
|
group = service;
|
||||||
|
extraGroups = [ "media" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# enable the ${service} service
|
||||||
|
systemd.services.${service} = {
|
||||||
|
description = "${service} library server";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
UMask = lib.mkForce "0007";
|
||||||
|
User = service;
|
||||||
|
Group = service;
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = "5s";
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${pkgs.yacreader}/bin/YACReaderLibraryServer start --port ${toString cfg.port}";
|
||||||
|
WorkingDirectory = "/var/lib/yacreader";
|
||||||
|
TimeoutStopSec = "20s";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# open firewall
|
||||||
|
networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||||
|
|
||||||
|
# add to caddy for reverse proxy
|
||||||
|
services.caddy.virtualHosts."${cfg.url}" = {
|
||||||
|
extraConfig = ''
|
||||||
|
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||||
|
reverse_proxy 127.0.0.1:${toString cfg.port} {
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# add to glance local service
|
||||||
|
modules.services.glance.links.mediastack = [{
|
||||||
|
title = service;
|
||||||
|
url = "https://${cfg.url}";
|
||||||
|
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
||||||
|
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
|
||||||
|
icon = "di:yac-reader"; }];
|
||||||
|
|
||||||
|
# add to backups
|
||||||
|
modules.system.backups.baks = {
|
||||||
|
${service} = { paths = [ cfg.data_dir ]; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@@ -27,9 +27,6 @@ in
|
|||||||
default = {};
|
default = {};
|
||||||
description = "backup jobs, nested attribute sets should be <bak_name> = paths [<list_of_paths>]";
|
description = "backup jobs, nested attribute sets should be <bak_name> = paths [<list_of_paths>]";
|
||||||
};
|
};
|
||||||
paths = lib.mkOption {
|
|
||||||
type = lib.types.list;
|
|
||||||
};
|
|
||||||
repo = lib.mkOption {
|
repo = lib.mkOption {
|
||||||
type = lib.types.path;
|
type = lib.types.path;
|
||||||
default = "/holocron/borg";
|
default = "/holocron/borg";
|
||||||
@@ -40,6 +37,11 @@ in
|
|||||||
default = sec."borg_passwd".path;
|
default = sec."borg_passwd".path;
|
||||||
description = "borg repository passphrase file";
|
description = "borg repository passphrase file";
|
||||||
};
|
};
|
||||||
|
mode = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "split"; # "all"
|
||||||
|
description = "choice between creating one archive of all paths or one archive per service";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf (cfg.enable && cfg.baks != {}) {
|
config = lib.mkIf (cfg.enable && cfg.baks != {}) {
|
||||||
@@ -52,11 +54,12 @@ in
|
|||||||
# EnvironmentFile = config.modules.system.backups.passphraseFile;
|
# EnvironmentFile = config.modules.system.backups.passphraseFile;
|
||||||
# the actual script borg is using
|
# the actual script borg is using
|
||||||
ExecStart = pkgs.writeShellScript "borg-backup" ''
|
ExecStart = pkgs.writeShellScript "borg-backup" ''
|
||||||
|
backup() {
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
export BORG_PASSPHRASE="$(cat ${cfg.passwd_file})"
|
export BORG_PASSPHRASE="$(cat ${cfg.passwd_file})"
|
||||||
export BORG_REPO="${cfg.repo}"
|
export BORG_REPO="${cfg.repo}"
|
||||||
timestamp="$(date +'%Y-%m-%d_%H:%M:%S')"
|
timestamp="$(date +'%Y-%m-%d_%H:%M:%S')"
|
||||||
mode=sep
|
mode=${cfg.mode}
|
||||||
|
|
||||||
# init repo in needed
|
# init repo in needed
|
||||||
if ! borg info "$BORG_REPO" >/dev/null 2>&1; then
|
if ! borg info "$BORG_REPO" >/dev/null 2>&1; then
|
||||||
@@ -68,7 +71,7 @@ in
|
|||||||
|
|
||||||
echo "starting backup at $timestamp"
|
echo "starting backup at $timestamp"
|
||||||
|
|
||||||
if [ "$mode" = "sep" ]; then
|
if [ "$mode" = "split" ]; then
|
||||||
# loop for each backup
|
# loop for each backup
|
||||||
${lib.concatStringsSep "\n\n" (lib.mapAttrsToList (bak_name: bak_paths:
|
${lib.concatStringsSep "\n\n" (lib.mapAttrsToList (bak_name: bak_paths:
|
||||||
''
|
''
|
||||||
@@ -77,23 +80,23 @@ in
|
|||||||
echo "backing up: ${lib.concatStringsSep " " bak_paths.paths} → $archive"
|
echo "backing up: ${lib.concatStringsSep " " bak_paths.paths} → $archive"
|
||||||
borg create \
|
borg create \
|
||||||
--verbose \
|
--verbose \
|
||||||
--filter AME \
|
# --filter AME \
|
||||||
--list \
|
--list \
|
||||||
--stats \
|
--stats \
|
||||||
--show-rc \
|
--show-rc \
|
||||||
--compression lzma,9 \
|
--compression lz4 \
|
||||||
"$BORG_REPO::$archive" \
|
"$BORG_REPO::$archive" \
|
||||||
${lib.concatStringsSep " " bak_paths.paths}
|
${lib.concatStringsSep " " bak_paths.paths}
|
||||||
echo "pruning old backups for ${bak_name}..."
|
echo "pruning old backups for ${bak_name}..."
|
||||||
borg prune -v --list "$BORG_REPO" \
|
borg prune -v --list "$BORG_REPO" \
|
||||||
--prefix "${bak_name}-" \
|
--glob-archives "*-${bak_name}" \
|
||||||
--keep-daily=7 \
|
--keep-daily=7 \
|
||||||
--keep-weekly=52 \
|
--keep-weekly=52 \
|
||||||
--keep-monthly=-1
|
--keep-monthly=-1
|
||||||
echo "backup run complete at \"$BORG_REPO::$archive\""
|
echo "backup run complete at \"$BORG_REPO::$archive\""
|
||||||
exit 0
|
|
||||||
''
|
''
|
||||||
) cfg.baks)}
|
) cfg.baks)}
|
||||||
|
exit 0
|
||||||
else
|
else
|
||||||
# flatten all paths from cfg.baks into one big list
|
# flatten all paths from cfg.baks into one big list
|
||||||
all_paths="${
|
all_paths="${
|
||||||
@@ -113,13 +116,23 @@ in
|
|||||||
|
|
||||||
echo "pruning old backups for ${toString config.networking.hostName}..."
|
echo "pruning old backups for ${toString config.networking.hostName}..."
|
||||||
borg prune -v --list "$BORG_REPO" \
|
borg prune -v --list "$BORG_REPO" \
|
||||||
--prefix "${toString config.networking.hostName}" \
|
--glob-archives "*-${toString config.networking.hostName}" \
|
||||||
--keep-daily=7 \
|
--keep-daily=7 \
|
||||||
--keep-weekly=52 \
|
--keep-weekly=52 \
|
||||||
--keep-monthly=-1
|
--keep-monthly=-1
|
||||||
echo "backup run complete at \"$BORG_REPO::${toString config.networking.hostName}\""
|
echo "backup run complete at \"$BORG_REPO::${toString config.networking.hostName}\""
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
start_time=$(date +%s)
|
||||||
|
backup
|
||||||
|
end_time=$(date +%s)
|
||||||
|
exec_time=$((end_time - start_time))
|
||||||
|
cpu_usage=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1"%"}')
|
||||||
|
echo ""
|
||||||
|
echo "backup stats:"
|
||||||
|
echo "exec time: $exec_time"
|
||||||
|
echo "cpu usage: $cpu_usage"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
|
# install the binary for compose
|
||||||
|
environment.systemPackages = with pkgs; [ podman-compose ];
|
||||||
|
|
||||||
virtualisation = {
|
virtualisation = {
|
||||||
oci-containers.backend = "podman";
|
oci-containers.backend = "podman";
|
||||||
podman = {
|
podman = {
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
{ pkgs, config, lib, ... }:
|
{
|
||||||
|
pkgs,
|
||||||
let
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
cfg = config.modules.system.tailscale;
|
cfg = config.modules.system.tailscale;
|
||||||
authkey_file = config.sops.secrets."tailscale_authkey".path;
|
authkey_file = config.sops.secrets."tailscale_authkey".path;
|
||||||
in
|
in {
|
||||||
{
|
|
||||||
options.modules.system.tailscale = {
|
options.modules.system.tailscale = {
|
||||||
enable = lib.mkEnableOption "enables tailscale";
|
enable = lib.mkEnableOption "enables tailscale";
|
||||||
};
|
};
|
||||||
@@ -20,6 +22,10 @@ in
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# network config
|
||||||
|
networking.firewall.trustedInterfaces = ["tailscale0"];
|
||||||
|
networking.firewall.allowedUDPPorts = [config.services.tailscale.port];
|
||||||
|
|
||||||
# declare authkey secrets
|
# declare authkey secrets
|
||||||
sops.secrets = {
|
sops.secrets = {
|
||||||
"tailscale_authkey" = {
|
"tailscale_authkey" = {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ in
|
|||||||
# create blake user
|
# create blake user
|
||||||
users.users.${cfg.username} = {
|
users.users.${cfg.username} = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" "networkmanager" "docker" "media" "minecraft" ]; # Enable ‘sudo’ for the user.
|
extraGroups = [ "wheel" "networkmanager" "docker" "media" "podman" "minecraft" ]; # Enable ‘sudo’ for the user.
|
||||||
uid = 1000;
|
uid = 1000;
|
||||||
shell = pkgs.zsh;
|
shell = pkgs.zsh;
|
||||||
group = "blake";
|
group = "blake";
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
# general
|
|
||||||
set forcekitty
|
|
||||||
set chafasixel
|
|
||||||
|
|
||||||
|
|
||||||
preview glow .md {{
|
|
||||||
glow -s "dark" < "$f"
|
|
||||||
}}
|
|
||||||
|
|
||||||
@@ -32,6 +32,7 @@ alias src='source $HOME/.config/zsh/.zshrc'
|
|||||||
|
|
||||||
# config editing
|
# config editing
|
||||||
alias cfh='nvim $HOME/.config/hypr/hyprland.conf'
|
alias cfh='nvim $HOME/.config/hypr/hyprland.conf'
|
||||||
|
alias cfl='nvim $HOME/.config/lf/lfrc'
|
||||||
|
|
||||||
# navigation
|
# navigation
|
||||||
setopt autocd
|
setopt autocd
|
||||||
@@ -95,6 +96,8 @@ alias stat='sudo systemctl status'
|
|||||||
alias restart='sudo systemctl restart'
|
alias restart='sudo systemctl restart'
|
||||||
alias start='sudo systemctl start'
|
alias start='sudo systemctl start'
|
||||||
alias stop='sudo systemctl stop'
|
alias stop='sudo systemctl stop'
|
||||||
|
alias jou='sudo journalctl -xeu'
|
||||||
|
alias live='sudo journalctl -o short-iso -n 50 -fu'
|
||||||
|
|
||||||
# shortcuts
|
# shortcuts
|
||||||
alias chil='nvim ~/documents/holocron/tech/devices/yveltal/chilton'
|
alias chil='nvim ~/documents/holocron/tech/devices/yveltal/chilton'
|
||||||
|
|||||||
5
users/blake/dots/lf/ctpv_config
Normal file
5
users/blake/dots/lf/ctpv_config
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# general
|
||||||
|
set forcekitty
|
||||||
|
set chafasixel
|
||||||
|
|
||||||
|
|
||||||
21
users/blake/dots/lf/default.nix
Normal file
21
users/blake/dots/lf/default.nix
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
# just using the normal lfrc
|
||||||
|
programs.lf = {
|
||||||
|
enable = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
# install it to userspace
|
||||||
|
home.packages = with pkgs; [lf ctpv trashy];
|
||||||
|
|
||||||
|
# link configs
|
||||||
|
xdg.configFile."lf/lfrc" = {
|
||||||
|
source = config.lib.file.mkOutOfStoreSymlink "/home/blake/.nix/users/blake/dots/lf/lfrc";
|
||||||
|
};
|
||||||
|
xdg.configFile."ctpv/config" = {
|
||||||
|
source = config.lib.file.mkOutOfStoreSymlink "/home/blake/.nix/users/blake/dots/lf/ctpv_config";
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -21,6 +21,10 @@ set ignorecase true
|
|||||||
|
|
||||||
# --- mappings ---
|
# --- mappings ---
|
||||||
|
|
||||||
|
# shortcuts
|
||||||
|
map gb cd /holocron
|
||||||
|
map gn cd ~/.nix
|
||||||
|
|
||||||
# navigation
|
# navigation
|
||||||
map [ half-up
|
map [ half-up
|
||||||
map ] half-down
|
map ] half-down
|
||||||
@@ -104,7 +108,7 @@ cmd mkfile %{{
|
|||||||
# make backup
|
# make backup
|
||||||
cmd mkbak %{{
|
cmd mkbak %{{
|
||||||
for x in $fx; do
|
for x in $fx; do
|
||||||
cp $x $x.bak
|
cp -r $x $x.bak
|
||||||
done
|
done
|
||||||
|
|
||||||
}}
|
}}
|
||||||
188
users/blake/dots/neovim/default.nix
Normal file
188
users/blake/dots/neovim/default.nix
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
inputs.nvf.homeManagerModules.default
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.nvf = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
vim = {
|
||||||
|
globals = {
|
||||||
|
mapleader = " ";
|
||||||
|
maplocalleader = " ";
|
||||||
|
};
|
||||||
|
|
||||||
|
vimAlias = true;
|
||||||
|
|
||||||
|
lsp.enable = true;
|
||||||
|
statusline.lualine.enable = true;
|
||||||
|
telescope.enable = true;
|
||||||
|
autocomplete.nvim-cmp.enable = true;
|
||||||
|
autopairs.nvim-autopairs.enable = true;
|
||||||
|
|
||||||
|
keymaps = [
|
||||||
|
# visual line movement (insert mode)
|
||||||
|
{
|
||||||
|
key = "<Up>";
|
||||||
|
mode = [ "i" ];
|
||||||
|
action = "<C-o>gk";
|
||||||
|
desc = "Visual Line Up (Insert)";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
key = "<Down>";
|
||||||
|
mode = [ "i" ];
|
||||||
|
action = "<C-o>gj";
|
||||||
|
desc = "Visual Line Down (Insert)";
|
||||||
|
}
|
||||||
|
|
||||||
|
# visual line movement (normal/visual)
|
||||||
|
{
|
||||||
|
key = "<Up>";
|
||||||
|
mode = [
|
||||||
|
"n"
|
||||||
|
"v"
|
||||||
|
];
|
||||||
|
action = "g<Up>";
|
||||||
|
desc = "Visual Line Up";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
key = "<Down>";
|
||||||
|
mode = [
|
||||||
|
"n"
|
||||||
|
"v"
|
||||||
|
];
|
||||||
|
action = "g<Down>";
|
||||||
|
desc = "Visual Line Down";
|
||||||
|
}
|
||||||
|
|
||||||
|
# lsp
|
||||||
|
#{ key = "gd"; mode = [ "n" ]; action = "<cmd>lua vim.lsp.buf.definition()<CR>"; desc = "Go to definition"; }
|
||||||
|
#{ key = "K"; mode = [ "n" ]; action = "<cmd>lua vim.lsp.buf.hover()<CR>"; desc = "Hover info"; }
|
||||||
|
#{ key = "<leader>f"; mode = [ "n" ]; action = "<cmd>lua vim.lsp.buf.format({ async = true })<CR>"; desc = "Format buffer"; }
|
||||||
|
|
||||||
|
{
|
||||||
|
key = "gd";
|
||||||
|
mode = [ "n" ];
|
||||||
|
silent = true;
|
||||||
|
action = "<cmd>lua vim.lsp.buf.definition()<CR>";
|
||||||
|
desc = "Go to definition";
|
||||||
|
}
|
||||||
|
# Hover info
|
||||||
|
{
|
||||||
|
key = "K";
|
||||||
|
mode = [ "n" ];
|
||||||
|
silent = true;
|
||||||
|
action = "<cmd>lua vim.lsp.buf.hover()<CR>";
|
||||||
|
desc = "Hover info";
|
||||||
|
}
|
||||||
|
# Format buffer (Alejandra for Nix)
|
||||||
|
{
|
||||||
|
key = "<leader>F";
|
||||||
|
mode = [ "n" ];
|
||||||
|
silent = true;
|
||||||
|
action = "<cmd>lua vim.lsp.buf.format({ async = true })<CR>";
|
||||||
|
desc = "Format buffer";
|
||||||
|
}
|
||||||
|
# Code actions / quickfix
|
||||||
|
{
|
||||||
|
key = "<leader>a";
|
||||||
|
mode = [ "n" ];
|
||||||
|
silent = true;
|
||||||
|
action = "<cmd>lua vim.lsp.buf.code_action()<CR>";
|
||||||
|
desc = "Code action";
|
||||||
|
}
|
||||||
|
# Rename symbol
|
||||||
|
{
|
||||||
|
key = "<leader>r";
|
||||||
|
mode = [ "n" ];
|
||||||
|
silent = true;
|
||||||
|
action = "<cmd>lua vim.lsp.buf.rename()<CR>";
|
||||||
|
desc = "Rename symbol";
|
||||||
|
}
|
||||||
|
# Diagnostics
|
||||||
|
{
|
||||||
|
key = "<leader>e";
|
||||||
|
mode = [ "n" ];
|
||||||
|
silent = true;
|
||||||
|
action = "<cmd>lua vim.diagnostic.open_float()<CR>";
|
||||||
|
desc = "Show diagnostic";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
key = "[d";
|
||||||
|
mode = [ "n" ];
|
||||||
|
silent = true;
|
||||||
|
action = "<cmd>lua vim.diagnostic.goto_prev()<CR>";
|
||||||
|
desc = "Previous diagnostic";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
key = "]d";
|
||||||
|
mode = [ "n" ];
|
||||||
|
silent = true;
|
||||||
|
action = "<cmd>lua vim.diagnostic.goto_next()<CR>";
|
||||||
|
desc = "Next diagnostic";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
clipboard = "unnamedplus";
|
||||||
|
|
||||||
|
# line numbers
|
||||||
|
number = true;
|
||||||
|
numberwidth = 2;
|
||||||
|
relativenumber = true;
|
||||||
|
|
||||||
|
# tabs and indentation
|
||||||
|
tabstop = 2;
|
||||||
|
shiftwidth = 2;
|
||||||
|
softtabstop = -1;
|
||||||
|
expandtab = true;
|
||||||
|
smarttab = true;
|
||||||
|
autoindent = true;
|
||||||
|
|
||||||
|
# search
|
||||||
|
ignorecase = true;
|
||||||
|
smartcase = true;
|
||||||
|
|
||||||
|
# files and backups
|
||||||
|
backup = false;
|
||||||
|
writebackup = false;
|
||||||
|
undofile = true;
|
||||||
|
swapfile = true;
|
||||||
|
|
||||||
|
# wrapping
|
||||||
|
wrap = true;
|
||||||
|
linebreak = true;
|
||||||
|
breakindent = true;
|
||||||
|
|
||||||
|
termguicolors = true;
|
||||||
|
autoread = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
languages = {
|
||||||
|
enableTreesitter = true;
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
enable = true;
|
||||||
|
format = {
|
||||||
|
enable = true;
|
||||||
|
type = "alejandra";
|
||||||
|
#type = "nixfmt";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
markdown.enable = true;
|
||||||
|
rust.enable = true;
|
||||||
|
lua.enable = true;
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,20 +1,25 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, inputs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
./dots/neovim
|
||||||
|
./dots/lf
|
||||||
|
];
|
||||||
|
|
||||||
# general config
|
# general config
|
||||||
home.username = "blake";
|
home.username = "blake";
|
||||||
home.homeDirectory = "/home/blake";
|
home.homeDirectory = "/home/blake";
|
||||||
|
home.stateVersion = "25.05";
|
||||||
|
|
||||||
|
# stand alone packages
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
git
|
|
||||||
lf
|
|
||||||
ripgrep
|
ripgrep
|
||||||
btop
|
btop
|
||||||
p7zip
|
p7zip
|
||||||
ctpv
|
|
||||||
imagemagick
|
imagemagick
|
||||||
sops
|
sops
|
||||||
usbutils
|
usbutils
|
||||||
trashy
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
@@ -22,6 +27,7 @@
|
|||||||
home.sessionVariables.ZDOTDIR = "$HOME/.config/zsh";
|
home.sessionVariables.ZDOTDIR = "$HOME/.config/zsh";
|
||||||
programs.zsh = {
|
programs.zsh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
# dotDir = ".config/zsh";
|
||||||
};
|
};
|
||||||
# link dotfiles
|
# link dotfiles
|
||||||
xdg.configFile."zsh" = {
|
xdg.configFile."zsh" = {
|
||||||
@@ -29,30 +35,6 @@
|
|||||||
recursive = true;
|
recursive = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# setup neovim
|
|
||||||
programs.neovim = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
# link dotfiles
|
|
||||||
xdg.configFile."nvim" = {
|
|
||||||
source = config.lib.file.mkOutOfStoreSymlink "/home/blake/.nix/users/blake/dotfiles/nvim";
|
|
||||||
recursive = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# setup lf
|
|
||||||
programs.lf = {
|
|
||||||
enable = false;
|
|
||||||
};
|
|
||||||
# link dotfiles
|
|
||||||
xdg.configFile."lf" = {
|
|
||||||
source = config.lib.file.mkOutOfStoreSymlink "/home/blake/.nix/users/blake/dotfiles/lf";
|
|
||||||
recursive = true;
|
|
||||||
};
|
|
||||||
xdg.configFile."ctpv" = {
|
|
||||||
source = config.lib.file.mkOutOfStoreSymlink "/home/blake/.nix/users/blake/dotfiles/ctpv";
|
|
||||||
recursive = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.gpg = {
|
programs.gpg = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
@@ -96,5 +78,4 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
home.stateVersion = "25.05";
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user