rename nodes and add runner for gitea instance

This commit is contained in:
shobu
2025-11-11 21:05:47 +01:00
parent c610ce80bc
commit 542034054c
34 changed files with 69 additions and 24 deletions

1
hosts/sin/.envrc Normal file
View File

@@ -0,0 +1 @@
use flake

106
hosts/sin/configuration.nix Normal file
View File

@@ -0,0 +1,106 @@
{
modulesPath,
lib,
pkgs,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
(modulesPath + "/profiles/qemu-guest.nix")
./luks-btrfs-raid.nix
./jellyfin.nix
./transmission.nix
./homepage.nix
./glances.nix
./secrets.nix
./coredns
./copyparty.nix
];
boot.initrd.kernelModules = [ "usb_storage" ];
boot.loader.grub = {
# devices = [ ];
efiSupport = true;
efiInstallAsRemovable = true;
};
networking = {
hostName = "sin";
nameservers = [ "10.0.0.4" ];
dhcpcd.extraConfig = "nohook resolv.conf";
firewall = {
allowedTCPPorts = [
8000
8001
3000 # gitea
53
];
allowedUDPPorts = [ 53 ];
};
};
time.timeZone = "Europe/Paris";
nix.settings.experimental-features = [ "nix-command" "flakes" ];
nixpkgs.config.allowUnfree = true;
users.users = {
zimablade = {
isNormalUser = true;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKsu+4S+BHmypQTq2IR9y+ihvbF7sXbBznKtIjVAeHJ1 shobu@nixos" ];
};
shobu = {
isNormalUser = true;
openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKsu+4S+BHmypQTq2IR9y+ihvbF7sXbBznKtIjVAeHJ1 shobu@nixos" ];
};
};
users.users.root.openssh.authorizedKeys.keys = [
# change this to your ssh key
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKsu+4S+BHmypQTq2IR9y+ihvbF7sXbBznKtIjVAeHJ1 shobu@nixos"
];
environment.systemPackages = map lib.lowPrio [
pkgs.curl
pkgs.gitMinimal
] ++ (with pkgs; [
helix
httpie
btop
tmux
# firefox
]);
services = {
openssh = {
enable = true;
ports = [ 22 ];
};
# xserver = {
# enable = true;
# desktopManager = {
# xterm.enable = false;
# xfce.enable = true;
# };
# };
blueman.enable = true;
};
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
};
system.stateVersion = "24.11";
}

31
hosts/sin/copyparty.nix Normal file
View File

@@ -0,0 +1,31 @@
{inputs, pkgs, ...}: {
imports = [ inputs.copyparty.nixosModules.default ];
nixpkgs.overlays = [ inputs.copyparty.overlays.default ];
environment.systemPackages = [ pkgs.copyparty ];
services.copyparty = {
enable = true;
settings = {
p = [ 8086 ];
e2dsa = true;
e2ts = true;
z = true;
qr = true;
xff-src = "lan";
http-only = true;
og = true;
shr = "/shares";
};
volumes = {
"/media" = {
path = "/mnt/mediacenter/media";
access = {
r = "*";
};
};
};
};
networking.firewall.allowedTCPPorts = [ 8086 ];
}

View File

@@ -0,0 +1,6 @@
$ORIGIN homelab.local.
@ IN SOA dns.homelab.local. shobu_serhao.proton.me. 2502011720 7200 3600 1209600 3600
dns IN A 10.0.0.5
thea IN A 10.0.0.5
sin IN A 10.0.0.4

View File

@@ -0,0 +1,20 @@
{...}: {
services.coredns = {
enable = true;
config = ''
homelab.local {
log
errors
cache
file ${./db.homelab.local}
}
. {
forward . 8.8.8.8
log
errors
cache
}
'';
};
}

161
hosts/sin/flake.lock generated Normal file
View File

