diff --git a/dotfiles/unpackerr.conf b/dotfiles/unpackerr.conf new file mode 100644 index 0000000..c049ce9 --- /dev/null +++ b/dotfiles/unpackerr.conf @@ -0,0 +1,222 @@ +## Unpackerr Example Configuration File ## +## The following values are application defaults. ## +## Environment Variables may override all values. ## +#################################################### + +# [true/false] Turn on debug messages in the output. Do not wrap this in quotes. +# Recommend trying this so you know what it looks like. I personally leave it on. +debug = false + +# Disable writing messages to stdout. This silences the app. You should set a log +# file below if you set this to true. Recommended when starting with systemctl. +quiet = false + +# Setting activity to true will silence all app queue log lines with only zeros. +# Set this to true when you want less log spam. +activity = false + +# The application queue data is logged on an interval. Adjust that interval with this setting. +# Default is a minute. 2m, 5m, 10m, 30m, 1h are also perfectly acceptable. +log_queues = "1m" + +# Write messages to a log file. This is the same data that is normally output to stdout. +# This setting is great for Docker users that want to export their logs to a file. +# The alternative is to use syslog to log the output of the application to a file. +# Default is no log file; this is unset. log_files=0 turns off auto-rotation. +# Default files is 10 and size(mb) is 10 Megabytes; both doubled if debug is true. +#log_file = '/downloads/unpackerr.log' +log_files = 10 +log_file_mb = 10 + +# How often to poll sonarr and radarr. +# Recommend 1m-5m. Uses Go Duration. +interval = "5m" + +# How long an item must be queued (download complete) before extraction will start. +# One minute is the historic default and works well. Set higher if your downloads +# take longer to finalize (or transfer locally). Uses Go Duration. +start_delay = "1m" + +# How long to wait before removing the history for a failed extraction. +# Once the history is deleted the item will be recognized as new and +# extraction will start again. Uses Go Duration. +retry_delay = "5m" + +# How many files may be extracted in parallel. 1 works fine. +# Do not wrap the number in quotes. Raise this only if you have fast disks and CPU. +parallel = 1 + +# Use these configurations to control the file modes used for newly extracted +# files and folders. Recommend 0644/0755 or 0666/0777. +file_mode = "0664" +dir_mode = "0775" + +[webserver] +## The web server currently only supports metrics; set this to true if you wish to use it. + metrics = false +## This may be set to a port or an ip:port to bind a specific IP. 0.0.0.0 binds ALL IPs. + listen_addr = "0.0.0.0:5656" +## Recommend setting a log file for HTTP requests. Otherwise, they go with other logs. + log_file = "" +## This app automatically rotates logs. Set these to the size and number to keep. + log_files = 10 + log_file_mb = 10 +## Set both of these to valid file paths to enable HTTPS/TLS. + ssl_cert_file = "" + ssl_key_file = "" +## Base URL from which to serve content. + urlbase = "/" +## Upstreams should be set to the IP or CIDR of your trusted upstream proxy. +## Setting this correctly allows X-Forwarded-For to be used in logs. +## In the future it may control auth proxy trust. Must be a list of strings. + upstreams = [ ] # example: upstreams = [ "127.0.0.1/32", "10.1.2.0/24" ] + +##-Notes-#######-READ THIS!!!-################################################## +## The following sections can be repeated if you have more than one Sonarr, ## +## Radarr or Lidarr, Readarr, Folder, Webhook, or Command Hook. ## +## You MUST uncomment the [[header]] and api_key at a minimum for Starr apps. ## +## ALL LINES BEGINNING WITH A HASH # ARE IGNORED ## +## REMOVE THE HASH # FROM CONFIG LINES YOU WANT TO CHANGE ## +################################################################################ + +[[sonarr]] +url = "http://localhost:8989" +api_key = "52869fe7bec4482dafb21c4053fe71e4" +## File system path where downloaded Sonarr items are located. +paths = ['/mnt/pool/multimedia/downloads/torrent'] +## Default protocols is torrent. Alternative: "torrent,usenet" +protocols = "torrent" +## How long to wait for a reply from the backend. +timeout = "10s" +## How long to wait after import before deleting the extracted items. +delete_delay = "5m" +## If you use this app with NZB you may wish to delete archives after extraction. +## General recommendation is: do not enable this for torrent use. +## Setting this to true deletes the entire original download folder after import. +# delete_orig = false +## If you use Syncthing, setting this to true will make unpackerr wait for syncs to finish. +# syncthing = false + +[[radarr]] +url = "http://127.0.0.1:7878" +api_key = "a987ac45ca2c47bc88e762031ea33296" +## File system path where downloaded Radarr items are located. +paths = ['/mnt/pool/multimedia/downloads/torrent'] +## Default protocols is torrents. Alternative: "torrent,usenet" +protocols = "torrent" +## How long to wait for a reply from the backend. +timeout = "10s" +## How long to wait after import before deleting the extracted items. +delete_delay = "5m" +## If you use this app with NZB you may wish to delete archives after extraction. +## General recommendation is: do not enable this for torrent use. +## Setting this to true deletes the entire original download folder after import. +# delete_orig = false +## If you use Syncthing, setting this to true will make unpackerr wait for syncs to finish. +# syncthing = false + +#[[lidarr]] +# url = "http://127.0.0.1:8686" +# api_key = "0123456789abcdef0123456789abcdef" +## File system path where downloaded Lidarr items are located. +# paths = ['/downloads'] +## Default protocols is torrent. Alternative: "torrent,usenet" +# protocols = "torrent" +## How long to wait for a reply from the backend. +# timeout = "10s" +## How long to wait after import before deleting the extracted items. +# delete_delay = "5m" +## If you use this app with NZB you may wish to delete archives after extraction. +## General recommendation is: do not enable this for torrent use. +## Setting this to true deletes the entire original download folder after import. +# delete_orig = false +## If you use Syncthing, setting this to true will make unpackerr wait for syncs to finish. +# syncthing = false + +#[[readarr]] +# url = "http://127.0.0.1:8787" +# api_key = "0123456789abcdef0123456789abc" +## File system path where downloaded Readarr items are located. +# paths = ['/downloads'] +## Default protocols is torrent. Alternative: "torrent,usenet" +# protocols = "torrent" +## How long to wait for a reply from the backend. +# timeout = "10s" +## How long to wait after import before deleting the extracted items. +# delete_delay = "5m" +## If you use this app with NZB you may wish to delete archives after extraction. +## General recommendation is: do not enable this for torrent use. +## Setting this to true deletes the entire original download folder after import. +# delete_orig = false +## If you use Syncthing, setting this to true will make unpackerr wait for syncs to finish. +# syncthing = false + + +################################################################################## +### ### STOP HERE ### STOP HERE ### STOP HERE ### STOP HERE #### STOP HERE ### # +### Only using Starr apps? The things above. The below configs are OPTIONAL. ### # +################################################################################## + +##-Folders-####################################################################### +## This application can also watch folders for things to extract. If you copy a ## +## subfolder into a watched folder (defined below) any extractable items in the ## +## folder will be decompressed. This has nothing to do with Starr applications. ## +################################################################################## +#[[folder]] +# path = '/some/folder/to/watch' +## Path to extract files to. The default (leaving this blank) is the same as `path` (above). +# extract_path = "" +## Delete extracted or original files this long after extraction. +## The default is 0. Set to 0 to disable all deletes. Uncomment it to enable deletes. Uses Go Duration. +# delete_after = "10m" +## Delete extracted files after successful extraction? true/false, no quotes. Honors delete_after. +# delete_files = false +## Delete original items after successful extraction? true/false, no quotes. Honors delete_after. +# delete_original = false +## Disable extraction log (unpackerred.txt) file creation? true/false, no quotes. +# disable_log = false +## Move extracted files into original folder? If false, files go into an _unpackerred folder. +# move_back = false +## Set this to true if you want this app to extract ISO files with .iso extension. +# extract_isos = false + + +################ +### Webhooks ### +################ +# Sends a webhook when an extraction queues, starts, finishes, and/or is deleted. +# Created to integrate with notifiarr.com. +# Also works natively with Discord.com, Telegram.org, and Slack.com webhooks. +# Can possibly be used with other services by providing a custom template_path. +###### Don't forget to uncomment [[webhook]] and url at a minimum !!!! +#[[webhook]] +# url = "https://notifiarr.com/api/v1/notification/unpackerr/api_key_from_notifiarr_com" +# name = "" # Set this to hide the URL in logs. +# silent = false # do not log success (less log spam) +# events = [0] # list of event ids to include, 0 == all. +## Advanced Optional Webhook Configuration +# nickname = "" # Used in Discord and Slack templates as bot name, in Telegram as chat_id. +# channel = "" # Also passed into templates. Used in Slack templates for destination channel. +# exclude = [] # list of apps to exclude, ie. ["radarr", "lidarr"] +# template_path = "" # Override internal webhook template for discord.com or other hooks. +# template = "" # Override automatic template detection. Values: notifiarr, discord, telegram, gotify, pushover, slack +# ignore_ssl = false # Set this to true to ignore the SSL certificate on the server. +# timeout = "10s" # You can adjust how long to wait for a server response. +# content_type = "application/json" # If your custom template uses another MIME type, set this. + + +##################### +### Command Hooks ### +##################### +# Executes a script or command when an extraction queues, starts, finishes, and/or is deleted. +# All data is passed in as environment variables. Try /usr/bin/env to see what variables are available. +###### Don't forget to uncomment [[cmdhook]] and url at a minimum !!!! +#[[cmdhook]] +# command = '/my/cool/app' # Path to command or script. +# shell = false # Runs the command inside /bin/sh ('nix) or cmd.exe (Windows). +# name = "" # Provide an optional name for logging. +# silent = false # Hides command output from logs. +# events = [0] # list of event ids to include, 0 == all. +## Optional Command Hook Configuration +# exclude = [] # list of apps to exclude, ie. ["radarr", "lidarr"] +# timeout = "10s" # You can adjust how long to wait for a server response. diff --git a/miniserver/configuration.nix b/miniserver/configuration.nix new file mode 100644 index 0000000..cd7e920 --- /dev/null +++ b/miniserver/configuration.nix @@ -0,0 +1,690 @@ +{ config, pkgs, lib, ... }: +let + version = "23.11"; + myEmail = "CaptainJawZ@outlook.com"; + myName = "Danilo Reyes"; + cpuArchitecture = "alderlake"; + home-manager = builtins.fetchTarball + # "https://github.com/nix-community/home-manager/archive/master.tar.gz"; + "https://github.com/nix-community/home-manager/archive/release-${version}.tar.gz"; + unstable = import + (builtins.fetchTarball "https://github.com/nixos/nixpkgs/tarball/master") { + config = config.nixpkgs.config; + }; + jawzManageLibrary = pkgs.writeScriptBin + "manage-library" (builtins.readFile ../scripts/manage-library.sh); + jawzTasks = pkgs.writeScriptBin + "tasks" (builtins.readFile ../scripts/tasks.sh); + jawzSubs = pkgs.writeScriptBin + "sub-sync" (builtins.readFile ../scripts/sub-sync.sh); + jawzStream = pkgs.writeScriptBin + "stream-dl" (builtins.readFile ../scripts/stream-dl.sh); +in +{ # Remember to close this bracket at the end of the document + +imports = [ + ./fstab.nix + ./servers.nix + ./docker.nix + # ./mail.nix + # ./openldap.nix + # + (import "${home-manager}/nixos") +]; + +powerManagement.cpuFreqGovernor = lib.mkDefault "performance"; +networking = { + useDHCP = lib.mkDefault true; + enableIPv6 = false; + hostName = "miniserver"; + networkmanager.enable = true; + extraHosts = '' + 192.168.1.64 workstation + 192.168.1.69 server + ''; + firewall = let + open_firewall_ports = [ + 51413 # torrent sedding + 9091 # qbittorrent + 2049 # nfs + ]; + open_firewall_port_ranges = [ ]; + in + { + enable = true; + allowPing = true; + allowedTCPPorts = open_firewall_ports; + allowedUDPPorts = open_firewall_ports; + allowedTCPPortRanges = open_firewall_port_ranges; + allowedUDPPortRanges = open_firewall_port_ranges; + }; +}; + +time.timeZone = "America/Mexico_City"; +i18n = { + defaultLocale = "en_CA.UTF-8"; + extraLocaleSettings = { + LC_MONETARY = "es_MX.UTF-8"; + }; +}; +console = { + font = "Lat2-Terminus16"; + keyMap = "us"; + # useXkbConfig = true; # use xkbOptions in tty. +}; + +system = { + copySystemConfiguration = true; + stateVersion = "${version}"; +}; +nix = let featuresList = [ + "nixos-test" + "benchmark" + "big-parallel" + "kvm" + "gccarch-${cpuArchitecture}" + "gccarch-znver3" + ]; + in + { + gc = { + automatic = true; + dates = "weekly"; + }; + buildMachines = [ { + hostName = "workstation"; + system = "x86_64-linux"; + sshUser = "nixremote"; + maxJobs = 14; + speedFactor = 1; + supportedFeatures = featuresList; + } ]; + distributedBuilds = true; + settings = { + cores = 3; + auto-optimise-store = true; + trusted-users = [ "nixremote" ]; + system-features = featuresList; + substituters = [ + "https://nix-gaming.cachix.org" + "https://nixpkgs-python.cachix.org" + "https://devenv.cachix.org" + "https://cuda-maintainers.cachix.org" + ]; + trusted-public-keys = [ + "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" + "nixpkgs-python.cachix.org-1:hxjI7pFxTyuTHn2NkvWCrAUcNZLNS3ZAvfYNuYifcEU=" + "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" + "cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E=" + ]; + }; +}; + +security = { + acme = { + acceptTerms = true; + defaults.email = myEmail; + }; + rtkit.enable = true; + sudo = { + enable = true; + wheelNeedsPassword = false; + }; + pam.loginLimits = [{ + domain = "*"; + type = "soft"; + item = "nofile"; + value = "8192"; + }]; +}; + +nixpkgs = { + hostPlatform = lib.mkDefault "x86_64-linux"; + config = { + allowUnfree = true; + permittedInsecurePackages = [ + "openssl-1.1.1w" + ]; + }; + # localSystem = { + # gcc.arch = cpuArchitecture; + # gcc.tune = cpuArchitecture; + # system = "x86_64-linux"; + # }; +}; + +users = { + groups.nixremote = { + name = "nixremote"; + gid = 555; + }; + users.nixremote = { + isNormalUser = true; + createHome = true; + group = "nixremote"; + home = "/var/nixremote/"; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICiyTwryzw8CblPldplDpVUkXD9C1fXVgO8LeXdE5cuR root@workstation" + "" + ]; + }; +}; +users.users.jawz = { + isNormalUser = true; + extraGroups = [ "wheel" "networkmanager" "docker" + "scanner" "lp" "piracy" "kavita" + "render" "video" + ]; + initialPassword = "password"; + openssh = { + authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB5GaQM4N+yGAByibOFQOBVMV/6TjOfaGIP+NunMiK76 gpodeacero\cdreyes@100CDREYES" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMkpeIV9G26W2/e9PsjBx3sNwPGoicJ807ExRGh4KjhW jawz@server" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH2wtsaMvfEUm//2YnFHyrc16o+TOXXBfIGPJ9nL8RMp jawz@workstation" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBEblxSDhWPEo33crSjooeUg4W02ruENxHLmmBqCuIo jawz@galaxy" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN6HsajaTL+nTJtSIu00M5WJwgt/7fyU59gBr2R7tbnv root@server" + ]; + }; + +packages = (with pkgs; [ + +hunspell +hunspellDicts.it_IT +hunspellDicts.es_MX +hunspellDicts.en_CA + +symbola + +unstable.yt-dlp # downloads videos from most video websites +unstable.gallery-dl # similar to yt-dlp but for most image gallery websites + +fd # modern find, faster searches +fzf # fuzzy finder! super cool and useful +gdu # disk-space utility, somewhat useful +du-dust # rusty du +trash-cli # oop! didn't meant to delete that +eza # like ls but with colors +rmlint # probably my favourite app, amazing dupe finder that integrates well with BTRFS +smartmontools # check hard drie health + +jawzManageLibrary +jawzTasks +jawzSubs +jawzStream +(writeScriptBin "ffmpeg4discord" (builtins.readFile ../scripts/ffmpeg4discord.py)) +(writeScriptBin "ffmpreg" (builtins.readFile ../scripts/ffmpreg.sh)) +(writeScriptBin "split-dir" (builtins.readFile ../scripts/split-dir.sh)) +(writeScriptBin "pika-list" (builtins.readFile ../scripts/pika-list.sh)) +(writeScriptBin "run" (builtins.readFile ../scripts/run.sh)) +(writeScriptBin "find-dup-episodes" (builtins.readFile ../scripts/find-dup-episodes.sh)) + +tldr # man for retards + +# SH +bats # testing system, required by Exercism +bashdb # autocomplete +shellcheck # linting +shfmt # a shell parser and formatter + +# NIX +expect # keep color when nom'ing +nix-output-monitor # autistic nix builds +nixfmt # linting +cachix # why spend time compiling? + +# PYTHON. +(python3.withPackages (ps: with ps; [ + flake8 # wraper for pyflakes, pycodestyle and mccabe + isort # sort Python imports + nose # testing and running python scripts + pyflakes # checks source code for errors + pytest # framework for writing tests + speedtest-cli # check internet speed from the comand line + editorconfig # follow rules of contributin + black # Python code formatter + pylint # bug and style checker for python +])) # base language + +]) ++ (with pkgs.python3Packages; [ +(buildPythonApplication rec { + pname = "download"; + version = "1.5"; + src = ../scripts/download/.; + doCheck = false; + buildInputs = [ setuptools ]; + propagatedBuildInputs = + [ pyyaml types-pyyaml ]; +}) +(buildPythonApplication rec { + pname = "ffpb"; + version = "0.4.1"; + src = fetchPypi { + inherit pname version; + sha256 = "sha256-7eVqbLpMHS1sBw2vYS4cTtyVdnnknGtEI8190VlXflk="; + }; + doCheck = false; + buildInputs = [ setuptools ]; + propagatedBuildInputs = + [ tqdm ]; +}) +# (buildPythonApplication rec { +# pname = "qbit_manage"; +# version = "4.0.3"; +# src = fetchPypi { +# inherit pname version; +# sha256 = "sha256-7eVqbLpMHS1sBw2vYS4cTtyVdnnknGtEI8190VlXflk="; +# }; +# doCheck = true; +# buildInputs = [ setuptools ]; +# propagatedBuildInputs = +# [ gitpython requests retrying ruamel-yaml schedule unstable.qbittorrent-api ]; +# }) + +]) ++ (with pkgs.nodePackages; [ + # Language servers + dockerfile-language-server-nodejs + yaml-language-server + bash-language-server + vscode-json-languageserver + pyright + + markdownlint-cli # Linter + prettier # Linter + pnpm # Package manager + +]); }; # <--- end of package list + +home-manager = { + useUserPackages = true; + useGlobalPkgs = true; + users.jawz = { config, pkgs, ... }:{ + home.stateVersion = "${version}"; + +programs.bash = { + enable = true; + historyFile = "\${XDG_STATE_HOME}/bash/history"; + historyControl = [ "erasedups" "ignorespace" ]; + shellAliases = { + hh = "hstr"; + ls = "eza --icons --group-directories-first"; + edit = "emacsclient -t"; + comic = "download -u jawz -i \"$(cat $LC | fzf --multi --exact -i)\""; + gallery = "download -u jawz -i \"$(cat $LW | fzf --multi --exact -i)\""; + cp = "cp -i"; + mv = "mv -i"; + mkcd = "mkdir -pv \"$1\" && cd \"$1\" || exit"; + mkdir = "mkdir -p"; + rm = "trash"; + ".." = "cd .."; + "..." = "cd ../.."; + ".3" = "cd ../../.."; + ".4" = "cd ../../../.."; + ".5" = "cd ../../../../.."; + dl = "download -u jawz -i"; + e = "edit"; + c = "cat"; + f = "fzf --multi --exact -i"; + sc = "systemctl --user"; + jc = "journalctl --user -xefu"; + open-gallery = "cd /mnt/pool/scrapping/JawZ/gallery-dl && + xdg-open $(fd . ./ Husbands -tdirectory -d 1 | fzf -i)\""; + unique-extensions = "fd -tf | rev | cut -d. -f1 | rev | + tr '[:upper:]' '[:lower:]' | sort | + uniq --count | sort -rn"; + }; + enableVteIntegration = true; + initExtra = '' + $HOME/.local/bin/pokemon-colorscripts -r --no-title + # Lists + list_root="${config.xdg.configHome}"/jawz/lists/jawz + export LW=$list_root/watch.txt + export LI=$list_root/instant.txt + export LC=$list_root/comic.txt + export command_timeout=30 + + if command -v fzf-share >/dev/null; then + source "$(fzf-share)/key-bindings.bash" + source "$(fzf-share)/completion.bash" + fi + + nixos-reload () { + nixfmt /home/jawz/Development/NixOS/miniserver/*.nix + sudo unbuffer nixos-rebuild switch -I nixos-config=/home/jawz/Development/NixOS/miniserver/configuration.nix |& nom + } + ''; +}; + +xdg = { + enable = true; + userDirs = { + enable = true; + createDirectories = false; + desktop = "${config.home.homeDirectory}"; + documents = "${config.home.homeDirectory}/Documents"; + download = "${config.home.homeDirectory}/Downloads"; + music = "${config.home.homeDirectory}/Music"; + pictures = "${config.home.homeDirectory}/Pictures"; + templates = "${config.xdg.dataHome}/Templates"; + videos = "${config.home.homeDirectory}/Videos"; + }; + configFile = { + "wgetrc".source = ../dotfiles/wget/wgetrc; + "configstore/update-notifier-npm-check.json".source = ../dotfiles/npm/update-notifier-npm-check.json; + "npm/npmrc".source = ../dotfiles/npm/npmrc; + "gallery-dl/config.json".source = ../dotfiles/gallery-dl/config.json; + "htop/htoprc".source = ../dotfiles/htop/htoprc; + "python/pythonrc".source = ../dotfiles/pythonrc; + "unpackerr.conf".source = ../dotfiles/unpackerr.conf; + }; +}; + +programs = { + helix = { + enable = true; + }; + hstr.enable = true; + emacs.enable = true; + direnv = { + enable = true; + enableBashIntegration = true; + nix-direnv.enable = true; + }; + bat = { + enable = true; + config = { + pager = "less -FR"; + theme = "base16"; + }; + extraPackages = with pkgs.bat-extras; [ + batman # man pages + batpipe # piping + batgrep # ripgrep + batdiff # this is getting crazy! + batwatch # probably my next best friend + prettybat # trans your sourcecode! + ]; + }; + git = { + enable = true; + userName = "${myName}"; + userEmail = "${myEmail}"; + }; + htop = { + enable = true; + package = pkgs.htop-vim; + }; +}; + +services = { + lorri.enable = true; + emacs = { + enable = true; + defaultEditor = true; + package = pkgs.emacs; + startWithUserSession = "graphical"; + }; +}; + +}; }; + +environment = { + systemPackages = with pkgs; [ + wget + jellyfin-ffmpeg # coolest video converter! + mediainfo + dlib + fd + ripgrep + ]; + variables = rec { + # PATH + XDG_CACHE_HOME = "\${HOME}/.cache"; + XDG_CONFIG_HOME = "\${HOME}/.config"; + XDG_BIN_HOME = "\${HOME}/.local/bin"; + XDG_DATA_HOME = "\${HOME}/.local/share"; + XDG_STATE_HOME = "\${HOME}/.local/state"; + + # DEV PATH + CABAL_DIR = "${XDG_CACHE_HOME}/cabal"; + CARGO_HOME = "${XDG_DATA_HOME}/cargo"; + GEM_HOME = "${XDG_DATA_HOME}/ruby/gems"; + GEM_PATH = "${XDG_DATA_HOME}/ruby/gems"; + GEM_SPEC_CACHE = "${XDG_DATA_HOME}/ruby/specs"; + GOPATH = "${XDG_DATA_HOME}/go"; + NPM_CONFIG_USERCONFIG = "${XDG_CONFIG_HOME}/npm/npmrc"; + PNPM_HOME = "${XDG_DATA_HOME}/pnpm"; + PSQL_HISTORY="${XDG_DATA_HOME}/psql_history"; + REDISCLI_HISTFILE="${XDG_DATA_HOME}/redis/rediscli_history"; + WINEPREFIX="${XDG_DATA_HOME}/wine"; + PYTHONSTARTUP="${XDG_CONFIG_HOME}/python/pythonrc"; + STACK_ROOT="${XDG_DATA_HOME}/stack"; + + # OPTIONS + HISTFILE = "${XDG_STATE_HOME}/bash/history"; + LESSHISTFILE = "-"; + GHCUP_USE_XDG_DIRS = "true"; + RIPGREP_CONFIG_PATH = "${XDG_CONFIG_HOME}/ripgrep/ripgreprc"; + ELECTRUMDIR = "${XDG_DATA_HOME}/electrum"; + VISUAL = "emacsclient -ca emacs"; + WGETRC = "${XDG_CONFIG_HOME}/wgetrc"; + XCOMPOSECACHE = "${XDG_CACHE_HOME}/X11/xcompose"; + "_JAVA_OPTIONS" = "-Djava.util.prefs.userRoot=${XDG_CONFIG_HOME}/java"; + DOCKER_CONFIG="${XDG_CONFIG_HOME}/docker"; + + # NVIDIA + CUDA_CACHE_PATH = "${XDG_CACHE_HOME}/nv"; + + # Themes + # WEBKIT_DISABLE_COMPOSITING_MODE = "1"; + CALIBRE_USE_SYSTEM_THEME = "1"; + + PATH = [ + "\${HOME}/.local/bin" + "\${XDG_CONFIG_HOME}/emacs/bin" + "\${XDG_DATA_HOME}/npm/bin" + "\${XDG_DATA_HOME}/pnpm" + ]; + + # needed for tensorflow + # CUDA_PATH = "${pkgs.cudatoolkit}"; + # # LD_LIBRARY_PATH = "${pkgs.linuxPackages.nvidia_x11}/lib:${pkgs.ncurses5}/lib"; + # EXTRA_LDFLAGS = "-L/lib -L${pkgs.linuxPackages.nvidia_x11}/lib"; + # EXTRA_CCFLAGS = "-I/usr/include"; + }; +}; + +programs = { + starship.enable = true; + tmux.enable = true; + fzf.fuzzyCompletion = true; + neovim = { + enable = true; + vimAlias = true; + }; + gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; +}; + +services = { + # minidlna = { + # enable = true; + # openFirewall = true; + # settings = { + # inotify = "yes"; + # media_dir = [ + # "/mnt/pool/glue" + # ]; + # }; + # }; + avahi = { + enable = true; + nssmdns = true; + }; + fstrim.enable = true; + smartd.enable = true; + btrfs.autoScrub = { + enable = true; + fileSystems = [ + "/" + "/mnt/pool" + ]; + }; + openssh = { + enable = true; + openFirewall = true; + startWhenNeeded = true; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + }; + }; +}; + +systemd = { + packages = let + pkgs = import (builtins.fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/9957cd48326fe8dbd52fdc50dd2502307f188b0d.tar.gz"; + }) {}; + + myPkg = pkgs.qbittorrent-nox; +in [ myPkg ]; + services = { + "qbittorrent-nox@jawz" = { + enable = true; + overrideStrategy = "asDropin"; + wantedBy = [ "multi-user.target" ]; + }; + }; + timers = { + }; + user = { + services = { + "stream@" = { + description = "monitors a stream channel for online streams."; + restartIfChanged = true; + wantedBy = [ "default.target" ]; + path = [ + pkgs.nix + jawzStream + ]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = "${jawzStream}/bin/stream-dl %I"; + }; + }; + unpackerr = { + enable = true; + restartIfChanged = true; + description = "Run unpackerr"; + wantedBy = [ "default.target" ]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = "${pkgs.unpackerr}/bin/unpackerr -c /home/jawz/.config/unpackerr.conf"; + }; + }; + # manage-library = { + # enable = true; + # restartIfChanged = true; + # description = "Run the manage library bash script"; + # wantedBy = [ "default.target" ]; + # path = [ + # pkgs.bash + # pkgs.nix + # jawzManageLibrary + # ]; + # serviceConfig = { + # Restart = "on-failure"; + # RestartSec = 30; + # ExecStart = "${jawzManageLibrary}/bin/manage-library"; + # }; + # }; + # tasks = { + # restartIfChanged = true; + # description = "Run a tasks script which keeps a lot of things organized"; + # wantedBy = [ "default.target" ]; + # path = [ + # pkgs.bash + # pkgs.nix + # jawzTasks + # ]; + # serviceConfig = { + # Restart = "on-failure"; + # RestartSec = 30; + # ExecStart = "${jawzTasks}/bin/tasks"; + # }; + # }; + # qbit_manage = let qbit_dir = "/home/jawz/Development/Git/qbit_manage"; in { + # restartIfChanged = true; + # description = "Tidy up my torrents"; + # wantedBy = [ "default.target" ]; + # path = [ + # pkgs.python3 + # pkgs.pipenv + # ]; + # serviceConfig = { + # Restart = "on-failure"; + # RestartSec = 30; + # ExecStart = "${qbit_dir}/.venv/bin/python3 ${qbit_dir}/qbit_manage.py -r -c ${qbit_dir}/config.yml"; + # }; + # }; + }; + timers = let + streamTimer = { + enable = true; + description = "monitors a stream channel for online streams."; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = "5min"; + OnUnitActiveSec = "65min"; + RandomizedDelaySec = 30; + }; + }; + in { + "stream@johnneal911" = streamTimer // { }; + "stream@uk2011boy" = streamTimer // { }; + "stream@tomayto\\x20picarto" = streamTimer // { }; + "stream@retrohurricaneLIVE\\x20picarto" = streamTimer // { }; + # tasks = { + # enable = true; + # description = "Run a tasks script which keeps a lot of things organized"; + # wantedBy = [ "timers.target" ]; + # timerConfig = { + # OnCalendar = "*:0/10"; + # }; + # }; + # manage-library = { + # enable = true; + # description = "Run the manage library bash script"; + # wantedBy = [ "timers.target" ]; + # timerConfig = { + # OnCalendar = "00:30"; + # }; + # }; + # qbit_manage = { + # enable = true; + # description = "Tidy up my torrents"; + # wantedBy = [ "timers.target" ]; + # timerConfig = { + # OnCalendar = "*:0/10"; + # }; + # }; + }; + }; +}; + +fonts.fontconfig.enable = true; + +hardware = { + cpu.intel.updateMicrocode = lib.mkDefault true; + opengl = { + enable = true; + driSupport = true; + driSupport32Bit = true; + }; +}; + +} diff --git a/miniserver/configuration.org b/miniserver/configuration.org new file mode 100644 index 0000000..5ec2a9c --- /dev/null +++ b/miniserver/configuration.org @@ -0,0 +1,956 @@ +#+TITLE: JawZ NixOS server configuration +#+AUTHOR: Danilo Reyes +#+PROPERTY: header-args :tangle configuration.nix +#+auto_tangle: t + +* TODO [0/6] +- [ ] System configurations [0/8] + - [ ] fail2ban +- [ ] Misc [0/3] + - [ ] Figure out how to get rid of xterm + + +* DECLARATION +Here I will declare the dependencies and variables that I call multiple times +through the config file, such as the current version of NixOS, repositories and +even some scripts that I reuse on systemd configurations. + +- version: used by both NixOS and home-manager to dictate the state repository + from which to pull configurations, modules and packages. +- myEmail myName: used by git and acme +- cpuArchitecture: used by NixOS to optimize the compiled binaries to my current + CPU specifications. +- home-manager: the channel containing the packages matching the NixOS state + version, with a commented out to the unstable master. +- unstable: a sort of overlay that allows to prepend "unstable" to a package, + to pull from the unstable channel rather than precompiled binaries on a case + by case use. +- jawz*: scripts that will reuse multiple times through the config, such as + on systemd, and as such this feels like a safe way to compile them only once. + +#+begin_src nix +{ config, pkgs, lib, ... }: +let + version = "23.11"; + myEmail = "CaptainJawZ@outlook.com"; + myName = "Danilo Reyes"; + cpuArchitecture = "alderlake"; + home-manager = builtins.fetchTarball + # "https://github.com/nix-community/home-manager/archive/master.tar.gz"; + "https://github.com/nix-community/home-manager/archive/release-${version}.tar.gz"; + unstable = import + (builtins.fetchTarball "https://github.com/nixos/nixpkgs/tarball/master") { + config = config.nixpkgs.config; + }; + jawzManageLibrary = pkgs.writeScriptBin + "manage-library" (builtins.readFile ../scripts/manage-library.sh); + jawzTasks = pkgs.writeScriptBin + "tasks" (builtins.readFile ../scripts/tasks.sh); + jawzSubs = pkgs.writeScriptBin + "sub-sync" (builtins.readFile ../scripts/sub-sync.sh); + jawzStream = pkgs.writeScriptBin + "stream-dl" (builtins.readFile ../scripts/stream-dl.sh); +in +{ # Remember to close this bracket at the end of the document +#+end_src + +These are files and modules which get loaded onto the configuration file, in the +future I may segment this file into different modules once it becomes too +cluttered, for example, I may create a module for systemd units. + +- agenix: an encryption system which cleans up the nix-configuration files from +passwords and other secrets. + +#+begin_src nix +imports = [ + ./fstab.nix + ./servers.nix + ./docker.nix + # ./mail.nix + # ./openldap.nix + # + (import "${home-manager}/nixos") +]; +#+end_src + +* SYSTEM CONFIGURATION +** NETWORKING +Sets sensible networking options, such as setting up a hostname, and creating a +hosts file with the static IP and hostname of other devices on my network. + +Also open ports on the firewall for LAN connectivity, and well keeping commented +what each port does, I declared the firwewall ports with variables, because I +don't care to figure out whether I need TCP or UDP so let's open both, and +repetition is maddening. + +#+begin_src nix +powerManagement.cpuFreqGovernor = lib.mkDefault "performance"; +networking = { + useDHCP = lib.mkDefault true; + enableIPv6 = false; + hostName = "miniserver"; + networkmanager.enable = true; + extraHosts = '' + 192.168.1.64 workstation + 192.168.1.69 server + ''; + firewall = let + open_firewall_ports = [ + 51413 # torrent sedding + 9091 # qbittorrent + 2049 # nfs + ]; + open_firewall_port_ranges = [ ]; + in + { + enable = true; + allowPing = true; + allowedTCPPorts = open_firewall_ports; + allowedUDPPorts = open_firewall_ports; + allowedTCPPortRanges = open_firewall_port_ranges; + allowedUDPPortRanges = open_firewall_port_ranges; + }; +}; +#+end_src + +** TIMEZONE & LOCALE +For some reason, useXkbConfig throws an error when building the system, either +way it is an unnecessary setting as my keyboards are the default en_US, only +locale set to Canadian out because I prefer how it displays the date. +LC_MONETARY, it's also a personal preference. + +#+begin_src nix +time.timeZone = "America/Mexico_City"; +i18n = { + defaultLocale = "en_CA.UTF-8"; + extraLocaleSettings = { + LC_MONETARY = "es_MX.UTF-8"; + }; +}; +console = { + font = "Lat2-Terminus16"; + keyMap = "us"; + # useXkbConfig = true; # use xkbOptions in tty. +}; +#+end_src + +** SYSTEM/NIX CONFIGURATIONS +The first setting creates a copy the NixOS configuration file and link it from +the resulting system (/run/current-system/configuration.nix). This is useful in +case you accidentally delete configuration.nix. + +The version value determines the NixOS release from which the default settings for +stateful data, like file locations and database versions on your system. +It‘s perfectly fine and recommended to leave this value at the release version +of the first install of this system. + +Lastly I configure in here cachix repositories, which is a website that keeps a +cache of nixbuilds for easy quick deployments without having to compile +everything from scratch. + +- gc: automatically garbage-collects. +- auto-optimise-store: hard-links binaries whenever possible. +- system-features: features present on compiling time. + +#+begin_src nix +system = { + copySystemConfiguration = true; + stateVersion = "${version}"; +}; +nix = let featuresList = [ + "nixos-test" + "benchmark" + "big-parallel" + "kvm" + "gccarch-${cpuArchitecture}" + "gccarch-znver3" + ]; + in + { + gc = { + automatic = true; + dates = "weekly"; + }; + buildMachines = [ { + hostName = "workstation"; + system = "x86_64-linux"; + sshUser = "nixremote"; + maxJobs = 14; + speedFactor = 1; + supportedFeatures = featuresList; + } ]; + distributedBuilds = true; + settings = { + cores = 3; + auto-optimise-store = true; + trusted-users = [ "nixremote" ]; + system-features = featuresList; + substituters = [ + "https://nix-gaming.cachix.org" + "https://nixpkgs-python.cachix.org" + "https://devenv.cachix.org" + "https://cuda-maintainers.cachix.org" + ]; + trusted-public-keys = [ + "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" + "nixpkgs-python.cachix.org-1:hxjI7pFxTyuTHn2NkvWCrAUcNZLNS3ZAvfYNuYifcEU=" + "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" + "cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E=" + ]; + }; +}; +#+end_src + +* SECURITY +Disabled password in sudo for commodity, but this is obviously not recommended, +regarding rkit, that setting enables pipewire to run with real-time +capabilities. And lastly, the acme settings are for signing certificates. + +The pam limits exists so NixOS can compile the entire system without running +into "Too many files open" errors. + +#+begin_src nix +security = { + acme = { + acceptTerms = true; + defaults.email = myEmail; + }; + rtkit.enable = true; + sudo = { + enable = true; + wheelNeedsPassword = false; + }; + pam.loginLimits = [{ + domain = "*"; + type = "soft"; + item = "nofile"; + value = "8192"; + }]; +}; +#+end_src + +* NIXPKGS SETTINGS +Allow non-free, sadly is a requirement for some of my drivers, besides that, +here is a good place to declare some package overrides as well as permit unsafe +packages. + +localSystem allows me to compile the entire operating system optimized to my CPU +architecture and other build flags. + +=note= if using gcc.arch flags, comment out hostPlatform and viceversa. + +#+begin_src nix +nixpkgs = { + hostPlatform = lib.mkDefault "x86_64-linux"; + config = { + allowUnfree = true; + permittedInsecurePackages = [ + "openssl-1.1.1w" + ]; + }; + # localSystem = { + # gcc.arch = cpuArchitecture; + # gcc.tune = cpuArchitecture; + # system = "x86_64-linux"; + # }; +}; +#+end_src + +* NORMAL USERS +Being part of the "wheel" group, means that the user has root privileges. The +piracy.gid is so I have read/write access permissions on all the hard drives +split among my multiple systems, the rest of the groups are self explanatory. + +- nixremote: is a low-privilege user set exclusively with the intention to be a + proxy to build the nix-store remotely. + +#+begin_src nix +users = { + groups.nixremote = { + name = "nixremote"; + gid = 555; + }; + users.nixremote = { + isNormalUser = true; + createHome = true; + group = "nixremote"; + home = "/var/nixremote/"; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICiyTwryzw8CblPldplDpVUkXD9C1fXVgO8LeXdE5cuR root@workstation" + "" + ]; + }; +}; +users.users.jawz = { + isNormalUser = true; + extraGroups = [ "wheel" "networkmanager" "docker" + "scanner" "lp" "piracy" "kavita" + "render" "video" + ]; + initialPassword = "password"; + openssh = { + authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB5GaQM4N+yGAByibOFQOBVMV/6TjOfaGIP+NunMiK76 gpodeacero\cdreyes@100CDREYES" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMkpeIV9G26W2/e9PsjBx3sNwPGoicJ807ExRGh4KjhW jawz@server" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH2wtsaMvfEUm//2YnFHyrc16o+TOXXBfIGPJ9nL8RMp jawz@workstation" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBEblxSDhWPEo33crSjooeUg4W02ruENxHLmmBqCuIo jawz@galaxy" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN6HsajaTL+nTJtSIu00M5WJwgt/7fyU59gBr2R7tbnv root@server" + ]; + }; +#+end_src + +This section of the document categorizes and organizes all he packages that I +want installed, attempting to group them as dependencies of others when +necessary. + +* USER PACKAGES +This section of the document categorizes and organizes all he packages that I +want installed, attempting to group them as dependencies of others when +necessary. + +Begin the block to install user packages. + +#+begin_src nix +packages = (with pkgs; [ +#+end_src + +cli and tui packages, which on their own right are as or more powerful than the +packages on the previous section. + +** HUNSPELL +These dictionaries work with Firefox, Doom Emacs and LibreOffice. + +#+begin_src nix +hunspell +hunspellDicts.it_IT +hunspellDicts.es_MX +hunspellDicts.en_CA +#+end_src + +** CUSTOMIZATION PACKAGES +Themes and other customization, making my DE look the way I want is one of the +main draws of Linux for me. + +#+begin_src nix +symbola +#+end_src + +** COMMAND-LINE PACKAGES + +#+begin_src nix +unstable.yt-dlp # downloads videos from most video websites +unstable.gallery-dl # similar to yt-dlp but for most image gallery websites + +fd # modern find, faster searches +fzf # fuzzy finder! super cool and useful +gdu # disk-space utility, somewhat useful +du-dust # rusty du +trash-cli # oop! didn't meant to delete that +eza # like ls but with colors +rmlint # probably my favourite app, amazing dupe finder that integrates well with BTRFS +smartmontools # check hard drie health +#+end_src + +** MY SCRIPTS +Here I compile my own scripts into binaries + +#+begin_src nix +jawzManageLibrary +jawzTasks +jawzSubs +jawzStream +(writeScriptBin "ffmpeg4discord" (builtins.readFile ../scripts/ffmpeg4discord.py)) +(writeScriptBin "ffmpreg" (builtins.readFile ../scripts/ffmpreg.sh)) +(writeScriptBin "split-dir" (builtins.readFile ../scripts/split-dir.sh)) +(writeScriptBin "pika-list" (builtins.readFile ../scripts/pika-list.sh)) +(writeScriptBin "run" (builtins.readFile ../scripts/run.sh)) +(writeScriptBin "find-dup-episodes" (builtins.readFile ../scripts/find-dup-episodes.sh)) +#+end_src + +** DEVELOPMENT PACKAGES +Assorted development packages and libraries, categorized by languages. + +#+begin_src nix +tldr # man for retards + +# SH +bats # testing system, required by Exercism +bashdb # autocomplete +shellcheck # linting +shfmt # a shell parser and formatter + +# NIX +expect # keep color when nom'ing +nix-output-monitor # autistic nix builds +nixfmt # linting +cachix # why spend time compiling? + +# PYTHON. +(python3.withPackages (ps: with ps; [ + flake8 # wraper for pyflakes, pycodestyle and mccabe + isort # sort Python imports + nose # testing and running python scripts + pyflakes # checks source code for errors + pytest # framework for writing tests + speedtest-cli # check internet speed from the comand line + editorconfig # follow rules of contributin + black # Python code formatter + pylint # bug and style checker for python +])) # base language +#+end_src + +** CUSTOM PYTHON SCRIPTS +Libraries & apps not found on the nix-store and scripts made by me. + +#+begin_src nix +]) ++ (with pkgs.python3Packages; [ +(buildPythonApplication rec { + pname = "download"; + version = "1.5"; + src = ../scripts/download/.; + doCheck = false; + buildInputs = [ setuptools ]; + propagatedBuildInputs = + [ pyyaml types-pyyaml ]; +}) +(buildPythonApplication rec { + pname = "ffpb"; + version = "0.4.1"; + src = fetchPypi { + inherit pname version; + sha256 = "sha256-7eVqbLpMHS1sBw2vYS4cTtyVdnnknGtEI8190VlXflk="; + }; + doCheck = false; + buildInputs = [ setuptools ]; + propagatedBuildInputs = + [ tqdm ]; +}) +# (buildPythonApplication rec { +# pname = "qbit_manage"; +# version = "4.0.3"; +# src = fetchPypi { +# inherit pname version; +# sha256 = "sha256-7eVqbLpMHS1sBw2vYS4cTtyVdnnknGtEI8190VlXflk="; +# }; +# doCheck = true; +# buildInputs = [ setuptools ]; +# propagatedBuildInputs = +# [ gitpython requests retrying ruamel-yaml schedule unstable.qbittorrent-api ]; +# }) +#+end_src + +** NODEJS PACKAGES +Language servers and linters. + +#+begin_src nix +]) ++ (with pkgs.nodePackages; [ + # Language servers + dockerfile-language-server-nodejs + yaml-language-server + bash-language-server + vscode-json-languageserver + pyright + + markdownlint-cli # Linter + prettier # Linter + pnpm # Package manager +#+end_src + +** CLOSING USER PACKAGES + +#+begin_src nix +]); }; # <--- end of package list +#+end_src + +* HOME-MANAGER +** HOME-MANAGER SETTINGS +These make it so packages install to '/etc' rather than the user home directory, +also allow for upgrades when rebuilding the system. + +#+begin_src nix +home-manager = { + useUserPackages = true; + useGlobalPkgs = true; + users.jawz = { config, pkgs, ... }:{ + home.stateVersion = "${version}"; +#+end_src + +** DOTFILES +I opted out of using home-manager to declare my package environment, and instead +I use it exclusively for setting up my dotfiles. + +*** BASH +Declares my .bashrc file, and sets up some environment and functions. + +#+begin_src nix +programs.bash = { + enable = true; + historyFile = "\${XDG_STATE_HOME}/bash/history"; + historyControl = [ "erasedups" "ignorespace" ]; + shellAliases = { + hh = "hstr"; + ls = "eza --icons --group-directories-first"; + edit = "emacsclient -t"; + comic = "download -u jawz -i \"$(cat $LC | fzf --multi --exact -i)\""; + gallery = "download -u jawz -i \"$(cat $LW | fzf --multi --exact -i)\""; + cp = "cp -i"; + mv = "mv -i"; + mkcd = "mkdir -pv \"$1\" && cd \"$1\" || exit"; + mkdir = "mkdir -p"; + rm = "trash"; + ".." = "cd .."; + "..." = "cd ../.."; + ".3" = "cd ../../.."; + ".4" = "cd ../../../.."; + ".5" = "cd ../../../../.."; + dl = "download -u jawz -i"; + e = "edit"; + c = "cat"; + f = "fzf --multi --exact -i"; + sc = "systemctl --user"; + jc = "journalctl --user -xefu"; + open-gallery = "cd /mnt/pool/scrapping/JawZ/gallery-dl && + xdg-open $(fd . ./ Husbands -tdirectory -d 1 | fzf -i)\""; + unique-extensions = "fd -tf | rev | cut -d. -f1 | rev | + tr '[:upper:]' '[:lower:]' | sort | + uniq --count | sort -rn"; + }; + enableVteIntegration = true; + initExtra = '' + $HOME/.local/bin/pokemon-colorscripts -r --no-title + # Lists + list_root="${config.xdg.configHome}"/jawz/lists/jawz + export LW=$list_root/watch.txt + export LI=$list_root/instant.txt + export LC=$list_root/comic.txt + export command_timeout=30 + + if command -v fzf-share >/dev/null; then + source "$(fzf-share)/key-bindings.bash" + source "$(fzf-share)/completion.bash" + fi + + nixos-reload () { + nixfmt /home/jawz/Development/NixOS/miniserver/*.nix + sudo unbuffer nixos-rebuild switch -I nixos-config=/home/jawz/Development/NixOS/miniserver/configuration.nix |& nom + } + ''; +}; +#+end_src + +*** XDG +Configurations for XDG directories, as well as installing dotfiles from the +sub-directory on this repository. + +#+begin_src nix +xdg = { + enable = true; + userDirs = { + enable = true; + createDirectories = false; + desktop = "${config.home.homeDirectory}"; + documents = "${config.home.homeDirectory}/Documents"; + download = "${config.home.homeDirectory}/Downloads"; + music = "${config.home.homeDirectory}/Music"; + pictures = "${config.home.homeDirectory}/Pictures"; + templates = "${config.xdg.dataHome}/Templates"; + videos = "${config.home.homeDirectory}/Videos"; + }; + configFile = { + "wgetrc".source = ../dotfiles/wget/wgetrc; + "configstore/update-notifier-npm-check.json".source = ../dotfiles/npm/update-notifier-npm-check.json; + "npm/npmrc".source = ../dotfiles/npm/npmrc; + "gallery-dl/config.json".source = ../dotfiles/gallery-dl/config.json; + "htop/htoprc".source = ../dotfiles/htop/htoprc; + "python/pythonrc".source = ../dotfiles/pythonrc; + "unpackerr.conf".source = ../dotfiles/unpackerr.conf; + }; +}; +#+end_src + +** HOME-MANAGER PROGRAMS +Program declarations that are exclusive to home-manager, declaring packages this +way allows for extra configuration and integration beyond installing the +packages on the user environment, it's the only exception I make to installing +packages through home-manager. + +#+begin_src nix +programs = { + helix = { + enable = true; + }; + hstr.enable = true; + emacs.enable = true; + direnv = { + enable = true; + enableBashIntegration = true; + nix-direnv.enable = true; + }; + bat = { + enable = true; + config = { + pager = "less -FR"; + theme = "base16"; + }; + extraPackages = with pkgs.bat-extras; [ + batman # man pages + batpipe # piping + batgrep # ripgrep + batdiff # this is getting crazy! + batwatch # probably my next best friend + prettybat # trans your sourcecode! + ]; + }; + git = { + enable = true; + userName = "${myName}"; + userEmail = "${myEmail}"; + }; + htop = { + enable = true; + package = pkgs.htop-vim; + }; +}; +#+end_src + +** HOME-MANAGER USER-SERVICES +Lorri helps optimize emacs compilations, and the declaring emacs as a service +through home-manager fixes the bug where emacs loads so quickly that can not +connect to a graphic environment unless restarting the systemd service. + +#+begin_src nix +services = { + lorri.enable = true; + emacs = { + enable = true; + defaultEditor = true; + package = pkgs.emacs; + startWithUserSession = "graphical"; + }; +}; +#+end_src + +** CLOSING HOME-MANAGER + +#+begin_src nix +}; }; +#+end_src + +* ENVIRONMENT +These are a MUST to ensure the optimal function of nix, without these, recovery +may be challenging. + +The environment.etc block allows for bluetooth devices to control volume, pause, +and other things through the headset controls. + +Declare environment variables whose function is mostly to clear-up the $HOME +directory from as much bloat as possible, as well as some minor graphical tweaks +some applications use. + +#+begin_src nix +environment = { + systemPackages = with pkgs; [ + wget + jellyfin-ffmpeg # coolest video converter! + mediainfo + dlib + fd + ripgrep + ]; + variables = rec { + # PATH + XDG_CACHE_HOME = "\${HOME}/.cache"; + XDG_CONFIG_HOME = "\${HOME}/.config"; + XDG_BIN_HOME = "\${HOME}/.local/bin"; + XDG_DATA_HOME = "\${HOME}/.local/share"; + XDG_STATE_HOME = "\${HOME}/.local/state"; + + # DEV PATH + CABAL_DIR = "${XDG_CACHE_HOME}/cabal"; + CARGO_HOME = "${XDG_DATA_HOME}/cargo"; + GEM_HOME = "${XDG_DATA_HOME}/ruby/gems"; + GEM_PATH = "${XDG_DATA_HOME}/ruby/gems"; + GEM_SPEC_CACHE = "${XDG_DATA_HOME}/ruby/specs"; + GOPATH = "${XDG_DATA_HOME}/go"; + NPM_CONFIG_USERCONFIG = "${XDG_CONFIG_HOME}/npm/npmrc"; + PNPM_HOME = "${XDG_DATA_HOME}/pnpm"; + PSQL_HISTORY="${XDG_DATA_HOME}/psql_history"; + REDISCLI_HISTFILE="${XDG_DATA_HOME}/redis/rediscli_history"; + WINEPREFIX="${XDG_DATA_HOME}/wine"; + PYTHONSTARTUP="${XDG_CONFIG_HOME}/python/pythonrc"; + STACK_ROOT="${XDG_DATA_HOME}/stack"; + + # OPTIONS + HISTFILE = "${XDG_STATE_HOME}/bash/history"; + LESSHISTFILE = "-"; + GHCUP_USE_XDG_DIRS = "true"; + RIPGREP_CONFIG_PATH = "${XDG_CONFIG_HOME}/ripgrep/ripgreprc"; + ELECTRUMDIR = "${XDG_DATA_HOME}/electrum"; + VISUAL = "emacsclient -ca emacs"; + WGETRC = "${XDG_CONFIG_HOME}/wgetrc"; + XCOMPOSECACHE = "${XDG_CACHE_HOME}/X11/xcompose"; + "_JAVA_OPTIONS" = "-Djava.util.prefs.userRoot=${XDG_CONFIG_HOME}/java"; + DOCKER_CONFIG="${XDG_CONFIG_HOME}/docker"; + + # NVIDIA + CUDA_CACHE_PATH = "${XDG_CACHE_HOME}/nv"; + + # Themes + # WEBKIT_DISABLE_COMPOSITING_MODE = "1"; + CALIBRE_USE_SYSTEM_THEME = "1"; + + PATH = [ + "\${HOME}/.local/bin" + "\${XDG_CONFIG_HOME}/emacs/bin" + "\${XDG_DATA_HOME}/npm/bin" + "\${XDG_DATA_HOME}/pnpm" + ]; + + # needed for tensorflow + # CUDA_PATH = "${pkgs.cudatoolkit}"; + # # LD_LIBRARY_PATH = "${pkgs.linuxPackages.nvidia_x11}/lib:${pkgs.ncurses5}/lib"; + # EXTRA_LDFLAGS = "-L/lib -L${pkgs.linuxPackages.nvidia_x11}/lib"; + # EXTRA_CCFLAGS = "-I/usr/include"; + }; +}; +#+end_src + +* PROGRAMS +Some programs get enabled and installed through here, as well as the activation +of some services. + +#+begin_src nix +programs = { + starship.enable = true; + tmux.enable = true; + fzf.fuzzyCompletion = true; + neovim = { + enable = true; + vimAlias = true; + }; + gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; +}; +#+end_src + +* SERVICES +Miscellaneous services, managed by systemd. + +- minidlna: allows me to watch my media on my TV. +- avahi: allows to discover/connect to devices through their hostname on the + same network. +- fstrim/btrfs: file-system services. + +#+begin_src nix +services = { + # minidlna = { + # enable = true; + # openFirewall = true; + # settings = { + # inotify = "yes"; + # media_dir = [ + # "/mnt/pool/glue" + # ]; + # }; + # }; + avahi = { + enable = true; + nssmdns = true; + }; + fstrim.enable = true; + smartd.enable = true; + btrfs.autoScrub = { + enable = true; + fileSystems = [ + "/" + "/mnt/pool" + ]; + }; + openssh = { + enable = true; + openFirewall = true; + startWhenNeeded = true; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + }; + }; +}; +#+end_src + +* SYSTEMD +Home-manager, is not as flushed out when it comes to creating systemd units, so +the best way to define them for now, is using nix. + +#+begin_src nix +systemd = { + packages = let + pkgs = import (builtins.fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/9957cd48326fe8dbd52fdc50dd2502307f188b0d.tar.gz"; + }) {}; + + myPkg = pkgs.qbittorrent-nox; +in [ myPkg ]; + services = { + "qbittorrent-nox@jawz" = { + enable = true; + overrideStrategy = "asDropin"; + wantedBy = [ "multi-user.target" ]; + }; + }; + timers = { + }; + user = { + services = { + "stream@" = { + description = "monitors a stream channel for online streams."; + restartIfChanged = true; + wantedBy = [ "default.target" ]; + path = [ + pkgs.nix + jawzStream + ]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = "${jawzStream}/bin/stream-dl %I"; + }; + }; + unpackerr = { + enable = true; + restartIfChanged = true; + description = "Run unpackerr"; + wantedBy = [ "default.target" ]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = "${pkgs.unpackerr}/bin/unpackerr -c /home/jawz/.config/unpackerr.conf"; + }; + }; + # manage-library = { + # enable = true; + # restartIfChanged = true; + # description = "Run the manage library bash script"; + # wantedBy = [ "default.target" ]; + # path = [ + # pkgs.bash + # pkgs.nix + # jawzManageLibrary + # ]; + # serviceConfig = { + # Restart = "on-failure"; + # RestartSec = 30; + # ExecStart = "${jawzManageLibrary}/bin/manage-library"; + # }; + # }; + # tasks = { + # restartIfChanged = true; + # description = "Run a tasks script which keeps a lot of things organized"; + # wantedBy = [ "default.target" ]; + # path = [ + # pkgs.bash + # pkgs.nix + # jawzTasks + # ]; + # serviceConfig = { + # Restart = "on-failure"; + # RestartSec = 30; + # ExecStart = "${jawzTasks}/bin/tasks"; + # }; + # }; + # qbit_manage = let qbit_dir = "/home/jawz/Development/Git/qbit_manage"; in { + # restartIfChanged = true; + # description = "Tidy up my torrents"; + # wantedBy = [ "default.target" ]; + # path = [ + # pkgs.python3 + # pkgs.pipenv + # ]; + # serviceConfig = { + # Restart = "on-failure"; + # RestartSec = 30; + # ExecStart = "${qbit_dir}/.venv/bin/python3 ${qbit_dir}/qbit_manage.py -r -c ${qbit_dir}/config.yml"; + # }; + # }; + }; + timers = let + streamTimer = { + enable = true; + description = "monitors a stream channel for online streams."; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = "5min"; + OnUnitActiveSec = "65min"; + RandomizedDelaySec = 30; + }; + }; + in { + "stream@johnneal911" = streamTimer // { }; + "stream@uk2011boy" = streamTimer // { }; + "stream@tomayto\\x20picarto" = streamTimer // { }; + "stream@retrohurricaneLIVE\\x20picarto" = streamTimer // { }; + # tasks = { + # enable = true; + # description = "Run a tasks script which keeps a lot of things organized"; + # wantedBy = [ "timers.target" ]; + # timerConfig = { + # OnCalendar = "*:0/10"; + # }; + # }; + # manage-library = { + # enable = true; + # description = "Run the manage library bash script"; + # wantedBy = [ "timers.target" ]; + # timerConfig = { + # OnCalendar = "00:30"; + # }; + # }; + # qbit_manage = { + # enable = true; + # description = "Tidy up my torrents"; + # wantedBy = [ "timers.target" ]; + # timerConfig = { + # OnCalendar = "*:0/10"; + # }; + # }; + }; + }; +}; +#+end_src + +* FONTCONFIG +If enabled, a Fontconfig configuration file will point to a set of default +fonts. If you don not care about running X11 applications or any other program +that uses Fontconfig, you can turn this option off and prevent a dependency on +all those fonts. +=tip= once that Wayland is ready for deployment, I probably can remove this +setting. + +#+begin_src nix +fonts.fontconfig.enable = true; +#+end_src + +* HARDWARE +Computer-specific hardware settings. The power management settings default to +"performance". + +- nvidia: GPU drivers. +- cpu.intel: microcode patches. + +#+begin_src nix +hardware = { + cpu.intel.updateMicrocode = lib.mkDefault true; + opengl = { + enable = true; + driSupport = true; + driSupport32Bit = true; + }; +}; +#+end_src + +* CLOSE SYSTEM +#+begin_src nix +} +#+end_src diff --git a/miniserver/docker.nix b/miniserver/docker.nix new file mode 100644 index 0000000..af734e7 --- /dev/null +++ b/miniserver/docker.nix @@ -0,0 +1,228 @@ +{ config, lib, pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ docker-compose ]; + virtualisation = let postgresSocket = "/run/postgresql"; + in { + docker = { + enable = true; + enableNvidia = true; + # dockerCompat = true; + # defaultNetwork.settings.dns_enabled = true; + autoPrune = { + enable = true; + flags = [ "--all" ]; + dates = "weekly"; + }; + }; + oci-containers = { + backend = "docker"; + containers = { + collabora = { + autoStart = true; + image = "collabora/code"; + imageFile = pkgs.dockerTools.pullImage { + imageName = "collabora/code"; + imageDigest = + "sha256:aab41379baf5652832e9237fcc06a768096a5a7fccc66cf8bd4fdb06d2cbba7f"; + sha256 = "sha256-M66lynhzaOEFnE15Sy1N6lBbGDxwNw6ap+IUJAvoCLs="; + }; + ports = [ "9980:9980" ]; + environment = { + TZ = "America/Mexico_City"; + domain = "cloud.servidos.lat"; + aliasgroup1 = "cloud.servidos.lat:443"; + aliasgroup2 = "cloud.rotehaare.art:443"; + dictionaries = "en_CA en_US es_MX es_ES fr_FR it pt_BR ru"; + extra_params = '' + --o:ssl.enable=false + --o:ssl.termination=true + ''; + }; + extraOptions = [ "--cap-add" "MKNOD" ]; + }; + # metube = { + # image = "ghcr.io/alexta69/metube"; + # ports = [ "8881:8081" ]; + # volumes = [ + # "/var/lib/docker-configs/metube:/downloads" + # "/home/jawz/.local/share/cookies.txt:/cookies.txt" + # ]; + # environment = { + # TZ = "America/Mexico_City"; + # YTDL_OPTIONS = ''{"cookiefile":"/cookies.txt"}''; + # }; + # }; + vocechat = { + image = "privoce/vocechat-server:latest"; + ports = [ "3001:3000" ]; + volumes = + [ "/var/lib/docker-configs/vocechat:/home/vocechat-server/data" ]; + environment = { TZ = "America/Mexico_City"; }; + }; + ryot = { + image = "ghcr.io/ignisda/ryot:latest"; + ports = [ "8765:8000" ]; + environment = { + TZ = "America/Mexico_City"; + DATABASE_URL = "postgres:///ryot?host=${postgresSocket}"; + SERVER_INSECURE_COOKIE = "true"; + VIDEO_GAMES_TWITCH_CLIENT_ID = "tfu0hw0zbdbu4lco4h72nqkb8krxp9"; + VIDEO_GAMES_TWITCH_CLIENT_SECRET = "582ecfb01ihv6wnt8zbc9pf3hs9p54"; + }; + volumes = [ "${postgresSocket}:${postgresSocket}" ]; + labels = { + "flame.type" = "application"; + "flame.name" = "Ryot"; + "flame.url" = "tracker.servidos.lat"; + "flame.icon" = "radar"; + }; + }; + multi-scrobbler = { + image = "foxxmd/multi-scrobbler"; + ports = [ "9078:9078" ]; + environment = { + TZ = "America/Mexico_City"; + PUID = "1000"; + PGID = "100"; + BASE_URL = "https://scrobble.servidos.lat"; + # JELLYFIN_USER = "jawz"; + # JELLYFIN_SERVER = "DaniloFlix"; + DEEZER_CLIENT_ID = "657431"; + DEEZER_CLIENT_SECRET = "cb2ad03682dd5a55dfef857388ef181e"; + DEEZER_REDIRECT_URI = "http://192.168.1.69:9078/deezer/callback"; + MALOJA_URL = "https://maloja.servidos.lat"; + MALOJA_API_KEY = + "LsnY2Ed484JlzUmF6EwhpGJ0gUCjJ2G5s1oJTwALJN8w1N3K6eXpfjBQp3raNPLA"; + WS_ENABLE = "true"; + }; + volumes = [ "/var/lib/docker-configs/multi-scrobbler:/config" ]; + labels = { + "flame.type" = "application"; + "flame.name" = "Multi-scrobbler"; + "flame.url" = "scrobble.servidos.lat"; + "flame.icon" = "broadcast"; + }; + }; + maloja = { + image = "krateng/maloja"; + ports = [ "42010:42010" ]; + environment = { + TZ = "America/Mexico_City"; + MALOJA_TIMEZONE = "-6"; + PUID = "1000"; + PGID = "100"; + MALOJA_DATA_DIRECTORY = "/mljdata"; + MALOJA_SKIP_SETUP = "true"; + MALOJA_FORCE_PASSWORD = "chichis"; + }; + volumes = [ "/var/lib/docker-configs/maloja:/mljdata" ]; + labels = { + "flame.type" = "application"; + "flame.name" = "Maloja"; + "flame.url" = "maloja.servidos.lat"; + "flame.icon" = "bookmark-music"; + }; + }; + # flaresolverr = { + # autoStart = true; + # image = "ghcr.io/flaresolverr/flaresolverr:latest"; + # ports = [ "8191:8191" ]; + # }; + flame = { + autoStart = true; + image = "pawelmalak/flame"; + ports = [ "5005:5005" ]; + volumes = [ + "/var/lib/docker-configs/flame:/app/data" + "/var/run/docker.sock:/var/run/docker.sock" + ]; + environment = { + TZ = "America/Mexico_City"; + PUID = "1000"; + PGID = "100"; + PASSWORD = "RkawpqMc8lR56QyU7JSfiLhG"; + }; + }; + flame-nsfw = { + autoStart = true; + image = "pawelmalak/flame"; + ports = [ "5007:5005" ]; + volumes = [ "/var/lib/docker-configs/flame-nsfw:/app/data" ]; + environment = { + TZ = "America/Mexico_City"; + PUID = "1000"; + PGID = "100"; + PASSWORD = "RkawpqMc8lR56QyU7JSfiLhG"; + }; + }; + # lidarr = { + # autoStart = true; + # image = "lscr.io/linuxserver/lidarr:latest"; + # ports = [ "8686:8686" ]; + # environment = { + # TZ = "America/Mexico_City"; + # PUID = "1000"; + # PGID = "100"; + # }; + # volumes = [ + # "/mnt/pool/multimedia:/data" + # "/mnt/pool/multimedia/media/Music:/music" + # "/mnt/pool/multimedia/media/MusicVideos:/music-videos" + # "/var/lib/docker-configs/lidarr/files:/config" + # "/var/lib/docker-configs/lidarr/custom-services.d:/custom-services.d" + # "/var/lib/docker-configs/lidarr/custom-cont-init.d:/custom-cont-init.d" + # ]; + # labels = { + # "flame.type" = "application"; + # "flame.name" = "Lidarr"; + # "flame.url" = "music.servidos.lat"; + # "flame.icon" = "music"; + # }; + # }; + mealie = { + autoStart = true; + image = "ghcr.io/mealie-recipes/mealie:v1.4.0"; + ports = [ "9925:9000" ]; + volumes = [ "/var/lib/docker-configs/mealie:/app/data/" ]; + environment = { + TZ = "America/Mexico_City"; + ALLOW_SIGNUP = "true"; + PUID = "1000"; + PGID = "100"; + MAX_WORKERS = "1"; + WEB_CONCURRENCY = "1"; + BASE_URL = "https://mealie.servidos.lat"; + SMTP_HOST = "smtp.gmail.com"; + SMTP_PORT = "587"; + SMTP_FROM_EMAIL = "stunner6399@gmail.com"; + SMTP_USER = "stunner6399@gmail.com"; + SMTP_PASSWORD = "ywofhisexfawslob"; + }; + extraOptions = [ + "--memory=1g" # VA-API (omit for NVENC) + ]; + labels = { + "flame.type" = "application"; + "flame.name" = "Mealie"; + "flame.url" = "mealie.servidos.lat"; + "flame.icon" = "fridge"; + }; + }; + go-vod = { + autoStart = true; + image = "radialapps/go-vod"; + environment = { + TZ = "America/Mexico_City"; + NEXTCLOUD_HOST = "https://${config.services.nextcloud.hostName}"; + NVIDIA_VISIBLE_DEVICES = "all"; + }; + volumes = [ "ncdata:/var/www/html:ro" ]; + extraOptions = [ + "--device=/dev/dri" # VA-API (omit for NVENC) + ]; + }; + }; + }; + }; +} diff --git a/miniserver/dotfiles/gallery-dl/config.json b/miniserver/dotfiles/gallery-dl/config.json new file mode 100644 index 0000000..a9ce78b --- /dev/null +++ b/miniserver/dotfiles/gallery-dl/config.json @@ -0,0 +1,228 @@ +{ + "extractor": { + "skip": "abort:5", + "cookies": ["firefox", "yw8fhvh4.default-release", "gnomekeyring"], + "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36", + "retries": 10, + "sleep-request": 0, + "directlink": { + "directory": [], + "filename": "{filename}.{extension}" + }, + "twitter": { + "skip": "abort:1", + "directory": ["{user[name]}"], + "retweets": false, + "videos": true, + "logout": true + }, + "flickr": { + "directory": ["{category}", "{owner[username]}"], + "size-max": "Original", + "access-token": "72157720849409732-e83af94a8ca145aa", + "access-token-secret": "0c7e86529694756a" + }, + "pinterest": { + "directory": ["{board[owner][username]}", "{board[name]}"] + }, + "wikifeet": { + "page-reverse": true, + "directory": ["{category}", "{celebrity}"] + }, + "instagram": { + "sleep-request": "25-45", + "sleep": "25-45", + "cookies": "$HOME/cookies.txt", + "directory": ["{username}"], + "parent-directory": true, + "highlights": { + "reverse": "true", + "directory": ["{username}"] + }, + "stories": { + "reverse": "true", + "directory": ["{username}"] + }, + "tagged": { + "directory": ["{tagged_username}", "tagged"] + } + }, + "kemonoparty": { + "directory": ["{category}", "{user}"], + "retries": 10, + "timeout": 5, + "filename": "{id}_{filename}.{extension}" + }, + "exhentai": { + "directory": ["{category}", "{title}"] + }, + "tumblr": { + "directory": ["{blog_name}"], + "access-token": "WTt2nJdHLJAOQMpTbnMBGYqeJwoBeY2HDRztDPjf4HnqJ65rnT", + "access-token-secret": "0mI7ZWmD9CJPrQ1jjXvMGLjvJa44kOtgcKHtwz8LsAVDcODMPi", + "external": true, + "inline": true, + "posts": "all", + "reblogs": false, + "parent-directory": true, + "api-key": "uhBUtgPaX9gl7eaD8suGWW6ZInRedQoVT6xsZzopljy0jXHqm5", + "api-secret": "D3FDj1INyPzXikVpp4jmzSqjlC9czFUQ8oj2I883PSYJdqwURv" + }, + "deviantart": { + "client-id": "20016", + "client-secret": "52e1f9b0cb26e673da36f69e2ddd0e9a", + "refresh-token": "cc862526cb515d82e750c099aa7f32a29087c961", + "directory": ["{username}"], + "include": "gallery,scraps", + "flat": true, + "original": true, + "mature": true, + "auto-watch": true, + "auto-unwatch": true + }, + "furaffinity": { + "directory": ["{user}", "{subcategory}"], + "include": ["scraps", "gallery"] + }, + "patreon": { + "directory": [ + "(Patreon) {creator[vanity]}", + "({date:%Y%m%d}) {title} ({id})" + ], + "filename": "{filename}.{num}.{extension}", + "browser": "firefox" + }, + "blogger": { + "directory": [ + "{blog[name]}", + "{post[author]}", + "{post[title]} - [{post[id]}]" + ], + "filename": "{filename} - {num}.{extension}" + }, + "artstation": { + "directory": ["{userinfo[username]}"], + "external": true + }, + "gfycat": { + "format": "webm" + }, + "reddit": { + "user-agent": "Python:gallery-dl:v1.0 (by /u/captainjawz)", + "client-id": "T7nZ6WZ3_onJWBhLP8r08g", + "refresh-token": "184157546842-bkMXgGYWzkwGSgXTeC8mMmaDZouhUQ", + "directory": ["{author}"], + "parent-directory": true + }, + "redgifs": { + "reverse": "true", + "directory": ["{userName}"] + }, + "imgur": { + "mp4": true + }, + "paheal": { + "directory": ["Husbands", "{search_tags}"] + }, + "rule34": { + "directory": ["Husbands", "{search_tags}"] + }, + "e621": { + "directory": ["Husbands", "{search_tags}"] + }, + "baraag": { + "directory": ["{account[username]}"] + }, + "pixiv": { + "refresh-token": "O4kc9tTzGItuuacDcfmevW6NELjm5CJdWiAbZdUv3Kk", + "directory": ["{user[account]} - {user[id]}"], + "ugoira": true, + "favorite": { + "directory": [ + "{user_bookmark[account]} - {user_bookmark[id]}", + "Bookmarks" + ] + }, + "postprocessors": [ + { + "name": "ugoira", + "extension": "webm", + "keep-files": false, + "whitelist": ["pixiv"], + "ffmpeg-twopass": true, + "ffmpeg-args": ["-c:v", "libvpx", "-crf", "4", "-b:v", "5000k", "-an"] + } + ] + }, + "fanbox": { + "directory": ["{category}", "{creatorId}"], + "embeds": true + }, + "readcomiconline": { + "chapter-reverse": true, + "directory": ["Comics", "{comic}", "{comic} #{issue}"], + "quality": "hq", + "captcha": "wait", + "postprocessors": ["cbz"] + }, + "kissmanga": { + "chapter-reverse": true, + "directory": ["Manga", "{manga}", "{manga} Ch.{chapter}{chapter_minor}"], + "captcha": "wait", + "postprocessors": ["cbz"] + }, + "mangahere": { + "chapter-reverse": true, + "directory": ["Manga", "{manga}", "{manga} Ch.{chapter}{chapter_minor}"], + "postprocessors": ["cbz"] + }, + "mangadex": { + "chapter-reverse": true, + "chapter-filter": "lang == 'en'", + "directory": ["Manga", "{manga}", "{manga} Ch.{chapter}{chapter_minor}"], + "postprocessors": ["cbz"] + }, + "mangareader": { + "chapter-reverse": true, + "directory": ["Manga", "{manga}", "{manga} Ch.{chapter}{chapter_minor}"], + "postprocessors": ["cbz"] + }, + "mangapanda": { + "chapter-reverse": true, + "directory": ["Manga", "{manga}", "{manga} Ch.{chapter}{chapter_minor}"], + "postprocessors": ["cbz"] + }, + "webtoons": { + "chapter-reverse": true, + "directory": ["Webtoons", "{comic}", "{comic} #{episode}"], + "postprocessors": ["cbz"] + } + }, + "output": { + "mode": "auto" + }, + "downloader": { + "part": true, + "part-directory": "/home/jawz/.cache/gallery-dl", + "ytdl": { + "logging": true, + "format": "bestvideo+bestaudio/best", + "module": "yt_dlp", + "forward-cookies": true + }, + "http": { + "rate": null, + "retries": 5, + "timeout": 10.0, + "verify": true + } + }, + "postprocessor": { + "cbz": { + "name": "zip", + "compression": "store", + "mode": "safe", + "extension": "cbz" + } + } +} diff --git a/miniserver/dotfiles/gopass/config.yml b/miniserver/dotfiles/gopass/config.yml new file mode 100644 index 0000000..ece10ca --- /dev/null +++ b/miniserver/dotfiles/gopass/config.yml @@ -0,0 +1,10 @@ +autoclip: true +autoimport: false +cliptimeout: 45 +exportkeys: false +nopager: false +notifications: false +parsing: true +path: /home/jawz/.local/share/pass +safecontent: true +mounts: {} diff --git a/miniserver/dotfiles/htop/htoprc b/miniserver/dotfiles/htop/htoprc new file mode 100644 index 0000000..79ff45d --- /dev/null +++ b/miniserver/dotfiles/htop/htoprc @@ -0,0 +1,61 @@ +# Beware! This file is rewritten by htop when settings are changed in the interface. +# The parser is also very primitive, and not human-friendly. +htop_version=3.2.1 +config_reader_min_version=3 +fields=18 0 123 124 46 47 38 50 1 +hide_kernel_threads=0 +hide_userland_threads=0 +shadow_other_users=0 +show_thread_names=0 +show_program_path=0 +highlight_base_name=1 +highlight_deleted_exe=1 +highlight_megabytes=1 +highlight_threads=1 +highlight_changes=0 +highlight_changes_delay_secs=5 +find_comm_in_cmdline=1 +strip_exe_from_cmdline=1 +show_merged_command=1 +header_margin=1 +screen_tabs=1 +detailed_cpu_time=0 +cpu_count_from_one=1 +show_cpu_usage=1 +show_cpu_frequency=1 +show_cpu_temperature=1 +degree_fahrenheit=0 +update_process_names=0 +account_guest_in_cpu_meter=0 +color_scheme=3 +enable_mouse=1 +delay=15 +hide_function_bar=0 +header_layout=two_67_33 +column_meters_0=LeftCPUs Swap Tasks NetworkIO Memory +column_meter_modes_0=1 1 2 2 2 +column_meters_1=RightCPUs Hostname Uptime LoadAverage +column_meter_modes_1=1 2 2 2 +tree_view=1 +sort_key=38 +tree_sort_key=0 +sort_direction=-1 +tree_sort_direction=1 +tree_view_always_by_pid=1 +all_branches_collapsed=1 +screen:Main=NICE PID COMM EXE PERCENT_CPU PERCENT_MEM M_VIRT NLWP Command +.sort_key=M_VIRT +.tree_sort_key=PID +.tree_view=1 +.tree_view_always_by_pid=1 +.sort_direction=-1 +.tree_sort_direction=1 +.all_branches_collapsed=1 +screen:I/O=PID USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE PERCENT_SWAP_DELAY PERCENT_IO_DELAY Command +.sort_key=IO_RATE +.tree_sort_key=PID +.tree_view=0 +.tree_view_always_by_pid=0 +.sort_direction=-1 +.tree_sort_direction=1 +.all_branches_collapsed=0 diff --git a/miniserver/dotfiles/npm/npmrc b/miniserver/dotfiles/npm/npmrc new file mode 100644 index 0000000..8932649 --- /dev/null +++ b/miniserver/dotfiles/npm/npmrc @@ -0,0 +1,7 @@ +user=0 +unsafe-perm=true +prefix=${XDG_DATA_HOME}/npm +cache=${XDG_CACHE_HOME}/npm +tmp=${XDG_RUNTIME_DIR}/npm +init-module=${XDG_CONFIG_HOME}/npm/config/npm-init.js +store-dir=${XDG_DATA_HOME}/pnpm-store diff --git a/miniserver/dotfiles/npm/update-notifier-npm-check.json b/miniserver/dotfiles/npm/update-notifier-npm-check.json new file mode 100644 index 0000000..d2275b3 --- /dev/null +++ b/miniserver/dotfiles/npm/update-notifier-npm-check.json @@ -0,0 +1,4 @@ +{ + "optOut": false, + "lastUpdateCheck": 1646662583446 +} \ No newline at end of file diff --git a/miniserver/dotfiles/pythonrc b/miniserver/dotfiles/pythonrc new file mode 100644 index 0000000..f3f86a5 --- /dev/null +++ b/miniserver/dotfiles/pythonrc @@ -0,0 +1,17 @@ +import os +import atexit +import readline + +history = os.path.join(os.environ['XDG_CACHE_HOME'], 'python_history') +try: + readline.read_history_file(history) +except OSError: + pass + +def write_history(): + try: + readline.write_history_file(history) + except OSError: + pass + +atexit.register(write_history) diff --git a/miniserver/dotfiles/secrets/mailserver b/miniserver/dotfiles/secrets/mailserver new file mode 100644 index 0000000..2a2b8ea --- /dev/null +++ b/miniserver/dotfiles/secrets/mailserver @@ -0,0 +1 @@ +b/run/current-system/sw/bin/bash5/BpvLE.0dXQuzNskhAD94U6zFCFvfhzqWJEiBi diff --git a/miniserver/dotfiles/wget/wgetrc b/miniserver/dotfiles/wget/wgetrc new file mode 100644 index 0000000..ed7eedf --- /dev/null +++ b/miniserver/dotfiles/wget/wgetrc @@ -0,0 +1 @@ +hsts-file = /home/jawz/.cache/wget-hsts diff --git a/miniserver/fstab.nix b/miniserver/fstab.nix new file mode 100644 index 0000000..c7c9463 --- /dev/null +++ b/miniserver/fstab.nix @@ -0,0 +1,155 @@ +{ config, lib, pkgs, modulesPath, ... }: { + imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; + boot = { + loader = { + efi = { + canTouchEfiVariables = true; + efiSysMountPoint = "/boot/efi"; + }; + grub = { + enable = true; + device = "nodev"; + efiSupport = true; + enableCryptodisk = true; + }; + }; + initrd.luks.devices = { + nvme = { + device = "/dev/disk/by-uuid/30fd7d86-9bed-42a6-8a4e-a2ddb0031233"; + preLVM = true; + }; + # disk1 = { + # device = "/dev/disk/by-uuid/a9b0f346-7e38-40a6-baf6-3ad80cafc842"; + # preLVM = true; + # }; + # disk2 = { + # device = "/dev/disk/by-uuid/0ed12b83-4c56-4ba8-b4ea-75a9e927d771"; + # preLVM = true; + # }; + # disk3 = { + # device = "/dev/disk/by-uuid/8cd728f6-0d5b-4cea-8f7d-01aad11192c1"; + # preLVM = true; + # }; + # disk4 = { + # device = "/dev/disk/by-uuid/7fcac808-491f-4846-a4a9-a34cc77cb43d"; + # preLVM = true; + # }; + }; + kernelModules = [ "kvm-intel" ]; + kernel.sysctl = { + "vm.swappiness" = 80; + "net.ipv6.conf.all.disable_ipv6" = 1; + "net.ipv6.conf.lo.disable_ipv6" = 1; + "net.ipv6.conf.default.disable_ipv6" = 1; + }; + extraModulePackages = [ ]; + initrd = { + availableKernelModules = [ + "xhci_pci" + "ahci" + "usbhid" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + "sdhci_pci" + ]; + kernelModules = [ "kvm-intel" ]; + }; + }; + + fileSystems = { + "/" = { + device = "/dev/mapper/nvme"; + fsType = "btrfs"; + options = [ + "subvol=nix" + "ssd" + "compress=zstd:3" + "x-systemd.device-timeout=0" + "space_cache=v2" + "commit=120" + "datacow" + "noatime" + ]; + }; + "/home" = { + device = "/dev/mapper/nvme"; + fsType = "btrfs"; + options = [ + "subvol=home" + "ssd" + "compress=zstd:3" + "x-systemd.device-timeout=0" + "space_cache=v2" + "commit=120" + "datacow" + ]; + }; + # "/mnt/pool" = { + # device = "/dev/disk/by-uuid/1e7cf787-e34d-4e3e-ac3c-0c07309dbd34"; + # fsType = "btrfs"; + # options = [ + # "subvol=@data" + # "compress=zstd:3" + # "space_cache=v2" + # "commit=120" + # "datacow" + # ]; + # }; + "/boot" = { + device = "/dev/disk/by-uuid/bf0aeb95-94cc-4377-b6e4-1dbb4958b334"; + fsType = "ext4"; + }; + "/boot/efi" = { + device = "/dev/disk/by-uuid/0C7B-4D4C"; + fsType = "vfat"; + }; + "/var/lib/nextcloud/data" = { + device = "/mnt/pool/nextcloud"; + options = [ "bind" ]; + depends = [ "/mnt/pool" ]; + }; + # "/mnt/jellyfin/media" = { + # device = "/mnt/pool/multimedia/media"; + # options = [ "bind" "ro" ]; + # depends = [ "/mnt/pool" ]; + # }; + # NFS + "/export/pool" = { + device = "/mnt/pool"; + options = [ "bind" ]; + depends = [ "/mnt/pool" ]; + }; + "/export/jawz" = { + device = "/home/jawz"; + options = [ "bind" ]; + depends = [ "/mnt/pool" ]; + }; + "/export/disks" = { + device = "/mnt/disks"; + options = [ "bind" ]; + depends = [ "/mnt/disks" ]; + }; + }; + services.nfs = { + server = { + enable = true; + exports = '' + /export workstation(rw,fsid=0,no_subtree_check) + /export/jawz workstation(rw,nohide,insecure,no_subtree_check) + /export/disks workstation(rw,nohide,insecure,no_subtree_check) + /export/pool workstation(rw,nohide,insecure,no_subtree_check) + ''; + }; + }; + swapDevices = [{ + device = "/dev/nvme0n1p3"; + randomEncryption = { + enable = true; + cipher = "aes-xts-plain64"; + keySize = 512; + sectorSize = 4096; + }; + }]; +} diff --git a/miniserver/mail.nix b/miniserver/mail.nix new file mode 100644 index 0000000..e6eee91 --- /dev/null +++ b/miniserver/mail.nix @@ -0,0 +1,37 @@ +{ config, pkgs, ... }: +let + version = "23.05"; + domain = "danilo-reyes.com"; +in { + imports = [ + (builtins.fetchTarball { + # Pick a release version you are interested in and set its hash, e.g. + url = + "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/nixos-${version}/nixos-mailserver-nixos-${version}.tar.gz"; + # To get the sha256 of the nixos-mailserver tarball, we can use the nix-prefetch-url command: + # release="nixos-23.05"; nix-prefetch-url "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/${release}/nixos-mailserver-${release}.tar.gz" --unpack + sha256 = "1ngil2shzkf61qxiqw11awyl81cr7ks2kv3r3k243zz7v2xakm5c"; + }) + ]; + + mailserver = { + enable = true; + fqdn = "mail.${domain}"; + domains = [ domain ]; + + # A list of all login accounts. To create the password hashes, use + # nix-shell -p mkpasswd --run 'mkpasswd -sm bcrypt' + loginAccounts = { + "contact@${domain}" = { + hashedPasswordFile = ../dotfiles/secrets/mailserver; + aliases = [ "jawz@${domain}" ]; + }; + }; + + # Use Let's Encrypt certificates. Note that this needs to set up a stripped + # down nginx and opens port 80. + certificateScheme = "acme-nginx"; + }; + security.acme.acceptTerms = true; + security.acme.defaults.email = "contact@${domain}"; +} diff --git a/miniserver/nginx.nix b/miniserver/nginx.nix new file mode 100644 index 0000000..8493915 --- /dev/null +++ b/miniserver/nginx.nix @@ -0,0 +1,260 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ + +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: +let + localhost = "127.0.0.1"; + workstation = "192.168.1.64"; + domain = "servidos.lat"; + jellyfinPort = 8096; + nextcloudPort = 80; + collaboraPort = 9980; + flamePort = 5005; + secretFlamePort = 5007; + lidarrPort = 8686; + qbitPort = 9091; + prowlarrPort = 9696; + radarrPort = 7878; + sonarrPort = 8989; + mealiePort = 9925; + ryotPort = 8765; + scrobblePort = 9078; + malojaPort = 42010; + darkwirePort = 3001; + jiraPort = 8091; + metatubePort = 8881; + bazarrPort = config.services.bazarr.listenPort; + kavitaPort = config.services.kavita.port; + vaultPort = config.services.vaultwarden.config.ROCKET_PORT; + audiobookPort = config.services.audiobookshelf.port; + microbinPort = config.services.microbin.settings.MICROBIN_PORT; +in { + services.nginx = { + enable = true; + clientMaxBodySize = "4096m"; + # recommendedTlsSettings = true; + # recommendedGzipSettings = true; + # recommendedOptimisation = true; + sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; + appendHttpConfig = '' + # JELLYFIN + proxy_cache_path /var/cache/nginx/jellyfin-videos levels=1:2 keys_zone=jellyfin-videos:100m inactive=90d max_size=35000m; + proxy_cache_path /var/cache/nginx/jellyfin levels=1:2 keys_zone=jellyfin:100m max_size=15g inactive=30d use_temp_path=off; + map $request_uri $h264Level { ~(h264-level=)(.+?)& $2; } + map $request_uri $h264Profile { ~(h264-profile=)(.+?)& $2; } + ''; + virtualHosts = let + base = locations: { + inherit locations; + forceSSL = true; + enableACME = true; + http2 = true; + }; + proxy = port: + base { "/".proxyPass = "http://${localhost}:${toString (port)}/"; }; + proxyArr = port: + proxy port // { + extraConfig = '' + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $http_connection; + + proxy_redirect off; + proxy_http_version 1.1; + ''; + }; + in { + # "movies.${domain}" = proxyArr radarrPort // { }; + # "indexer.${domain}" = proxyArr prowlarrPort // { }; + # "music.${domain}" = proxyArr lidarrPort // { }; + # "library.${domain}" = proxy kavitaPort // { }; + "start.${domain}" = proxy flamePort // { }; + # "subs.${domain}" = proxy bazarrPort // { }; + # "series.${domain}" = proxy sonarrPort // { }; + "vault.${domain}" = proxy vaultPort // { }; + "copy.${domain}" = proxy microbinPort // { }; + "mealie.${domain}" = proxy mealiePort // { }; + "tracker.${domain}" = proxy ryotPort // { }; + "scrobble.${domain}" = proxy scrobblePort // { }; + "maloja.${domain}" = proxy malojaPort // { }; + "jira.${domain}" = proxy jiraPort // { }; + "bajameesta.${domain}" = proxy metatubePort // { }; + "qampqwn4wprhqny8h8zj.${domain}" = proxy secretFlamePort // { }; + "xfwmrle6h6skqujbeizw.${domain}" = proxy qbitPort // { }; + "audiobooks.${domain}" = base { + "/" = { + proxyPass = "http://${localhost}:${toString (audiobookPort)}"; + 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; + + proxy_redirect http:// https://; + ''; + }; + }; + "dontcancelmeplz.${domain}" = base { + "/" = { + proxyPass = "http://${localhost}:${toString (darkwirePort)}"; + proxyWebsockets = true; + extraConfig = '' + # Ensuring it can use websockets + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + 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 http; + proxy_redirect http:// $scheme://; + + # The proxy must preserve the host because gotify verifies the host with the origin + # for WebSocket connections + proxy_set_header Host $host; + + # These sets the timeout so that the websocket can stay alive + proxy_connect_timeout 1m; + proxy_send_timeout 1m; + proxy_read_timeout 1m; + ''; + }; + }; + "flix.${domain}" = { + forceSSL = true; + enableACME = true; + http2 = true; + extraConfig = '' + # use a variable to store the upstream proxy + # in this example we are using a hostname which is resolved via DNS + # (if you aren't using DNS remove the resolver line and change the variable to point to an IP address + resolver ${localhost} valid=30; + + location = / { + return 302 http://$host/web/; + #return 302 https://$host/web/; + } + + location = /web/ { + # Proxy main Jellyfin traffic + proxy_pass http://${localhost}:${ + toString (jellyfinPort) + }/web/index.html; + 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; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + } + ''; + locations = { + "/" = { + proxyPass = "http://${localhost}:${toString (jellyfinPort)}"; + proxyWebsockets = true; + }; + "/socket" = { + proxyPass = "http://${localhost}:${toString (jellyfinPort)}"; + extraConfig = '' + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + ''; + }; + "~ /Items/(.*)/Images" = { + proxyPass = "http://${localhost}:${toString (jellyfinPort)}"; + extraConfig = '' + proxy_cache jellyfin; + proxy_cache_revalidate on; + proxy_cache_lock on; + ''; + }; + "~* ^/Videos/(.*)/(?!live)" = { + proxyPass = "http://${localhost}:${toString (jellyfinPort)}"; + extraConfig = '' + # Set size of a slice (this amount will be always requested from the backend by nginx) + # Higher value means more latency, lower more overhead + # This size is independent of the size clients/browsers can request + # slice 2m; + + proxy_cache jellyfin-videos; + proxy_cache_valid 200 206 301 302 30d; + proxy_ignore_headers Expires Cache-Control Set-Cookie X-Accel-Expires; + proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; + proxy_connect_timeout 15s; + proxy_http_version 1.1; + proxy_set_header Connection ""; + # Transmit slice range to the backend + proxy_set_header Range 2m; + + # This saves bandwidth between the proxy and jellyfin, as a file is only downloaded one time instead of multiple times when multiple clients want to at the same time + # The first client will trigger the download, the other clients will have to wait until the slice is cached + # Esp. practical during SyncPlay + proxy_cache_lock on; + proxy_cache_lock_age 60s; + + proxy_cache_key "jellyvideo$uri?MediaSourceId=$arg_MediaSourceId&VideoCodec=$arg_VideoCodec&AudioCodec=$arg_AudioCodec&AudioStreamIndex=$arg_AudioStreamIndex&VideoBitrate=$arg_VideoBitrate&AudioBitrate=$arg_AudioBitrate&SubtitleMethod=$arg_SubtitleMethod&TranscodingMaxAudioChannels=$arg_TranscodingMaxAudioChannels&RequireAvc=$arg_RequireAvc&SegmentContainer=$arg_SegmentContainer&MinSegments=$arg_MinSegments&BreakOnNonKeyFrames=$arg_BreakOnNonKeyFrames&h264-profile=$h264Profile&h264-level=$h264Level&slicerange=2m"; + + # add_header X-Cache-Status $upstream_cache_status; # This is only for debugging cache + ''; + }; + }; + }; + ${config.services.nextcloud.hostName} = { + forceSSL = true; + enableACME = true; + http2 = true; + serverAliases = [ "cloud.rotehaare.art" ]; + locations = { + "/".proxyWebsockets = true; + # uh, equals what? + "~ ^/nextcloud/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|oc[ms]-provider/.+|.+/richdocumentscode/proxy).php(?:$|/)" = + { }; + }; + }; + + "collabora.${domain}" = let + collaboraString = "http://${localhost}:${toString (collaboraPort)}"; + collaboraProxy = { + proxyPass = collaboraString; + extraConfig = '' + proxy_set_header Host $host; + ''; + }; + collaboraSocket = { + proxyPass = collaboraString; + extraConfig = '' + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_read_timeout 36000s; + ''; + }; + in base { + # static files + "^~ /loleaflet" = collaboraProxy; + # WOPI discovery URL + "^~ /hosting/discovery" = collaboraProxy; + # Capabilities + "^~ /hosting/capabilities" = collaboraProxy; + # download, presentation, image upload and websocket + "~ ^/lool" = collaboraSocket; + # Admin Console websocket + "^~ /lool/adminws" = collaboraSocket; + }; + }; + }; + networking = { + firewall = let open_firewall_ports = [ 80 443 ]; + in { + enable = true; + allowedTCPPorts = open_firewall_ports; + allowedUDPPorts = open_firewall_ports; + }; + }; +} diff --git a/miniserver/openldap.nix b/miniserver/openldap.nix new file mode 100644 index 0000000..53c9429 --- /dev/null +++ b/miniserver/openldap.nix @@ -0,0 +1,83 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +let hostname = "servidos.lat"; +in { + services.openldap = { + enable = true; + + # enable plain and secure connections + urlList = [ "ldap:///" "ldaps:///" ]; + + settings = { + attrs = { + olcLogLevel = "conns config"; + + # settings for acme ssl + olcTLSCACertificateFile = "/var/lib/acme/${hostname}/full.pem"; + olcTLSCertificateFile = "/var/lib/acme/${hostname}/cert.pem"; + olcTLSCertificateKeyFile = "/var/lib/acme/${hostname}/key.pem"; + olcTLSCipherSuite = "HIGH:MEDIUM:+3DES:+RC4:+aNULL"; + olcTLSCRLCheck = "none"; + olcTLSVerifyClient = "never"; + olcTLSProtocolMin = "3.1"; + }; + + children = { + "cn=schema".includes = [ + "${pkgs.openldap}/etc/schema/core.ldif" + "${pkgs.openldap}/etc/schema/cosine.ldif" + "${pkgs.openldap}/etc/schema/inetorgperson.ldif" + ]; + + "olcDatabase={1}mdb".attrs = { + objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ]; + + olcDatabase = "{1}mdb"; + olcDbDirectory = "/var/lib/openldap/data"; + + olcSuffix = "dc=example,dc=com"; + + # your admin account, do not use writeText on a production system + olcRootDN = "cn=admin,dc=example,dc=com"; + olcRootPW.path = pkgs.writeText "olcRootPW" "pass"; + + olcAccess = [ + # custom access rules for userPassword attributes + '' + {0}to attrs=userPassword + by self write + by anonymous auth + by * none'' + + # allow read on anything else + '' + {1}to * + by * read'' + ]; + }; + }; + }; + }; + + # ensure openldap is launched after certificates are created + systemd.services.openldap = { + wants = [ "acme-${hostname}.service" ]; + after = [ "acme-${hostname}.service" ]; + }; + + # make acme certificates accessible by openldap + security.acme.defaults.group = "certs"; + users.groups.certs.members = [ "openldap" ]; + + # trigger the actual certificate generation for your hostname + security.acme.certs."${hostname}" = { extraDomainNames = [ ]; }; + + # example using hetzner dns to run letsencrypt verification + security.acme.defaults.dnsProvider = "hetzner"; + security.acme.defaults.credentialsFile = pkgs.writeText "credentialsFile" '' + HETZNER_API_KEY= + ''; +} diff --git a/miniserver/servers.nix b/miniserver/servers.nix new file mode 100644 index 0000000..e6011e7 --- /dev/null +++ b/miniserver/servers.nix @@ -0,0 +1,336 @@ +{ config, lib, pkgs, modulesPath, ... }: +let + localhost = "127.0.0.1"; + postgresSocket = "/run/postgresql"; + unstable = import + (builtins.fetchTarball "https://github.com/nixos/nixpkgs/tarball/master") { + config = config.nixpkgs.config; + }; +in { + + imports = [ ./nginx.nix ]; + nixpkgs.config = { + permittedInsecurePackages = [ "nodejs-14.21.3" "openssl-1.1.1v" ]; + }; + environment.systemPackages = with pkgs; + [ + # Upgrades postgres + (let + # XXX specify the postgresql package you'd like to upgrade to. + # Do not forget to list the extensions you need. + newPostgres = pkgs.postgresql_16.withPackages (pp: + [ + # pp.plv8 + ]); + in pkgs.writeScriptBin "upgrade-pg-cluster" '' + set -eux + # XXX it's perhaps advisable to stop all services that depend on postgresql + systemctl stop postgresql + + export NEWDATA="/var/lib/postgresql/${newPostgres.psqlSchema}" + + export NEWBIN="${newPostgres}/bin" + + export OLDDATA="${config.services.postgresql.dataDir}" + export OLDBIN="${config.services.postgresql.package}/bin" + + install -d -m 0700 -o postgres -g postgres "$NEWDATA" + cd "$NEWDATA" + sudo -u postgres $NEWBIN/initdb -D "$NEWDATA" + + sudo -u postgres $NEWBIN/pg_upgrade \ + --old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \ + --old-bindir $OLDBIN --new-bindir $NEWBIN \ + "$@" + '') + ]; + users.groups = { piracy.gid = 985; }; + users.users = let base = { isSystemUser = true; }; + in { + # # prowlarr = base // { group = "piracy"; }; + # # kavita = base // { + # # group = "kavita"; + # # extraGroups = [ "piracy" ]; + # # }; + nextcloud = base // { + extraGroups = [ "render" ]; + packages = (with pkgs; [ + nodejs + (python3.withPackages (ps: with ps; [ tensorflow ])) + perl + (perlPackages.buildPerlPackage rec { + pname = "Image-ExifTool"; + version = "12.70"; + src = fetchurl { + url = "https://exiftool.org/Image-ExifTool-${version}.tar.gz"; + hash = "sha256-TLJSJEXMPj870TkExq6uraX8Wl4kmNerrSlX3LQsr/4="; + }; + }) + ]); + }; + }; + programs = { + msmtp = { + enable = true; + accounts.default = { + auth = true; + host = "smtp.gmail.com"; + port = 587; + tls = true; + from = "stunner6399@gmail.com"; + user = "stunner6399@gmail.com"; + password = "eqyctcgjdykqeuwt"; + }; + }; + }; + services = let + base = { + enable = true; + group = "piracy"; + }; + in { + # sonarr = base // { package = pkgs.sonarr; }; + # radarr = base // { package = pkgs.radarr; }; + # bazarr = base // { }; + jellyfin = base // { }; + # prowlarr.enable = true; + # jira.enable = true; + microbin = { + enable = true; + settings = { + MICROBIN_HIDE_LOGO = false; + MICROBIN_PORT = 8080; + MICROBIN_HIGHLIGHTSYNTAX = true; + MICROBIN_PRIVATE = true; + MICROBIN_QR = true; + MICROBIN_ENCRYPTION_CLIENT_SIDE = true; + MICROBIN_ENCRYPTION_SERVER_SIDE = true; + }; + }; + # audiobookshelf = { + # enable = true; + # group = "piracy"; + # port = 5687; + # }; + # paperless = { + # enable = true; + # address = "0.0.0.0"; + # consumptionDirIsPublic = true; + # consumptionDir = "/home/jawz/Backups/Scans"; + # extraConfig = { + # PAPERLESS_DBENGINE = "postgress"; + # PAPERLESS_DBNAME = "paperless"; + # PAPERLESS_DBHOST = postgresSocket; + # PAPERLESS_CONSUMER_IGNORE_PATTERN = + # builtins.toJSON [ ".DS_STORE/*" "desktop.ini" ]; + # PAPERLESS_TIME_ZONE = "America/Mexico_City"; + # PAPERLESS_OCR_USER_ARGS = builtins.toJSON { + # optimize = 1; + # pdfa_image_compression = "lossless"; + # }; + # }; + # }; + vaultwarden = { + enable = true; + dbBackend = "postgresql"; + package = pkgs.vaultwarden; + config = { + ROCKET_ADDRESS = "${localhost}"; + ROCKET_PORT = 8222; + WEBSOCKET_PORT = 8333; + ADMIN_TOKEN = + "x9BLqz2QmnU5RmrMLt2kPpoPBTNPZxNFw/b8XrPgpQML2/01+MYENl87dmhDX+Jm"; + DATABASE_URL = "postgresql:///vaultwarden?host=${postgresSocket}"; + ENABLE_DB_WAL = false; + WEBSOCKET_ENABLED = true; + SHOW_PASSWORD_HINT = false; + SIGNUPS_ALLOWED = false; + EXTENDED_LOGGING = true; + LOG_LEVEL = "warn"; + }; + }; + # kavita = { + # enable = true; + # tokenKeyFile = "${pkgs.writeText "kavitaToken" + # "Au002BRkRxBjlQrmWSuXWTGUcpXZjzMo2nJ0Z4g4OZ1S4c2zp6oaesGUXzKp2mhvOwjju002BNoURG3CRIE2qnGybvOgAlDxAZCPBzSNRcx6RJ1lFRgvI8wQR6Nd5ivYX0RMo4S8yOH8XIDhzN6vNo31rCjyv2IycX0JqiJPIovfbvXn9Y="}"; + # }; + nextcloud = { + enable = true; + https = true; + package = pkgs.nextcloud27; + appstoreEnable = true; + configureRedis = true; + extraAppsEnable = true; + enableImagemagick = true; + maxUploadSize = "16G"; + hostName = "cloud.servidos.lat"; + config = { + adminpassFile = "${pkgs.writeText "adminpass" + "Overlying-Hatchback-Charting-Encounter-Deface-Gallantly7"}"; + overwriteProtocol = "https"; + defaultPhoneRegion = "MX"; + dbtype = "pgsql"; + dbhost = postgresSocket; + dbtableprefix = "oc_"; + dbname = "nextcloud"; + trustedProxies = [ "nginx" ]; + extraTrustedDomains = [ "cloud.rotehaare.art" "danilo-reyes.com" ]; + }; + phpOptions = { + catch_workers_output = "yes"; + display_errors = "stderr"; + error_reporting = "E_ALL & ~E_DEPRECATED & ~E_STRICT"; + expose_php = "Off"; + "opcache.enable_cli" = "1"; + "opcache.fast_shutdown" = "1"; + "opcache.interned_strings_buffer" = "16"; + "opcache.jit" = "1255"; + "opcache.jit_buffer_size" = "256M"; + "opcache.max_accelerated_files" = "10000"; + "opcache.huge_code_pages" = "1"; + "opcache.enable_file_override" = "1"; + "opcache.memory_consumption" = "128"; + "opcache.revalidate_freq" = "60"; + "opcache.save_comments" = "1"; + "opcache.validate_timestamps" = "0"; + "openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt"; + short_open_tag = "Off"; + }; + extraOptions = { + "allow_local_remote_servers" = true; + mail_smtpmode = "sendmail"; + mail_sendmailmode = "pipe"; + "installed" = true; + "memories.exiftool" = "/etc/profiles/per-user/nextcloud/bin/exiftool"; + enabledPreviewProviders = [ + "OC\\Preview\\Image" + "OC\\Preview\\HEIC" + "OC\\Preview\\TIFF" + "OC\\Preview\\MKV" + "OC\\Preview\\MP4" + "OC\\Preview\\AVI" + "OC\\Preview\\Movie" + ]; + }; + phpExtraExtensions = all: [ all.pdlib all.bz2 ]; + }; + postgresql = { + enable = true; + ensureDatabases = [ "jawz" "paperless" "nextcloud" "ryot" "vaultwarden" ]; + package = pkgs.postgresql_16; + ensureUsers = [ + { + name = "jawz"; + ensureDBOwnership = true; + } + { + name = "nextcloud"; + ensureDBOwnership = true; + } + { + name = "paperless"; + ensureDBOwnership = true; + } + { + name = "ryot"; + ensureDBOwnership = true; + } + { + name = "vaultwarden"; + ensureDBOwnership = true; + } + ]; + authentication = pkgs.lib.mkOverride 10 '' + local all all trust + host all all ${localhost}/32 trust + host all all ::1/128 trust + ''; + }; + }; + systemd = { + services = { + # sub-sync = { + # restartIfChanged = true; + # description = "syncronizes subtitles downloaded & modified today"; + # wantedBy = [ "default.target" ]; + # path = [ + # pkgs.bash + # pkgs.nix + # jawzSubs + # ]; + # serviceConfig = { + # Restart = "on-failure"; + # RestartSec = 30; + # ExecStart = "${jawzSubs}/bin/sub-sync all"; + # Type = "forking"; + # User = "root"; + # }; + # }; + nextcloud-cronjob = let + jawzNextcloudCronjob = pkgs.writeScriptBin "nextcloud-cronjob" + (builtins.readFile ../scripts/nextcloud-cronjob.sh); + in { + description = "Runs various nextcloud-related cronjobs"; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.bash jawzNextcloudCronjob ]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = "${jawzNextcloudCronjob}/bin/nextcloud-cronjob"; + }; + }; + }; + timers = { + nextcloud-cronjob = { + enable = true; + description = "Runs various nextcloud-related cronjobs"; + wantedBy = [ "timers.target" ]; + timerConfig = { OnCalendar = "*:0/10"; }; + }; + # sub-sync = { + # enable = true; + # description = "syncronizes subtitles downloaded & modified today"; + # wantedBy = [ "timers.target" ]; + # timerConfig = { + # OnCalendar = "22:00"; + # }; + # }; + }; + user.services = { + update-dns = let + jawzUpdateDns = pkgs.writeScriptBin "update-dns" + (builtins.readFile ../scripts/update-dns.sh); + in { + restartIfChanged = true; + description = "update DNS of my websites"; + wantedBy = [ "default.target" ]; + path = [ pkgs.bash pkgs.nix jawzUpdateDns ]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = "${jawzUpdateDns}/bin/update-dns"; + }; + }; + }; + user.timers = { + update-dns = { + enable = true; + description = "update DNS of my websites"; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = "1min"; + OnUnitActiveSec = "30m"; + }; + }; + }; + }; + + networking = { + firewall = let open_firewall_ports = [ config.services.paperless.port ]; + in { + enable = true; + allowedTCPPorts = open_firewall_ports; + allowedUDPPorts = open_firewall_ports; + }; + }; +} diff --git a/server/configuration.org b/server/configuration.org index f4fcb83..6e3481a 100644 --- a/server/configuration.org +++ b/server/configuration.org @@ -291,6 +291,7 @@ users.users.jawz = { authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB5GaQM4N+yGAByibOFQOBVMV/6TjOfaGIP+NunMiK76 gpodeacero\cdreyes@100CDREYES" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH2wtsaMvfEUm//2YnFHyrc16o+TOXXBfIGPJ9nL8RMp jawz@workstation" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGjnNIggZweJ+GJKKvFEPhpLcs+t64xXjBmeuERsLFLL jawz@miniserver" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBEblxSDhWPEo33crSjooeUg4W02ruENxHLmmBqCuIo jawz@galaxy" ]; }; diff --git a/workstation/configuration.org b/workstation/configuration.org index 3356155..2bfae08 100644 --- a/workstation/configuration.org +++ b/workstation/configuration.org @@ -363,6 +363,7 @@ users = { authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB5GaQM4N+yGAByibOFQOBVMV/6TjOfaGIP+NunMiK76 gpodeacero\cdreyes@100CDREYES" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMkpeIV9G26W2/e9PsjBx3sNwPGoicJ807ExRGh4KjhW jawz@server" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGjnNIggZweJ+GJKKvFEPhpLcs+t64xXjBmeuERsLFLL jawz@miniserver" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBEblxSDhWPEo33crSjooeUg4W02ruENxHLmmBqCuIo jawz@galaxy" ]; };