heather: add JupyterLab systemd service (jupyter.iscg.dev, localhost:8890, resource limits, caddy basicauth)

This commit is contained in:
mikl 2026-09-11 03:12:01 +03:00
commit d4153028d6
3 changed files with 78 additions and 0 deletions

View file

@ -113,6 +113,16 @@ Allow: /" 200
reverse_proxy 127.0.0.1:6767
'';
# JupyterLab (ботать аналитику с iPad). Два слоя защиты:
# Caddy basicauth (пароль в pass iscg.dev/jupyter/basicauth)
# + Jupyter token внутри. Лимиты памяти/CPU в jupyter.nix.
"jupyter.iscg.dev".extraConfig = ''
basicauth {
mikl $2a$14$u4jCpuLFeymewgx1uuGRs.6.L1JYf7vMtgwhU/Wvw5iuXJflynvSu
}
reverse_proxy 127.0.0.1:8890
'';;
# File explorer (directory listing) для раздачи файлов через браузер.
# browse включает Caddy's built-in directory listing. Корень /var/www/pub.
# Без auth — класть только публичные файлы.

View file

@ -21,6 +21,7 @@
./syncthing.nix # sync + relay
./tuwunel-admin.nix # matrix admin web UI (systemd, статический бинарник)
./paseo.nix # paseo daemon (web UI для CLI-агентов, systemd + npm global)
./jupyter.nix # JupyterLab (systemd, localhost:8890, лимиты)
./mesh-clients.nix # Sol-style client pool (wg-clients1)
./mesh-egress.nix # Sol-style selected-destination egress policy
];

67
hosts/heather/jupyter.nix Normal file
View file

@ -0,0 +1,67 @@
# heather — JupyterLab (systemd, не контейнер).
#
# Среда собирается uv'ом в /var/lib/jupyter-env (venv с jupyterlab + LSP +
# SQL + темы). Устанавливается однократно вручную (nix run nixpkgs#uv), сама
# установка не в nix store — пакеты летят из PyPI, пинить нечего.
#
# Безопасность: слушает только 127.0.0.1:8890, наружу через Caddy
# (jupyter.iscg.dev). Caddy basicauth (см. caddy.nix jupyterBasicAuth) +
# Jupyter token (пасс iscg.dev/jupyter/token, env-файл jupyter-secrets).
#
# Лимиты: MemoryMax 2G, CPUQuota 50% — ноутбук не сможет съесть сервер.
{ config, pkgs, lib, ... }:
let
jupyterEnv = "/var/lib/jupyter-env";
jupyterBin = "${jupyterEnv}/bin/jupyter-lab";
in {
# JupyterLab управляет собственным env-файлом? нет — используем
# EnvironmentFile с токеном: /var/lib/jupyter-secrets/jupyter.env
# (JUPYTER_TOKEN=..., mikl:users 0600)
systemd.services.jupyterlab = {
description = "JupyterLab notebook server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
path = with pkgs; [ bash ];
environment = {
HOME = "/home/mikl";
PATH = "${jupyterEnv}/bin:/run/current-system/sw/bin";
};
serviceConfig = {
Type = "simple";
User = "mikl";
Group = "users";
EnvironmentFile = "/var/lib/jupyter-secrets/jupyter.env";
ExecStart = ''
${jupyterBin} \
--no-browser \
--ip=127.0.0.1 \
--port=8890 \
--ServerApp.token="$JUPYTER_TOKEN" \
--ServerApp.root_dir=/srv/jupyter \
--ServerApp.password_required=True
'';
Restart = "on-failure";
RestartSec = 5;
# --- лимиты ресурсов ---
MemoryMax = "2G";
MemoryHigh = "1536M";
CPUQuota = "50%";
TasksMax = 256;
# --- sandbox (лёгкий, т.к. ноутбукам нужен доступ к ~/srv) ---
NoNewPrivileges = true;
PrivateTmp = true;
ProtectSystem = "full";
ReadWritePaths = [ "/srv/jupyter" "/home/mikl" ];
};
};
# Каталог ноутбуков и env-директория
systemd.tmpfiles.rules = [
"d /srv/jupyter 0755 mikl users -"
"d /var/lib/jupyter-secrets 0750 mikl users -"
"d /var/lib/jupyter-env 0755 mikl users -"
];
}