litten: add tandoor-recipes and other minor changes

This commit is contained in:
Brian Lee 2025-02-22 17:29:24 -08:00
parent be16241253
commit 0a84fd1533
6 changed files with 260 additions and 66 deletions

View File

@ -1,2 +1 @@
secrets.nix secrets.nix
litellm.yaml

1
.gitignore vendored
View File

@ -2,5 +2,4 @@
secrets.nix secrets.nix
archive/ archive/
glance/config.yaml glance/config.yaml
litellm.yaml
result result

View File

@ -0,0 +1,60 @@
# Litten
* n8n - [cli commands](https://docs.n8n.io/hosting/cli-commands/#credentials)
## Caddy with namecheap-dns
Some special handling is necessary for Caddy
```sh
#!/usr/bin/env bash
# This script demonstrates how to construct a Go pseudo-version for a commit from the
# "caddy-dns/namecheap" repository using curl, jq, and date.
#
# The pseudoversion format is:
# 0.0.0-YYYYMMDDHHMMSS-<short-commit-hash>
#
# Steps:
#
# 1. Query the GitHub API for the commit metadata. (The URL is:
# https://api.github.com/repos/caddy-dns/namecheap/commits/HEAD
# You can replace HEAD with a specific commit SHA if needed.)
#
# 2. Extract the commit date. The GitHub API returns the date in ISO 8601 format, e.g.,
# "2025-02-15T18:47:56Z".
#
# 3. Convert that date to UTC timestamp in the format YYYYMMDDHHMMSS.
#
# 4. Extract the full commit SHA and take its first 12 characters.
#
# 5. Combine these values in the form: "0.0.0-<timestamp>-<short-hash>", resulting in a pseudo-version,
# like: "0.0.0-20250215184756-635a4c34fd25"
#
# Example:
# Given:
# Commit date = "2025-02-15T18:47:56Z"
# Commit SHA = "635a4c34fd25d48df62f8e9d5485ac9026796a83"
# The pseudo-version will be:
# 0.0.0-20250215184756-635a4c34fd25
# Set the commit reference (or use a specific commit SHA instead of "HEAD")
COMMIT_REF="HEAD"
# Fetch commit metadata from GitHub API
COMMIT_JSON=$(curl -s "https://api.github.com/repos/caddy-dns/namecheap/commits/$COMMIT_REF")
# Extract the commit date (author date)
COMMIT_DATE=$(echo "$COMMIT_JSON" | jq -r '.commit.author.date')
# Convert the date to UTC (should already be in UTC if it ends with 'Z') and format it as YYYYMMDDHHMMSS
TIMESTAMP=$(date -u -d "$COMMIT_DATE" +"%Y%m%d%H%M%S")
# Extract the full commit hash and get the first 12 characters
FULL_HASH=$(echo "$COMMIT_JSON" | jq -r '.sha')
SHORT_HASH=${FULL_HASH:0:12}
# Construct the pseudo-version string
PSEUDO_VERSION="0.0.0-${TIMESTAMP}-${SHORT_HASH}"
echo "Pseudo-Version: $PSEUDO_VERSION"
```

View File

@ -1,14 +1,28 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
let let
host_name = "litten";
host_fqdn = "${host_name}.brenise.dev";
secrets = import ./secrets.nix;
# Add nixpkgs-unstable channel with the following command: # Add nixpkgs-unstable channel with the following command:
# nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs-unstable && nix-channel --update # nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs-unstable && nix-channel --update
# 09/15/24: Use nixpkgs-unstable for logseq, see https://github.com/NixOS/nixpkgs/pull/340427 # 09/15/24: Use nixpkgs-unstable for logseq, see https://github.com/NixOS/nixpkgs/pull/340427
unstable = import <nixpkgs-unstable> { config = config.nixpkgs.config; }; unstable = import <nixpkgs-unstable> { config = config.nixpkgs.config; };
host_name = "litten";
host_fqdn = "${host_name}.brenise.dev"; # https://github.com/NixOS/nixpkgs/pull/358586
caddyWithPlugins = unstable.caddy.withPlugins {
# commit: 7095083a353829fc83632c34e8988fd8eb72f43d (01/14/2024)
plugins = ["github.com/caddy-dns/namecheap@v0.0.0-20240114194457-7095083a3538"];
hash = "sha256-Wu4j6XBNHX+ckCBmqTMC7ECLnOc3D3IJ04sJF14NHJo="; # WARNING: This will change every update
};
in in
{ {
# nix.settings.experimental-features = [ "nix-command" "flakes" ]; # nix.settings.experimental-features = [ "nix-command" "flakes" ];
# nix.shellHook = ''
# if [ -z "$IN_NIX_SHELL" ]; then
# exec fish
# fi
# '';
nixpkgs.config = { nixpkgs.config = {
allowUnfreePredicate = pkg: allowUnfreePredicate = pkg:
@ -16,10 +30,16 @@ in
"obsidian" "obsidian"
"packer" "packer"
"reaper" "reaper"
"n8n"
"vscode" "vscode"
"terraform" "terraform"
"zoom" "zoom"
"charlatan3" "charlatan3"
"steam"
"steam-original"
"steam-unwrapped"
"steam-run"
"tokenizer.json" # goose-cli
]; ];
}; };
nixpkgs.overlays = [ nixpkgs.overlays = [
@ -59,7 +79,6 @@ in
networking = { networking = {
hostName = "${host_name}"; hostName = "${host_name}";
# networkmanager.enable = true;
firewall.enable = false; firewall.enable = false;
interfaces = { interfaces = {
enp100s0.ipv4.addresses = [{ enp100s0.ipv4.addresses = [{
@ -76,6 +95,10 @@ in
extraHosts = '' extraHosts = ''
192.168.1.1 shinx.${host_fqdn} 192.168.1.1 shinx.${host_fqdn}
''; '';
localCommands = ''
ip route add 10.19.21.11/32 dev ${config.networking.defaultGateway.interface} via ${config.networking.defaultGateway.address} || true # timburr
ip route add 10.19.21.34/32 dev ${config.networking.defaultGateway.interface} via ${config.networking.defaultGateway.address} || true # weavile
'';
}; };
time.timeZone = "America/Los_Angeles"; time.timeZone = "America/Los_Angeles";
@ -88,7 +111,11 @@ in
}; };
users = { users = {
groups.glance = {}; groups = {
glance = {};
n8n = {};
mealie = {};
};
users = { users = {
root = { root = {
@ -104,10 +131,17 @@ in
isNormalUser = true; isNormalUser = true;
extraGroups = [ extraGroups = [
"wheel" "wheel"
"adbusers"
"docker" "docker"
"glance" "glance"
"n8n"
"mealie"
]; ];
packages = with pkgs; [ packages = with pkgs; [
# unstable.n8n
# unstable.goose-cli
gh
solaar
binutils binutils
chromium chromium
coreutils # base64 coreutils # base64
@ -123,10 +157,12 @@ in
# unstable.logseq # warning: https://github.com/logseq/logseq/issues/10851#issuecomment-2402925912 # unstable.logseq # warning: https://github.com/logseq/logseq/issues/10851#issuecomment-2402925912
unstable.ghostty unstable.ghostty
moonlight-qt moonlight-qt
nmap
obs-studio obs-studio
obsidian obsidian
pavucontrol pavucontrol
# qbittorrent # qbittorrent
rclone
rtorrent rtorrent
sq sq
synergy synergy
@ -136,7 +172,6 @@ in
via via
vlc vlc
vscode vscode
xcaddy # warning: awfuly hacky
yt-dlp yt-dlp
zoom-us zoom-us
@ -155,8 +190,7 @@ in
python311Packages.ipython python311Packages.ipython
libreoffice-qt libreoffice-qt
hunspell hunspell
hunspellDicts.uk_UA hunspellDicts.en-us
hunspellDicts.th_TH
# postman # nope, auth is broken # postman # nope, auth is broken
nodejs_20 nodejs_20
yarn yarn
@ -179,14 +213,35 @@ in
# shell = pkgs.bash; # shell = pkgs.bash;
}; };
n8n = {
isSystemUser = true;
group = "n8n";
home = "/var/lib/n8n";
createHome = true;
description = "System account for n8n";
shell = pkgs.bashInteractive;
packages = with pkgs; [
unstable.n8n
];
};
mealie = {
isSystemUser = true;
group = "mealie";
description = "Mealie service user";
home = "/var/lib/mealie";
createHome = true;
packages = with pkgs; [
unstable.mealie
];
}; };
}; };
home-manager.users.blee = { imports = [ ./home.nix ]; }; };
# home-manager.users.blee = { imports = [ ./home.nix ]; };
environment = { environment = {
systemPackages = with pkgs; [ systemPackages = with pkgs; [
# GPU tools # GPU tools
android-tools
arp-scan arp-scan
cryptsetup cryptsetup
curl curl
@ -252,6 +307,7 @@ in
}; };
programs = { programs = {
adb.enable = true;
appimage = { appimage = {
enable = true; enable = true;
binfmt = true; binfmt = true;
@ -291,6 +347,7 @@ in
enableSSHSupport = true; enableSSHSupport = true;
}; };
kdeconnect.enable = true; kdeconnect.enable = true;
steam.enable = true;
chromium = { chromium = {
enable = true; enable = true;
extraOpts = { extraOpts = {
@ -363,6 +420,8 @@ in
caddy = { caddy = {
enable = true; enable = true;
package = caddyWithPlugins;
logFormat = "output discard"; logFormat = "output discard";
extraConfig = let extraConfig = let
tlsConfig = '' tlsConfig = ''
@ -401,7 +460,19 @@ in
reverse_proxy http://127.0.0.1:8032 reverse_proxy http://127.0.0.1:8032
} }
${host_fqdn}:4433 { # n8n
${tlsConfig}
reverse_proxy http://127.0.0.1:8033
}
${host_fqdn}:4434 { # tandoor-recipes
${tlsConfig}
reverse_proxy http://127.0.0.1:8034
}
:9999 {
respond "success"
}
''; '';
}; };
@ -414,23 +485,62 @@ in
desktopManager.plasma5.enable = true; desktopManager.plasma5.enable = true;
}; };
tandoor-recipes = {
enable = true;
# address = "127.0.0.1";
port = 8034;
extraConfig = {
# https://github.com/TandoorRecipes/recipes/raw/refs/heads/develop/docs/system/configuration.md
SECRET_KEY = "${secrets.tandoorSecretKey}";
ALLOWED_HOSTS = "${host_fqdn}";
TANDOOR_PORT = "8034";
};
};
}; };
systemd = { systemd = {
services.caddy = {
serviceConfig = {
EnvironmentFile = "/var/src/secrets/namecheap";
ExecStart = [
"" # This empty string clears the existing ExecStart commands
"/opt/bin/caddy run --config /etc/caddy/caddy_config --adapter caddyfile"
];
ExecReload = [
"" # This empty string clears the existing ExecReload commands
"/opt/bin/caddy reload --config /etc/caddy/caddy_config --adapter caddyfile --force"
];
services.mealie = {
enable = true;
description = "Mealie";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "mealie";
Group = "mealie";
WorkingDirectory = "/var/lib/mealie";
ExecStart = "${pkgs.mealie}/bin/mealie";
Restart = "on-failure";
RestartSec = "1m";
Environment = [
"MEALIE_PORT=8035"
];
}; };
}; };
services.n8n = {
enable = true;
description = "n8n";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "n8n";
Group = "n8n";
ExecStart = "${unstable.n8n}/bin/n8n";
Restart = "on-failure";
RestartSec = "1m";
Environment = [
"N8N_PORT=8033"
"N8N_EDITOR_BASE_URL=https://${host_fqdn}:4433"
"N8N_HIRING_BANNER_ENABLED=false"
"N8N_METRICS=true"
];
};
};
services.glance = { services.glance = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network.target" ]; after = [ "network.target" ];
@ -442,40 +552,6 @@ in
ExecStart = "${pkgs.glance}/bin/glance --config config.yaml"; ExecStart = "${pkgs.glance}/bin/glance --config config.yaml";
}; };
}; };
# TODO: fix errors
# services.nightly-backups = {
# description = "Nightly Backup Service";
# wantedBy = [ "multi-user.target" ];
# after = [ "network.target" ];
# # enable = false; # testing
# serviceConfig = {
# User = "blee";
# Type = "oneshot";
# Environment = "NIX_PATH=nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels";
# WorkingDirectory = "/home/blee/ops/brenise.dev/scripts/backups";
# # batch.sh calls other shell scripts which leads to nix environment hell.
# # As a workaround, I think we could add multiple ExecStart lines for other backup scripts.
# # ExecStart = "${pkgs.bash}/bin/bash /home/blee/ops/brenise.dev/scripts/backups/batch.sh";
# ExecStart = "${pkgs.bash}/bin/bash /home/blee/ops/brenise.dev/scripts/backups/hosts/litten.brenise.dev.sh";
# # Path = [
# # "${pkgs.openssh}/bin"
# # "${pkgs.coreutils}/bin"
# # "${pkgs.gnugrep}/bin"
# # "${pkgs.gnused}/bin"
# # ];
# };
# };
# timers.nightly-backups = {
# wantedBy = [ "timers.target" ];
# partOf = [ "nightly-backups.service" ];
# timerConfig = {
# OnCalendar = "daily";
# nCalendar = "*-*-* 03:00:00";
# # Persistent = true;
# Unit = "nightly-backups.service";
# };
# };
services.open-webui = { services.open-webui = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];

View File

@ -21,18 +21,24 @@ in
# Troubleshooting: ldd ~/.clap/Charlatan3.so # Troubleshooting: ldd ~/.clap/Charlatan3.so
# Status: Not working, Reaper doesn't load the plugin. # Status: Not working, Reaper doesn't load the plugin.
# file = { file = {
# ".clap/Charlatan3.so" = { ".clap/Charlatan3.so" = {
# source = "${plebpkgs.charlatan3}/lib/charlatan3/Charlatan3.so"; source = "${plebpkgs.charlatan3}/lib/charlatan3/Charlatan3.so";
# }; };
# ".local/share/charlatan3/presets" = { ".local/share/charlatan3/presets" = {
# source = "${plebpkgs.charlatan3}/share/charlatan3/presets"; source = "${plebpkgs.charlatan3}/share/charlatan3/presets";
# }; };
};
# programs.git = {
# enable = true;
# userName = "Brian Lee";
# userEmail = "git@satstack.dev";
# }; # };
username = "blee"; username = "blee";
homeDirectory = "/home/blee"; homeDirectory = "/home/blee";
stateVersion = "23.11"; stateVersion = "24.11";
}; };
} }

View File

@ -0,0 +1,54 @@
#general_settings: {}
#litellm_settings: {}
litellm_settings:
set_verbose: True
# https://docs.litellm.ai/docs/providers/
model_list:
# https://docs.x.ai/docs/overview#featured-models
- model_name: grok-3
litellm_params:
model: xai/grok-3-latest
api_key: os.environ/XAI_API_KEY
# https://console.groq.com/docs/models
- model_name: deepseek-r1-distill-llama-70b
litellm_params:
model: groq/deepseek-r1-distill-llama-70b
api_key: os.environ/GROK_API_KEY
# https://docs.anthropic.com/en/docs/about-claude/models
- model_name: claude-3.5-sonnet
litellm_params:
model: anthropic/claude-3-5-sonnet-latest
api_key: os.environ/ANTHROPIC_API_KEY
# https://ai.google.dev/gemini-api/docs/models/gemini#gemini-2.0-flash
- model_name: gemini-2.0-flash
litellm_params:
model: gemini/gemini-2.0-flash-exp
api_key: os.environ/GOOGLE_API_KEY
safety_settings:
- category: HARM_CATEGORY_HARASSMENT
threshold: BLOCK_NONE
- category: HARM_CATEGORY_HATE_SPEECH
threshold: BLOCK_NONE
- category: HARM_CATEGORY_SEXUALLY_EXPLICIT
threshold: BLOCK_NONE
- category: HARM_CATEGORY_DANGEROUS_CONTENT
threshold: BLOCK_NONE
# Note: no payment method added yet, identity not disclosed
# https://docs.mistral.ai/getting-started/models/models_overview/
# - model_name: mistral-large
# litellm_params:
# model: mistral/mistral-large-latest
# api_key: os.environ/MISTRAL_API_KEY
#router_settings: {}
#router_settings: {}