From 0a84fd15338feab14580918891801e8bb5e40374 Mon Sep 17 00:00:00 2001 From: Brian Lee Date: Sat, 22 Feb 2025 17:29:24 -0800 Subject: [PATCH] litten: add tandoor-recipes and other minor changes --- .cursorignore | 3 +- .gitignore | 1 - litten.brenise.dev/README.md | 60 ++++++ litten.brenise.dev/configuration.nix | 186 ++++++++++++------ litten.brenise.dev/home.nix | 22 ++- .../opt/open-webui/litellm.yaml | 54 +++++ 6 files changed, 260 insertions(+), 66 deletions(-) create mode 100644 litten.brenise.dev/README.md create mode 100644 litten.brenise.dev/opt/open-webui/litellm.yaml diff --git a/.cursorignore b/.cursorignore index 51e0893..caa502d 100644 --- a/.cursorignore +++ b/.cursorignore @@ -1,2 +1 @@ -secrets.nix -litellm.yaml \ No newline at end of file +secrets.nix \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2834758..b75fae7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,4 @@ secrets.nix archive/ glance/config.yaml -litellm.yaml result \ No newline at end of file diff --git a/litten.brenise.dev/README.md b/litten.brenise.dev/README.md new file mode 100644 index 0000000..6af2150 --- /dev/null +++ b/litten.brenise.dev/README.md @@ -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- +# +# 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--", 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" +``` diff --git a/litten.brenise.dev/configuration.nix b/litten.brenise.dev/configuration.nix index a699f7f..0ec996a 100644 --- a/litten.brenise.dev/configuration.nix +++ b/litten.brenise.dev/configuration.nix @@ -1,14 +1,28 @@ { config, pkgs, lib, ... }: let + host_name = "litten"; + host_fqdn = "${host_name}.brenise.dev"; + secrets = import ./secrets.nix; + # Add nixpkgs-unstable channel with the following command: # 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 unstable = import { 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 { # nix.settings.experimental-features = [ "nix-command" "flakes" ]; +# nix.shellHook = '' +# if [ -z "$IN_NIX_SHELL" ]; then +# exec fish +# fi +# ''; nixpkgs.config = { allowUnfreePredicate = pkg: @@ -16,10 +30,16 @@ in "obsidian" "packer" "reaper" + "n8n" "vscode" "terraform" "zoom" "charlatan3" + "steam" + "steam-original" + "steam-unwrapped" + "steam-run" + "tokenizer.json" # goose-cli ]; }; nixpkgs.overlays = [ @@ -59,7 +79,6 @@ in networking = { hostName = "${host_name}"; - # networkmanager.enable = true; firewall.enable = false; interfaces = { enp100s0.ipv4.addresses = [{ @@ -76,6 +95,10 @@ in extraHosts = '' 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"; @@ -88,7 +111,11 @@ in }; users = { - groups.glance = {}; + groups = { + glance = {}; + n8n = {}; + mealie = {}; + }; users = { root = { @@ -104,10 +131,17 @@ in isNormalUser = true; extraGroups = [ "wheel" + "adbusers" "docker" "glance" - ]; + "n8n" + "mealie" + ]; packages = with pkgs; [ + # unstable.n8n + # unstable.goose-cli + gh + solaar binutils chromium coreutils # base64 @@ -123,10 +157,12 @@ in # unstable.logseq # warning: https://github.com/logseq/logseq/issues/10851#issuecomment-2402925912 unstable.ghostty moonlight-qt + nmap obs-studio obsidian pavucontrol # qbittorrent + rclone rtorrent sq synergy @@ -136,7 +172,6 @@ in via vlc vscode - xcaddy # warning: awfuly hacky yt-dlp zoom-us @@ -155,8 +190,7 @@ in python311Packages.ipython libreoffice-qt hunspell - hunspellDicts.uk_UA - hunspellDicts.th_TH + hunspellDicts.en-us # postman # nope, auth is broken nodejs_20 yarn @@ -179,14 +213,35 @@ in # 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 = { systemPackages = with pkgs; [ # GPU tools - android-tools arp-scan cryptsetup curl @@ -252,6 +307,7 @@ in }; programs = { + adb.enable = true; appimage = { enable = true; binfmt = true; @@ -291,6 +347,7 @@ in enableSSHSupport = true; }; kdeconnect.enable = true; + steam.enable = true; chromium = { enable = true; extraOpts = { @@ -363,6 +420,8 @@ in caddy = { enable = true; + package = caddyWithPlugins; + logFormat = "output discard"; extraConfig = let tlsConfig = '' @@ -401,7 +460,19 @@ in 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; }; + 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 = { - 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 = { wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; @@ -442,40 +552,6 @@ in 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 = { wantedBy = [ "multi-user.target" ]; diff --git a/litten.brenise.dev/home.nix b/litten.brenise.dev/home.nix index 4c043c1..6e3f4bd 100644 --- a/litten.brenise.dev/home.nix +++ b/litten.brenise.dev/home.nix @@ -21,18 +21,24 @@ in # Troubleshooting: ldd ~/.clap/Charlatan3.so # Status: Not working, Reaper doesn't load the plugin. -# file = { -# ".clap/Charlatan3.so" = { -# source = "${plebpkgs.charlatan3}/lib/charlatan3/Charlatan3.so"; -# }; -# ".local/share/charlatan3/presets" = { -# source = "${plebpkgs.charlatan3}/share/charlatan3/presets"; -# }; + file = { + ".clap/Charlatan3.so" = { + source = "${plebpkgs.charlatan3}/lib/charlatan3/Charlatan3.so"; + }; + ".local/share/charlatan3/presets" = { + source = "${plebpkgs.charlatan3}/share/charlatan3/presets"; + }; + }; + +# programs.git = { +# enable = true; +# userName = "Brian Lee"; +# userEmail = "git@satstack.dev"; # }; username = "blee"; homeDirectory = "/home/blee"; - stateVersion = "23.11"; + stateVersion = "24.11"; }; } \ No newline at end of file diff --git a/litten.brenise.dev/opt/open-webui/litellm.yaml b/litten.brenise.dev/opt/open-webui/litellm.yaml new file mode 100644 index 0000000..8c6af6f --- /dev/null +++ b/litten.brenise.dev/opt/open-webui/litellm.yaml @@ -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: {} +