refactor(viridian): migrate service data to dedicated BTRFS subvolumes

Migrate from path-based persistence (/persist/var/lib/*) to dedicated
BTRFS subvolumes for better data isolation and snapshot capabilities.

- Move valuable user-facing services to /srv/* with srv-* subvolumes:
  - forgejo: git repositories and database
  - opengist: paste data
  - minecraft: game world data
  - lighttpd: static web content
  - containers: OCI container volumes

- Update home directory to use hm-sajenim subvolume on viridian disk
- Remove jupyterhub service (no longer in use)
- Update borgbackup paths to match new service locations
- Follow upstream service defaults where possible for maintainability

Services kept on /persist (disposable state):
- traefik, crowdsec, murmur
This commit is contained in:
♥ Minnie ♥ 2025-10-06 13:07:46 +08:00
parent 28ba8186bb
commit b0bfb37d3c
Signed by: jasmine
GPG key ID: 8563E358D4E8040E
10 changed files with 64 additions and 94 deletions

View file

@ -4,7 +4,9 @@
pkgs,
config,
...
}: {
}: let
hostname = config.networking.hostName;
in {
imports = [
inputs.home-manager.nixosModules.home-manager
];
@ -29,8 +31,8 @@
};
fileSystems."/home/sajenim" = {
device = "/dev/disk/by-label/data";
device = "/dev/disk/by-label/${hostname}";
fsType = "btrfs";
options = ["subvol=sajenim" "compress=zstd"];
options = ["subvol=hm-sajenim" "compress=zstd"];
};
}

View file

@ -52,17 +52,6 @@
fsType = "vfat";
};
fileSystems."/srv/multimedia" = {
device = "/dev/disk/by-label/multimedia";
fsType = "ext4";
};
fileSystems."/srv/multimedia/containers" = {
device = "/dev/disk/by-label/data";
fsType = "btrfs";
options = ["subvol=containers" "compress=zstd"];
};
swapDevices = [
{
device = "/swap/swapfile";

View file

@ -1,4 +1,6 @@
{...}: {
{config, ...}: let
hostname = config.networking.hostName;
in {
imports = [
./jellyfin
./lidarr
@ -7,4 +9,17 @@
./radarr
./sonarr
];
fileSystems = {
"/srv/multimedia" = {
device = "/dev/disk/by-label/multimedia";
fsType = "ext4";
};
"/srv/multimedia/containers" = {
device = "/dev/disk/by-label/${hostname}";
fsType = "btrfs";
options = ["subvol=srv-containers" "compress=zstd"];
};
};
}

View file

@ -6,14 +6,13 @@
services.borgbackup.jobs."borgbase" = {
paths = [
# Websites
"/srv/www/sajenim.dev"
"/srv/lighttpd/sajenim.dev"
# Services
"/var/lib/crowdsec"
"/var/lib/forgejo"
"/var/lib/jupyterhub"
"/var/lib/minecraft"
"/var/lib/opengist"
"/var/lib/traefik"
"/srv/minecraft"
# Multimedia
"/srv/multimedia/containers/jellyfin"
"/srv/multimedia/containers/lidarr"

View file

@ -4,7 +4,6 @@
./crowdsec
./forgejo
./inspircd
./jupyterhub
./lighttpd
./minecraft
./mpd

View file

@ -1,7 +1,9 @@
{config, ...}: {
{config, ...}: let
hostname = config.networking.hostName;
in {
services.forgejo = {
enable = true;
stateDir = "/var/lib/forgejo";
stateDir = "/srv/forgejo";
settings = {
server = {
DOMAIN = "git.sajenim.dev";
@ -32,13 +34,12 @@
];
};
environment.persistence."/persist" = {
directories = [
{
directory = "/var/lib/forgejo";
user = "forgejo";
group = "forgejo";
}
fileSystems."/srv/forgejo" = {
device = "/dev/disk/by-label/${hostname}";
fsType = "btrfs";
options = [
"subvol=srv-forgejo"
"compress=zstd"
];
};
}

View file

@ -1,31 +0,0 @@
{config, ...}: {
services.jupyterhub = {
enable = true;
port = 9475;
extraConfig = ''
c.Authenticator.allowed_users = {'sajenim'}
'';
};
services.traefik.dynamicConfigOptions.http.routers = {
jupyter = {
rule = "Host(`jupyter.home.arpa`)";
entryPoints = [
"websecure"
];
service = "jupyter";
};
};
services.traefik.dynamicConfigOptions.http.services = {
jupyter.loadBalancer.servers = [
{url = "http://127.0.0.1:${toString config.services.jupyterhub.port}";}
];
};
environment.persistence."/persist" = {
directories = [
"/var/lib/jupyterhub"
];
};
}

View file

@ -1,8 +1,10 @@
{config, ...}: {
{config, ...}: let
hostname = config.networking.hostName;
in {
services.lighttpd = {
enable = true;
port = 5624;
document-root = "/srv/www/sajenim.dev";
document-root = "/srv/lighttpd/sajenim.dev";
};
services.traefik.dynamicConfigOptions.http.routers = {
@ -21,13 +23,12 @@
];
};
environment.persistence."/persist" = {
directories = [
{
directory = "/srv/www";
user = "lighttpd";
group = "lighttpd";
}
fileSystems."/srv/lighttpd" = {
device = "/dev/disk/by-label/${hostname}";
fsType = "btrfs";
options = [
"subvol=srv-lighttpd"
"compress=zstd"
];
};
}

View file

@ -5,6 +5,7 @@
config,
...
}: let
hostname = config.networking.hostName;
modpack = pkgs.fetchPackwizModpack rec {
version = "9083262";
url = "https://raw.githubusercontent.com/sajenim/minecraft-modpack/${version}/pack.toml";
@ -71,9 +72,6 @@ in {
};
};
# Each server will be under a subdirectory named after the server name.
dataDir = "/var/lib/minecraft";
# Open firewall for all servers.
openFirewall = true;
@ -106,14 +104,12 @@ in {
};
};
# Enable persistence for the data directory.
environment.persistence."/persist" = {
directories = [
{
directory = "/var/lib/minecraft";
user = "minecraft";
group = "minecraft";
}
fileSystems."/srv/minecraft" = {
device = "/dev/disk/by-label/${hostname}";
fsType = "btrfs";
options = [
"subvol=srv-minecraft"
"compress=zstd"
];
};
}

View file

@ -1,4 +1,5 @@
{...}: let
{config, ...}: let
hostname = config.networking.hostName;
port = "6157";
in {
# OpenGist service configuration
@ -9,7 +10,7 @@ in {
"${port}:${port}"
];
volumes = [
"/var/lib/opengist:/opengist"
"/srv/opengist:/opengist"
];
# Environment variables for OpenGist
environment = {
@ -43,20 +44,18 @@ in {
};
};
# Persist data for OpenGist
environment.persistence."/persist" = {
directories = [
{
directory = "/var/lib/opengist";
user = "sajenim";
group = "users";
}
];
};
# Activation script to create symlinks for custom assets
system.activationScripts.opengist-symlink = ''
cp ${toString ./assets/pikachu.png} /var/lib/opengist/custom/pikachu.png
cp ${toString ./assets/pokeball.png} /var/lib/opengist/custom/pokeball.png
cp ${toString ./assets/pikachu.png} /srv/opengist/custom/pikachu.png
cp ${toString ./assets/pokeball.png} /srv/opengist/custom/pokeball.png
'';
fileSystems."/srv/opengist" = {
device = "/dev/disk/by-label/${hostname}";
fsType = "btrfs";
options = [
"subvol=srv-opengist"
"compress=zstd"
];
};
}