Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 19050b4cf4 | |||
| 6676c15f75 | |||
| 27e487e322 | |||
| 4f28050eff | |||
| b58ea60557 | |||
| e95eedffe4 | |||
| 1abd53987c | |||
| d1a3e7338a | |||
| 687ef0c167 | |||
| 3a86148352 |
@@ -37,7 +37,12 @@
|
|||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
overlays = builtins.attrValues outputs.overlays;
|
overlays = builtins.attrValues outputs.overlays;
|
||||||
config.allowUnfree = true;
|
config = {
|
||||||
|
allowUnfree = true;
|
||||||
|
permittedInsecurePackages = [
|
||||||
|
"openssl-1.1.1w" # This is for discord-canary
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
|
|||||||
@@ -42,11 +42,12 @@
|
|||||||
"qwen3:8b"
|
"qwen3:8b"
|
||||||
"qwen3.5:27b"
|
"qwen3.5:27b"
|
||||||
"qwen3.5:35b"
|
"qwen3.5:35b"
|
||||||
|
"qwen3.6:27b"
|
||||||
"qwen3.6:35b"
|
"qwen3.6:35b"
|
||||||
|
"rinex20/translategemma3:12b"
|
||||||
"translategemma:12b"
|
"translategemma:12b"
|
||||||
"translategemma:27b"
|
"translategemma:27b"
|
||||||
"translategemma:4b"
|
"translategemma:4b"
|
||||||
"rinex20/translategemma3:12b"
|
|
||||||
];
|
];
|
||||||
models = "/zfs/storage/models";
|
models = "/zfs/storage/models";
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
|
|||||||
@@ -1,4 +1,13 @@
|
|||||||
{
|
{
|
||||||
|
# Docker loads br_netfilter on jeeves. Disable bridge netfilter so
|
||||||
|
# br-nix-builder behaves like a pure L2 bridge and bridged traffic
|
||||||
|
# does not hit the host firewall/rpfilter path.
|
||||||
|
boot.kernel.sysctl = {
|
||||||
|
"net.bridge.bridge-nf-call-arptables" = 0;
|
||||||
|
"net.bridge.bridge-nf-call-ip6tables" = 0;
|
||||||
|
"net.bridge.bridge-nf-call-iptables" = 0;
|
||||||
|
};
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
hostName = "jeeves";
|
hostName = "jeeves";
|
||||||
hostId = "0e15ce35";
|
hostId = "0e15ce35";
|
||||||
@@ -49,23 +58,10 @@
|
|||||||
"60-br-nix-builder" = {
|
"60-br-nix-builder" = {
|
||||||
matchConfig.Name = "br-nix-builder";
|
matchConfig.Name = "br-nix-builder";
|
||||||
bridgeConfig = { };
|
bridgeConfig = { };
|
||||||
address = [ "192.168.3.10/24" ];
|
networkConfig = {
|
||||||
routingPolicyRules = [
|
IPv6AcceptRA = false;
|
||||||
{
|
LinkLocalAddressing = "no";
|
||||||
From = "192.168.3.0/24";
|
};
|
||||||
Table = 100;
|
|
||||||
Priority = 100;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
routes = [
|
|
||||||
{
|
|
||||||
Gateway = "192.168.3.1";
|
|
||||||
Table = 100;
|
|
||||||
GatewayOnLink = false;
|
|
||||||
Metric = 2048;
|
|
||||||
PreferredSource = "192.168.3.10";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
linkConfig.RequiredForOnline = "no";
|
linkConfig.RequiredForOnline = "no";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
outputs,
|
outputs,
|
||||||
|
utils,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
@@ -9,6 +10,8 @@ with lib;
|
|||||||
let
|
let
|
||||||
vars = import ../vars.nix;
|
vars = import ../vars.nix;
|
||||||
cfg = config.services.nix_builder;
|
cfg = config.services.nix_builder;
|
||||||
|
runnerUsername = "gitea-runner";
|
||||||
|
runnerUserid = 601;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.services.nix_builder = {
|
options.services.nix_builder = {
|
||||||
@@ -33,27 +36,30 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
users = {
|
||||||
|
users.${runnerUsername} = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = runnerUsername;
|
||||||
|
uid = runnerUserid;
|
||||||
|
};
|
||||||
|
groups.${runnerUsername}.gid = runnerUserid;
|
||||||
|
};
|
||||||
|
|
||||||
containers = mapAttrs (
|
containers = mapAttrs (
|
||||||
name: containerCfg:
|
name: containerCfg:
|
||||||
mkIf containerCfg.enable {
|
mkIf containerCfg.enable {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
privateNetwork = true;
|
privateNetwork = true;
|
||||||
hostBridge = cfg.bridgeName;
|
hostBridge = cfg.bridgeName;
|
||||||
ephemeral = true;
|
|
||||||
bindMounts = {
|
bindMounts = {
|
||||||
storage = {
|
|
||||||
hostPath = "/zfs/media/github-runners/${name}";
|
|
||||||
mountPoint = "/var/lib/gitea-runner/${name}";
|
|
||||||
isReadOnly = false;
|
|
||||||
};
|
|
||||||
host-nix = {
|
host-nix = {
|
||||||
mountPoint = "/host-nix/var/nix/daemon-socket";
|
mountPoint = "/host-nix/var/nix/daemon-socket";
|
||||||
hostPath = "/nix/var/nix/daemon-socket";
|
hostPath = "/nix/var/nix/daemon-socket";
|
||||||
isReadOnly = false;
|
isReadOnly = false;
|
||||||
};
|
};
|
||||||
token = {
|
token = {
|
||||||
hostPath = "${vars.secrets}/services/gitea-runners/registration-token";
|
hostPath = "${vars.secrets}/services/gitea-runners";
|
||||||
mountPoint = "${vars.secrets}/services/gitea-runners/registration-token";
|
mountPoint = "/run/secrets/gitea-runners";
|
||||||
isReadOnly = true;
|
isReadOnly = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -102,24 +108,59 @@ in
|
|||||||
overlays = builtins.attrValues outputs.overlays;
|
overlays = builtins.attrValues outputs.overlays;
|
||||||
config.allowUnfree = true;
|
config.allowUnfree = true;
|
||||||
};
|
};
|
||||||
|
users = {
|
||||||
|
users.${runnerUsername} = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = runnerUsername;
|
||||||
|
uid = runnerUserid;
|
||||||
|
};
|
||||||
|
groups.${runnerUsername}.gid = runnerUserid;
|
||||||
|
};
|
||||||
services.gitea-actions-runner.instances.${name} = {
|
services.gitea-actions-runner.instances.${name} = {
|
||||||
enable = true;
|
enable = true;
|
||||||
name = "jeeves-${name}";
|
name = "jeeves-${name}";
|
||||||
url = "https://gitea.tmmworkshop.com";
|
url = "http://192.168.99.14:6443/";
|
||||||
labels = [
|
labels = [
|
||||||
"self-hosted:host"
|
"self-hosted:host"
|
||||||
"nixos:host"
|
"nixos:host"
|
||||||
];
|
];
|
||||||
tokenFile = "${vars.secrets}/services/gitea-runners/registration-token";
|
tokenFile = "/run/secrets/gitea-runners/registration-token";
|
||||||
hostPackages = with pkgs; [
|
hostPackages = with pkgs; [
|
||||||
nixos-rebuild
|
bash
|
||||||
treefmt
|
coreutils
|
||||||
|
curl
|
||||||
|
gawk
|
||||||
|
gitMinimal
|
||||||
|
gnused
|
||||||
my_python
|
my_python
|
||||||
|
nix
|
||||||
|
nixfmt
|
||||||
|
nixos-rebuild
|
||||||
|
nodejs
|
||||||
|
treefmt
|
||||||
|
wget
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
systemd.services."gitea-runner-${utils.escapeSystemdPath name}" = {
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = mkForce false;
|
||||||
|
User = mkForce runnerUsername;
|
||||||
|
Group = mkForce runnerUsername;
|
||||||
|
};
|
||||||
|
};
|
||||||
system.stateVersion = "24.05";
|
system.stateVersion = "24.05";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
) cfg.containers;
|
) cfg.containers;
|
||||||
|
|
||||||
|
systemd.services = builtins.listToAttrs (
|
||||||
|
map (name: {
|
||||||
|
name = "container@${name}";
|
||||||
|
value = {
|
||||||
|
requires = [ "gitea.service" ];
|
||||||
|
after = [ "gitea.service" ];
|
||||||
|
};
|
||||||
|
}) (builtins.attrNames (filterAttrs (_: c: c.enable) cfg.containers))
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
vars = import ../vars.nix;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${vars.docker_configs}/camofox-browser 0750 root root - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
containers.camofox-browser = {
|
||||||
|
autoStart = true;
|
||||||
|
privateNetwork = false;
|
||||||
|
bindMounts = {
|
||||||
|
camofox-browser = {
|
||||||
|
hostPath = "${vars.docker_configs}/camofox-browser";
|
||||||
|
mountPoint = "/var/lib/camofox-browser";
|
||||||
|
isReadOnly = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
networking.hostName = "camofox-browser";
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
ffmpeg
|
||||||
|
git
|
||||||
|
nodejs
|
||||||
|
python3Packages.yt-dlp
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.services.camofox-browser = {
|
||||||
|
description = "Camofox browser server";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
environment = {
|
||||||
|
CAMOFOX_HOST = "127.0.0.1";
|
||||||
|
CAMOFOX_PORT = "9377";
|
||||||
|
HOME = "/var/lib/camofox-browser";
|
||||||
|
};
|
||||||
|
path = with pkgs; [
|
||||||
|
bash
|
||||||
|
coreutils
|
||||||
|
git
|
||||||
|
nodejs
|
||||||
|
];
|
||||||
|
serviceConfig = {
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = "5s";
|
||||||
|
WorkingDirectory = "/var/lib/camofox-browser";
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
app_dir=/var/lib/camofox-browser/app
|
||||||
|
|
||||||
|
if [ ! -d "$app_dir/.git" ]; then
|
||||||
|
git clone --depth 1 https://github.com/jo-inc/camofox-browser "$app_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$app_dir"
|
||||||
|
|
||||||
|
if [ ! -d node_modules ]; then
|
||||||
|
npm install
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec npm start
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
system.stateVersion = lib.mkDefault "24.05";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
{
|
|
||||||
pkgs,
|
|
||||||
inputs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
vars = import ../vars.nix;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
users = {
|
|
||||||
users.signalbot = {
|
|
||||||
isSystemUser = true;
|
|
||||||
group = "signalbot";
|
|
||||||
};
|
|
||||||
groups.signalbot = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.signal-bot = {
|
|
||||||
description = "Signal command and control bot";
|
|
||||||
after = [
|
|
||||||
"network.target"
|
|
||||||
"podman-signal_cli_rest_api.service"
|
|
||||||
];
|
|
||||||
wants = [ "podman-signal_cli_rest_api.service" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
|
|
||||||
environment = {
|
|
||||||
PYTHONPATH = "${inputs.self}";
|
|
||||||
SIGNALBOT_DB = "signalbot";
|
|
||||||
SIGNALBOT_USER = "signalbot";
|
|
||||||
SIGNALBOT_HOST = "/run/postgresql";
|
|
||||||
SIGNALBOT_PORT = "5432";
|
|
||||||
};
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "simple";
|
|
||||||
WorkingDirectory = "${inputs.self}";
|
|
||||||
User = "signalbot";
|
|
||||||
Group = "signalbot";
|
|
||||||
EnvironmentFile = "${vars.secrets}/services/signal-bot";
|
|
||||||
ExecStart = "${pkgs.my_python}/bin/python -m python.signal_bot.main";
|
|
||||||
StateDirectory = "signal-bot";
|
|
||||||
Restart = "on-failure";
|
|
||||||
RestartSec = "10s";
|
|
||||||
StandardOutput = "journal";
|
|
||||||
StandardError = "journal";
|
|
||||||
NoNewPrivileges = true;
|
|
||||||
ProtectSystem = "strict";
|
|
||||||
ProtectHome = "read-only";
|
|
||||||
PrivateTmp = true;
|
|
||||||
ReadWritePaths = [ "/var/lib/signal-bot" ];
|
|
||||||
ReadOnlyPaths = [
|
|
||||||
"${inputs.self}"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -28,7 +28,6 @@ frontend ContentSwitching
|
|||||||
|
|
||||||
# ACME challenge routing (must be first)
|
# ACME challenge routing (must be first)
|
||||||
acl is_acme path_beg /.well-known/acme-challenge/
|
acl is_acme path_beg /.well-known/acme-challenge/
|
||||||
use_backend acme_challenge if is_acme
|
|
||||||
|
|
||||||
# tmmworkshop.com
|
# tmmworkshop.com
|
||||||
acl host_audiobookshelf hdr(host) -i audiobookshelf.tmmworkshop.com
|
acl host_audiobookshelf hdr(host) -i audiobookshelf.tmmworkshop.com
|
||||||
@@ -45,6 +44,7 @@ frontend ContentSwitching
|
|||||||
# Redirect all HTTP to HTTPS unless on the allow list or ACME challenge
|
# Redirect all HTTP to HTTPS unless on the allow list or ACME challenge
|
||||||
http-request redirect scheme https code 301 if !{ ssl_fc } !allow_http !is_acme
|
http-request redirect scheme https code 301 if !{ ssl_fc } !allow_http !is_acme
|
||||||
|
|
||||||
|
use_backend acme_challenge if is_acme
|
||||||
use_backend audiobookshelf_nodes if host_audiobookshelf
|
use_backend audiobookshelf_nodes if host_audiobookshelf
|
||||||
use_backend cache_nodes if host_cache
|
use_backend cache_nodes if host_cache
|
||||||
use_backend jellyfin if host_jellyfin
|
use_backend jellyfin if host_jellyfin
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
"${inputs.self}/common/optional/yubikey.nix"
|
"${inputs.self}/common/optional/yubikey.nix"
|
||||||
"${inputs.self}/common/optional/zerotier.nix"
|
"${inputs.self}/common/optional/zerotier.nix"
|
||||||
./hardware.nix
|
./hardware.nix
|
||||||
./llms.nix
|
|
||||||
./open_webui.nix
|
./open_webui.nix
|
||||||
./qmk.nix
|
./qmk.nix
|
||||||
./sunshine.nix
|
./sunshine.nix
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
services.ollama = {
|
|
||||||
user = "ollama";
|
|
||||||
enable = true;
|
|
||||||
host = "127.0.0.1";
|
|
||||||
syncModels = true;
|
|
||||||
loadModels = [
|
|
||||||
"deepscaler:1.5b"
|
|
||||||
"deepseek-r1:8b"
|
|
||||||
"gemma3:12b"
|
|
||||||
"lfm2:24b"
|
|
||||||
"nemotron-3-nano:4b"
|
|
||||||
"qwen3:14b"
|
|
||||||
"qwen3.5:27b"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
systemd.services = {
|
|
||||||
ollama.serviceConfig = {
|
|
||||||
Nice = 19;
|
|
||||||
IOSchedulingPriority = 7;
|
|
||||||
};
|
|
||||||
ollama-model-loader.serviceConfig = {
|
|
||||||
Nice = 19;
|
|
||||||
CPUWeight = 50;
|
|
||||||
IOSchedulingClass = "idle";
|
|
||||||
IOSchedulingPriority = 7;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user