124 lines
5.5 KiB
Nix
124 lines
5.5 KiB
Nix
# heather — сервер на Yandex Cloud (NixOS 26.11).
|
||
# https://git.iscg.dev/mikl/nix-config
|
||
#
|
||
# Перенесено из muscari (переименование 2026-07-11).
|
||
# VM на Yandex Cloud, 2 vCPU / 8 GB / 64 GB SSD (network-ssd), Legacy BIOS.
|
||
# Образ NixOS собирается как qcow2 (см. ./image.nix, make-disk-image.nix) и
|
||
# заливается как boot disk в YC. НЕ через nixos-anywhere — kexec на YC хрупкий.
|
||
# См. memory/yandex-nixos-qcow2.md.
|
||
#
|
||
# Архитектура (2026-07-12, заменила k3s):
|
||
# Caddy (edge, TLS) → host-сервисы (syncthing) + docker-контейнеры (arion)
|
||
# Cilium/k3s выключены — overhead 1.3 GB был неоправдан для single-node.
|
||
# См. ./docker.nix, ./caddy.nix, ./syncthing.nix, ./arion-compose.nix.
|
||
|
||
{ config, pkgs, lib, ... }:
|
||
{
|
||
imports = [
|
||
./image.nix # YC guest profile + qcow2 build target
|
||
./docker.nix # docker + arion CLI (контейнеры)
|
||
./caddy.nix # edge proxy, TLS, роутинг по доменам
|
||
./syncthing.nix # sync + relay
|
||
./tuwunel-admin.nix # matrix admin web UI (systemd, статический бинарник)
|
||
./paseo.nix # paseo daemon (web UI для CLI-агентов, systemd + npm global)
|
||
./nick.nix # Nick timer prototype (systemd, localhost:8787)
|
||
./jupyter.nix # JupyterLab (systemd, localhost:8890, лимиты)
|
||
./astrnet.nix # AstrNet (Sol): two WireGuard legs, FRR/BGP, ingress guard
|
||
./minecraft-api.nix # mesh-only typed Minecraft API, isolated DynamicUser
|
||
];
|
||
|
||
# Heather has 8 GiB RAM and runs several containers. Keep a 4 GiB
|
||
# swapfile so a transient application spike does not take down the host.
|
||
swapDevices = [
|
||
{
|
||
device = "/var/swapfile";
|
||
size = 4096;
|
||
}
|
||
];
|
||
|
||
# WireGuard tooling is also used by AstrNet. Keep this package and the
|
||
# diagnostics tools available in non-login SSH sessions.
|
||
environment.systemPackages = with pkgs; [
|
||
wireguard-tools
|
||
tmux
|
||
jq
|
||
wget
|
||
python3
|
||
];
|
||
|
||
# Static public pages used by the personal gcalcli OAuth application.
|
||
environment.etc = {
|
||
"gcalcli-site/index.html".source = ./gcalcli-site/index.html;
|
||
"gcalcli-site/privacy.html".source = ./gcalcli-site/privacy.html;
|
||
"gcalcli-site/terms.html".source = ./gcalcli-site/terms.html;
|
||
"gcalcli-site/style.css".source = ./gcalcli-site/style.css;
|
||
};
|
||
|
||
# Docker requires forwarding; AstrNet ingress is blocked by astrnet-guard.
|
||
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
|
||
|
||
# Arion-проект как systemd-сервис: arion-compose.nix → docker-compose → up.
|
||
# NB: settings — это модуль с imports, НЕ `import ./arion-compose.nix`.
|
||
virtualisation.arion.backend = "docker";
|
||
virtualisation.arion.projects.heather = {
|
||
serviceName = "heather"; # systemd: heather.service
|
||
settings = {
|
||
imports = [ ./arion-compose.nix ];
|
||
};
|
||
};
|
||
# Applying the NixOS configuration must not run `arion up` for *all* services:
|
||
# in particular it would start the intentionally stopped Teable stack and
|
||
# touch production Matrix. After changing an image, update that one service
|
||
# explicitly with `arion --prebuilt-file <active-unit-compose> up -d --no-deps SERVICE`.
|
||
systemd.services.heather.restartIfChanged = false;
|
||
|
||
networking = {
|
||
hostName = "heather";
|
||
# Firewall выключен в ./image.nix (полагаемся на YC Security Groups).
|
||
# Порты тут только для документации — реально открывает YC SG.
|
||
firewall.allowedTCPPorts = [
|
||
22 # SSH
|
||
80 # HTTP (Caddy → redirect to HTTPS)
|
||
443 # HTTPS (Caddy, TLS termination)
|
||
2222 # forgejo git ssh (публично)
|
||
22000 # syncthing sync
|
||
22067 # strelaysrv (relay)
|
||
22070 # strelaysrv (status)
|
||
3478 # coturn TURN (tcp+udp)
|
||
8443 # xray VLESS+Reality (публичный прокси)
|
||
];
|
||
firewall.allowedUDPPorts = [
|
||
22000 # syncthing sync (QUIC)
|
||
10000 # jitsi jvb (RTP media)
|
||
3478 # coturn TURN
|
||
];
|
||
# coturn RTP relay range
|
||
firewall.allowedUDPPortRanges = [
|
||
{ from = 49152; to = 65535; } # coturn RTP relay
|
||
];
|
||
};
|
||
# useDHCP задаёт ./image.nix (mkDefault) — облачный профиль.
|
||
|
||
# SSH ключи для mikl: forgejo .keys endpoint с sha256-pinning.
|
||
# Poppy-ключ (этот ноутбук) лежит там последней строкой.
|
||
users.users.mikl.openssh.authorizedKeys.keyFiles = [
|
||
(pkgs.fetchurl {
|
||
url = "https://git.iscg.dev/mikl.keys";
|
||
sha256 = "sha256-Omc/3NJn0nM8SWeF33trFwOAVgSX0fXB5dfEakcRoTA=";
|
||
})
|
||
];
|
||
|
||
# Rescue-канал: root с тем же poppy-ключом. PermitRootLogin = prohibit-password
|
||
# (см. image.nix) пускает root только по ключу — парольного root-логина нет.
|
||
# Нужен, чтобы не оказаться запертым без root, если passwordless sudo сломается
|
||
# (как произошло на первом образе heather): ssh root@heather и nixos-rebuild.
|
||
users.users.root.openssh.authorizedKeys.keyFiles = [
|
||
(pkgs.fetchurl {
|
||
url = "https://git.iscg.dev/mikl.keys";
|
||
sha256 = "sha256-Omc/3NJn0nM8SWeF33trFwOAVgSX0fXB5dfEakcRoTA=";
|
||
})
|
||
];
|
||
|
||
# После первой установки 25.11 не трогаем (NixOS convention)
|
||
system.stateVersion = "25.11";
|
||
}
|