@@ -0,0 +1,161 @@
{
"nodes": {
"agenix": {
"inputs": {
"darwin": "darwin",
"home-manager": "home-manager",
"nixpkgs": "nixpkgs",
"systems": "systems"
},
"locked": {
"lastModified": 1736955230,
"narHash": "sha256-uenf8fv2eG5bKM8C/UvFaiJMZ4IpUFaQxk9OH5t/1gA=",
"owner": "ryantm",
"repo": "agenix",
"rev": "e600439ec4c273cf11e06fe4d9d906fb98fa097c",
"type": "github"
},
"original": {
"owner": "ryantm",
"repo": "agenix",
"type": "github"
}
},
"darwin": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1700795494,
"narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d",
"type": "github"
},
"original": {
"owner": "lnl7",
"ref": "master",
"repo": "nix-darwin",
"type": "github"
}
},
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1738765162,
"narHash": "sha256-3Z40qHaFScWUCVQrGc4Y+RdoPsh1R/wIh+AN4cTXP0I=",
"owner": "nix-community",
"repo": "disko",
"rev": "ff3568858c54bd306e9e1f2886f0f781df307dff",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1703113217,
"narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1703013332,
"narHash": "sha256-+tFNwMvlXLbJZXiMHqYq77z/RfmpfpiI3yjL6o/Zo9M=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "54aac082a4d9bb5bbc5c4e899603abfb76a3f6d6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1738843498,
"narHash": "sha256-7x+Q4xgFj9UxZZO9aUDCR8h4vyYut4zPUvfj3i+jBHE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f5a32fa27df91dfc4b762671a0e0a859a8a0058f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"disko": "disko",
"nixpkgs": "nixpkgs_2",
"unstable": "unstable"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"unstable": {
"locked": {
"lastModified": 1740367490,
"narHash": "sha256-WGaHVAjcrv+Cun7zPlI41SerRtfknGQap281+AakSAw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "0196c0175e9191c474c26ab5548db27ef5d34b05",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

54
hosts/sin/flake.nix Normal file
View File

@@ -0,0 +1,54 @@
{
description = "An empty flake template that you can adapt to your own environment";
# Flake inputs
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
inputs.disko.url = "github:nix-community/disko";
inputs.disko.inputs.nixpkgs.follows = "nixpkgs";
inputs = {
# projects
unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
agenix.url = "github:ryantm/agenix";
};
# Flake outputs
outputs = inputs@{ self, nixpkgs, disko, unstable, agenix, ... }:
let
# The systems supported for this flake
supportedSystems = [
"x86_64-linux" # 64-bit Intel/AMD Linux
];
# Helper to provide system-specific attributes
forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
pkgs = import nixpkgs { inherit system; };
});
in
{
nixosConfigurations.zimablade = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
disko.nixosModules.disko
agenix.nixosModules.default
./configuration.nix
./hardware-configuration.nix
];
specialArgs = {
inherit inputs;
};
};
devShells = forEachSupportedSystem ({ pkgs }: {
default = pkgs.mkShell {
# The Nix packages provided in the environment
# Add any you need here
packages = with pkgs; [ pkgs.disko nixos-anywhere ];
# Add any shell logic you want executed any time the environment is activated
shellHook = '''';
};
});
};
}

8
hosts/sin/glances.nix Normal file
View File

@@ -0,0 +1,8 @@
{...}: {
services.glances = {
enable = true;
openFirewall = true;
# TODO Change secrets
extraArgs = [ "--webserver" ];
};
}

View File

@@ -0,0 +1,26 @@
# 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, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "usb_storage" "usbhid" "sd_mod" "sdhci_pci" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp0s21f0u3u4.useDHCP = lib.mkDefault true;
# networking.interfaces.enp2s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

231
hosts/sin/homepage.nix Normal file
View File

@@ -0,0 +1,231 @@
{inputs, pkgs, ...}: {
services.homepage-dashboard = {
enable = true;
openFirewall = true;
allowedHosts = "dashboard.shobu.fr";
settings = {
title = "Shobu's homelab dashboard";
description = "a dashboard of free and wesome bullshit";
startUrl = "https://dashboard.shobu.fr";
base = "https://dashboard.shobu.fr";
headerStyle = "boxed";
providers = {
"finnhub" = "cuvq5e9r01qub8tv03g0cuvq5e9r01qub8tv03gg";
};
layout = [
{"resources" = {};}
{
"about me stuff" = {
tab = "Public";
};
}
{
"tools" = {
tab = "Public";
};
}
{
"gayming" = {
tab = "Public";
};
}
{
"mediacenter" = {
tab = "Mediacenter";
header = false;
};
}
];
};
widgets = [
{
greeting = {
text = "Welcome on my services and links dashboard, make yourself home.";
};
}
{
datetime = {
format = {
dateStyle = "short";
};
};
}
{
glances = {
url = "https://zimablade-admin.shobu.fr";
user = "shobu";
password = "shobu";
version = 4;
disk = [
"/"
"/mnt/fs"
];
expanded = true;
};
}
];
bookmarks = [
{
"tools" = [
{
"bddtrans" = [
{
icon = "https://bddtrans.shobu.fr/favicon.ico";
href = "https://bddtrans.shobu.fr";
}
];
}
];
}
{
"about me stuff" = [
{
"shobu.fr" = [
{
icon = "https://shobu.fr/favicon.ico";
href = "https://shobu.fr";
}
];
}
{
"gitlab" = [
{
icon = "gitlab.png";
href = "https://gitlab.com/shobu13";
}
];
}
];
}
];
services = [
{
"gayming" = [
{
"testing grounds" = {
description = "a lightweight modded minecraft server";
href = "https://modrinth.com/modpack/testing-grounds";
widget = {
type = "minecraft";
url = "udp://minecraft.shobu.fr:25565";
};
};
}
];
}
{
"mediacenter" = [
{
"users" = [
{
"jellyfin" = {
icon = "jellyfin.png";
href = "https://jellyfin.shobu.fr";
description = "Movies & TV shows";
widget = {
type = "jellyfin";
url = "https://jellyfin.shobu.fr";
key = "af4888d2c6594473be63e8299355d048";
enableBlocks = true;
enableNowPlaying = false;
};
};
}
{
"jellyseerr" = {
icon = "jellyseerr.png";
href = "https://jellyseerr.shobu.fr";
description = "Request movies and shows";
widget = {
type = "jellyseerr";
url = "https://jellyseerr.shobu.fr";
key = "MTczNzkyNzMxMzgwODk4N2FlZWJkLTQ0N2QtNGU0MS1iOWE1LTJmZmE3OTI4ZGQ5OQ==";
};
};
}
{
"calendar" = {
widget = {
type = "calendar";
view = "agenda";
showTime = true;
integrations = [
{
type = "sonarr";
service_group = "administration";
service_name = "sonarr";
}
{
type = "radarr";
service_group = "administration";
service_name = "radarr";
}
{
type = "lidarr";
service_group = "administration";
service_name = "lidarr";
}
];
};
};
}
];
}
{
"administration" = [
{
"radarr" = {
icon = "radarr.png";
href = "https://radarr.shobu.fr";
widget = {
type = "radarr";
url = "https://radarr.shobu.fr";
key = "13474b968893451fb5aa378457dc84a2";
};
};
}
{
"sonarr" = {
icon = "sonarr.png";
href = "https://sonarr.shobu.fr";
widget = {
type = "sonarr";
url = "https://sonarr.shobu.fr";
key = "f194704f6dce4072928d857d49c1f185";
};
};
}
{
"lidarr" = {
icon = "lidarr.png";
href = "https://lidarr.shobu.fr";
widget = {
type = "lidarr";
url = "https://lidarr.shobu.fr";
key = "deff3fc5052844e7b37dfe439a91f8bc";
};
};
}
{
"transmission" = {
icon = "transmission.png";
href = "https://transmission.shobu.fr";
widget = {
type = "transmission";
url = "https://transmission.shobu.fr";
};
};
}
];
}
];
}
];
};
}

83
hosts/sin/jellyfin.nix Normal file
View File

@@ -0,0 +1,83 @@
{pkgs, inputs, ...}: let
unstable = import inputs.unstable { system = pkgs.system; };
in {
nixpkgs.config.packageOverrides = pkgs: {
vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
};
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver
intel-vaapi-driver
vaapiVdpau
intel-compute-runtime # OpenCL filter support (hardware tonemapping and subtitle burn-in)
vpl-gpu-rt # QSV on 11th gen or newer
intel-media-sdk # QSV up to 11th gen
];
};
nixpkgs.config.permittedInsecurePackages = [
"dotnet-sdk-6.0.428"
"aspnetcore-runtime-6.0.36"
];
users.users."starr" = {
isSystemUser = true;
group = "starr";
extraGroups = [ "jellyfin" ];
};
users.users.sonarr.extraGroups = ["jellyfin" "radarr" "transmission" "starr"];
users.users.radarr.extraGroups = ["jellyfin" "sonarr" "transmission" "starr"];
users.users.bazarr.extraGroups = ["jellyfin" "sonarr" "transmission" "starr" "radarr"];
users.users.lidarr.extraGroups = ["jellyfin" "starr" "transmission"];
users.users.shobu.extraGroups = [ "jellyfin" "starr" "transmission" "radarr" "sonarr" ];
users.groups = {
starr = {};
};
services = {
jellyfin = {
enable = true;
openFirewall = true;
};
sonarr = {
enable = true;
openFirewall = true;
group = "starr";
};
radarr = {
enable = true;
openFirewall = true;
group = "starr";
};
prowlarr = {
enable = true;
openFirewall = true;
};
bazarr = {
enable = true;
openFirewall = true;
};
lidarr = {
enable = true;
openFirewall = true;
package = unstable.lidarr;
};
jellyseerr = {
enable = true;
openFirewall = true;
};
};
environment.systemPackages = [
pkgs.jellyfin
pkgs.jellyfin-web
pkgs.jellyfin-ffmpeg
];
}

View File

@@ -0,0 +1,136 @@
{...}: {
disko.devices = {
disk = {
# Devices will be mounted and formatted in alphabetical order, and btrfs can only mount raids
# when all devices are present. So we define an "empty" luks device on the first disk,
# and the actual btrfs raid on the second disk, and the name of these entries matters!
system = {
type = "disk";
device = "/dev/mmcblk0";
content = {
type = "gpt";
partitions = {
boot = {
name = "boot";
size = "1M";
type = "EF02";
};
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
crypt_root = {
size = "100%";
content = {
type = "luks";
name = "p_root";
settings = {
allowDiscards = true;
keyFile = "/dev/disk/by-uuid/2021-07-11-12-33-27-00";
keyFileSize = 4096;
};
content = {
type = "btrfs";
subvolumes = {
"/root" = {
mountpoint = "/";
};
};
};
};
};
};
};
};
data1 = {
type = "disk";
device = "/dev/sda";
content = {
type = "gpt";
partitions = {
crypt_p1 = {
size = "100%";
content = {
type = "luks";
name = "p_data1"; # device-mapper name when decrypted
# Remove settings.keyFile if you want to use interactive password entry
settings = {
allowDiscards = true;
keyFile = "/dev/disk/by-uuid/2021-07-11-12-33-27-00";
keyFileSize = 4096;
};
};
};
};
};
};
data2 = {
type = "disk";
device = "/dev/sdb";
content = {
type = "gpt";
partitions = {
crypt_p2 = {
size = "100%";
content = {
type = "luks";
name = "p_data2";
# Remove settings.keyFile if you want to use interactive password entry
settings = {
allowDiscards = true;
keyFile = "/dev/disk/by-uuid/2021-07-11-12-33-27-00"; # Same key for both devices
keyFileSize = 4096;
};
content = {
type = "btrfs";
extraArgs = [
"-d raid0"
"/dev/mapper/p_data1" # Use decrypted mapped device, same name as defined in disk1
];
subvolumes = {
"/" = {
mountpoint = "/mnt/fs";
mountOptions = [ "compress=zstd:3" ];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [ "compress=zstd:3" ];
};
"/data" = {
mountpoint = "/mnt/data";
mountOptions = [ "compress=zstd:3" ];
};
"/mediacenter" = {
mountpoint = "/mnt/mediacenter";
mountOptions = [ "compress=zstd:3" ];
};
"/backups" = {
mountpoint = "/mnt/backups";
mountOptions = [ "compress=zstd:6" ];
};
"/jellyfin" = {
mountpoint = "/mnt/jellyfin";
mountOptions = [ ];
};
"/containers" = {
mountpoint = "/var/lib/containers";
mountOptions = [ ];
};
};
};
};
};
};
};
};
};
};
}

60
hosts/sin/matrix.nix Normal file
View File

@@ -0,0 +1,60 @@
{pkgs, config, ...}:
{
users.users = {
postgres = {
isSystemUser = true;
};
matrix-synapse = {
isSystemUser = true;
};
};
services.postgresql = {
enable = true;
ensureDatabases = [ "matrix-synapse" ];
ensureUsers = [
{
name = "matrix-synapse";
ensureDBOwnership = true;
ensureClauses.login = true;
}
];
authentication = pkgs.lib.mkOverride 10 ''
#type #database #user #auth-method
local postgres all trust
local matrix-synapse matrix-synapse trust
'';
};
networking.firewall.allowedTCPPorts = [ 8008 8448 ];
services.matrix-synapse = {
enable = true;
settings = {
server_name = "matrix.shobu.fr";
public_baseurl = "https://matrix.shobu.fr/";
enable_registration = true;
enable_registration_captcha = true;
serve_server_wellknown = true;
listeners = [
{
port = 8008;
bind_addresses = ["0.0.0.0"];
type = "http";
tls = false;
x_forwarded = true;
resources = [
{
names = [ "client" "federation" ];
compress = true;
}
];
}
];
};
extraConfigFiles = [
config.age.secrets.captcha.path
];
};
}

13
hosts/sin/secrets.nix Normal file
View File

@@ -0,0 +1,13 @@
{...}: {
age.secrets = {
# captcha = {
# file = ./secrets/matrix_captcha.age;
# group = "matrix-synapse";
# mode = "770";
# };
airvpn-params = {
file = ./secrets/airvpn_wireguard_key_env.age;
mode = "700";
};
};
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,69 @@
{config, ...}: {
users.users."starr" = {
extraGroups = [ "transmission" ];
};
users.users.transmission = {
isSystemUser = true;
group = "transmission";
uid = 992;
};
users.groups = {
transmission.gid = 989;
};
virtualisation.oci-containers = let
peerport = "63369";
in {
backend = "docker";
containers = {
gluetun = {
image = "qmcgaw/gluetun";
environment = {
VPN_SERVICE_PROVIDER = "airvpn";
VPN_TYPE = "wireguard";
# WIREGUARD_PRIVATE_KEY = "from agenix";
# WIREGUARD_PRESHARED_KEY = "from agenix";
# WIREGUARD_ADDRESSES = "from agenix";
# SERVER_COUNTRIES = "from agenix";
FIREWALL_VPN_INPUT_PORTS = "13277,${peerport}";
};
environmentFiles = [
config.age.secrets.airvpn-params.path
];
extraOptions = [
"--cap-add=NET_ADMIN"
"--device=/dev/net/tun"
];
ports = [
"13277:13277"
"9091:13277"
"${peerport}:${peerport}"
"${peerport}:${peerport}/udp"
];
};
transmission = {
image = "docker.io/linuxserver/transmission:latest";
volumes = [
"/etc/transmission:/config"
"/etc/localtime:/etc/localtime:ro"
"/mnt/mediacenter/torrents:/mnt/mediacenter/torrents"
"/mnt/data/transmission_downloads:/mnt/data/transmission_downloads"
];
dependsOn = [
"gluetun"
];
extraOptions = [
"--network=container:gluetun"
];
environment = {
PUID = toString config.users.users.transmission.uid;
GUID = toString config.users.groups.transmission.gid;
PEERPORT = peerport;
};
};
};
};
}