Compare commits

...

55 Commits

Author SHA1 Message Date
numbus df3c3d1c08 Update Whiteboard 2026-06-08 12:45:17 +02:00
numbus e98263b100 Update Immich 2026-06-08 12:42:04 +02:00
numbus 0500445003 Update Traefik 2026-06-08 12:40:06 +02:00
numbus ce4fa00b77 Update NixOS 2026-06-08 12:38:50 +02:00
numbus ec9b8f7d55 Update Traefik 2026-05-14 11:48:55 +02:00
numbus 0cc60dcd29 Update Nextcloud, Whiteboard and OnlyOffice 2026-05-14 11:48:03 +02:00
numbus 3b432d8bd4 Update Nextcloud 2026-04-13 09:21:29 +02:00
numbus 19b2459f65 Up the amount of RAM usable by Nextcloud 2026-04-12 15:12:01 +02:00
numbus 76fbcd86db Added screen package 2026-03-25 09:13:09 +01:00
numbus d1e511bfc0 Typo : 1 data disk 2026-03-15 12:34:23 +01:00
numbus 090cb2a7e4 Remove the /mnt/content-0 if more than 2 data disks 2026-03-15 12:30:20 +01:00
numbus c994337e1f Change onlyoffice headers. 2026-03-09 00:35:21 +01:00
numbus f1e24678b9 Remove security option to make Nextcloud onlyoffice work. 2026-03-09 00:28:25 +01:00
Raphaël Numbus dcde9fad01 Changed trusted proxy address. 2026-03-05 22:09:01 +01:00
Raphaël Numbus 3c41c307ee Fixed Nextcloud headers. OnlyOffice now works with Nextcloud. 2026-03-05 22:05:32 +01:00
Raphaël Numbus 7e4ef7b679 Get nextcloud-onlyoffice to work. 2026-03-05 13:04:24 +01:00
Raphaël Numbus 3e927af8f9 Get nextcloud-onlyoffice to work. 2026-03-05 12:58:05 +01:00
Raphaël Numbus 6de5f0cd28 Get gitea to work. 2026-03-05 12:48:25 +01:00
Raphaël Numbus 5394287b3a Home-assistant bug. Get nextcloud-onlyoffice to work. 2026-03-05 12:42:26 +01:00
Raphaël Numbus a4c0c2b051 Fixed home-assistant 400: bad request. Fixed Nextcloud-Quirk failing. Fixed Nextcloud-Onlyoffice mkdir: permission denied. 2026-03-05 09:24:51 +01:00
Raphaël Numbus 7933a3aa57 Added slirp4netns 2026-03-04 21:54:46 +01:00
Raphaël Numbus b5bece34ed Moved coral tpu config to a single file. Added slirp4netns. 2026-03-04 21:22:33 +01:00
Raphaël Numbus 4ab54cae0a Added AdGuard (NEEDS TESTING). Fixed bad indentation for middlewares. Switched from every 2 month periodic scan to every 3 months. 2026-03-03 22:27:24 +01:00
Raphaël Numbus e6907ddd0a Try to fix newuidmap exec not found 2026-03-03 22:08:21 +01:00
Raphaël Numbus 5bf87a1f83 Try to fix newuidmap exec not found 2026-03-03 22:04:58 +01:00
Raphaël Numbus cca3e0d42b Try to fix newuidmap exec not found 2026-03-03 21:46:15 +01:00
Raphaël Numbus f190eb2040 Try to fix newuidmap exec not found 2026-03-03 21:14:06 +01:00
Raphaël Numbus 96d049d486 Try to fix newuidmap exec not found 2026-03-03 20:49:21 +01:00
Raphaël Numbus e09301c493 Try to fix newuidmap exec not found 2026-03-03 16:30:21 +01:00
Raphaël Numbus 3721e41e94 Try to fix newuidmap exec not found 2026-03-03 16:00:48 +01:00
Raphaël Numbus 5b604fac08 Try to fix newuidmap exec not found 2026-03-03 15:43:21 +01:00
Raphaël Numbus e1ddf88300 Try to fix newuidmap exec not found 2026-03-03 15:35:18 +01:00
Raphaël Numbus 07e7084b1b Try to fix Traefik not launching on startup 2026-03-03 15:07:39 +01:00
Raphaël Numbus e46ee8495c Fixed Home-assistant script. 2026-03-03 14:45:23 +01:00
Raphaël Numbus 5cd7f661c0 Fixed passbolt error. 2026-03-03 14:38:25 +01:00
Raphaël Numbus 4d1448189c Added coral TPU driver compile files. Try to fix passbolt YAML error. 2026-03-03 14:23:53 +01:00
Raphaël Numbus 501383bc8d Get periodic scan to work. 2026-03-02 14:45:59 +01:00
Raphaël Numbus 331b686bae Get periodic scan to work. 2026-03-01 19:11:39 +01:00
Raphaël Numbus ca8e8c967e Remove unnecessary input 2026-03-01 17:58:26 +01:00
Raphaël Numbus 487889e3c6 Forgot with lib 2026-03-01 17:58:04 +01:00
Raphaël Numbus de6c80d7b4 Fixed bad option in it-tools, pi-hole and traefik. Added virtualization file. 2026-03-01 17:57:01 +01:00
Raphaël Numbus d384fe1f7c Fix clamAV onacc service. 2026-03-01 17:39:30 +01:00
Raphaël Numbus 65e1ba4ed2 Enable clamAV mail alerts. 2026-03-01 15:06:36 +01:00
Raphaël Numbus 6705329887 Debugging 2026-03-01 15:02:58 +01:00
Raphaël Numbus ae00cb69de Fix nextcloud-quirk systemD service failures. Also get clamAV configuration to work. 2026-03-01 14:49:28 +01:00
Raphaël Numbus 19b2ac7426 Fix nextcloud-quirk systemD service failures. 2026-03-01 14:25:19 +01:00
Raphaël Numbus b12f081bc3 Malformed if statement. 2026-03-01 14:10:38 +01:00
Raphaël Numbus 0ff3ec0e1b Fix nextcloud-quirk systemD service failures. 2026-03-01 14:08:03 +01:00
Raphaël Numbus 45495b114f Fix nextcloud-quirk systemD service failures. 2026-03-01 13:46:18 +01:00
Raphaël Numbus 3bfaf5fa6f Added periodic clamAV scan. Added mail alert on virus detection. 2026-03-01 13:18:35 +01:00
Raphaël Numbus bbe269bfcd Fix systemD service failures. 2026-03-01 12:25:12 +01:00
Raphaël Numbus af4f384797 Fixed syntax error. 2026-03-01 12:10:03 +01:00
Raphaël Numbus 68949dc81b Forgot to add lib. 2026-03-01 12:06:57 +01:00
Raphaël Numbus fad1f51323 Updated clamAV configuration. Fixed nextcloud-quirk typo. 2026-03-01 12:05:30 +01:00
Raphaël Numbus ab886a8a0b Fixed error. 2026-03-01 11:29:26 +01:00
22 changed files with 474 additions and 113 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
description = "Numbus Server Module";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
};
outputs = { self, nixpkgs }: {
+1
View File
@@ -5,5 +5,6 @@
./boot.nix
./cpu.nix
./disks.nix
./pcie-coral.nix
];
}
+1 -1
View File
@@ -265,7 +265,7 @@ in
services.snapraid = {
enable = true;
contentFiles = [ "/mnt/content-0/snapraid.content" ] ++
contentFiles = (optionals (length cfg.dataDisksList == 1) [ "/mnt/content-0/snapraid.content" ]) ++
(map (i: "/mnt/content-${toString i}/snapraid.content") (range 1 (length cfg.dataDisksList)));
parityFiles = map (i: "/mnt/parity-${toString i}/snapraid.parity") (range 1 (length cfg.parityDisksList));
dataDisks = listToAttrs (imap1 (i: _: nameValuePair "d${toString i}" "/mnt/content-${toString i}") cfg.dataDisksList);
+111
View File
@@ -0,0 +1,111 @@
{ config, lib, pkgs, ... }:
let
cfg = config.numbus.hardware.pcie-coral;
gasket-driver = { stdenv, lib, fetchFromGitHub, kernel }: stdenv.mkDerivation rec {
pname = "gasket";
version = "1.0-18";
src = fetchFromGitHub {
owner = "google";
repo = "gasket-driver";
rev = "97aeba584efd18983850c36dcf7384b0185284b3";
sha256 = "pJwrrI7jVKFts4+bl2xmPIAD01VKFta2SRuElerQnTo=";
};
makeFlags = [
"-C"
"${kernel.dev}/lib/modules/${kernel.modDirVersion}/build"
"M=$(PWD)"
];
buildFlags = [ "modules" ];
installFlags = [ "INSTALL_MOD_PATH=${placeholder "out"}" ];
installTargets = [ "modules_install" ];
sourceRoot = "source/src";
hardeningDisable = [ "pic" "format" ];
nativeBuildInputs = kernel.moduleBuildDependencies;
meta = with lib; {
description = "The Coral Gasket Driver allows usage of the Coral EdgeTPU on Linux systems.";
homepage = "https://github.com/google/gasket-driver";
license = licenses.gpl2;
maintainers = [ maintainers.kylehendricks ];
platforms = platforms.linux;
};
};
libedgetpu-pkg = { stdenv, lib, fetchFromGitHub, libusb1, abseil-cpp, flatbuffers, xxd }:
let
flatbuffers_1_12 = flatbuffers.overrideAttrs (oldAttrs: rec {
version = "1.12.0";
NIX_CFLAGS_COMPILE = "-Wno-error=class-memaccess -Wno-error=maybe-uninitialized";
cmakeFlags = (oldAttrs.cmakeFlags or []) ++ ["-DFLATBUFFERS_BUILD_SHAREDLIB=ON"];
NIX_CXXSTDLIB_COMPILE = "-std=c++17";
configureFlags = (oldAttrs.configureFlags or []) ++ ["--enable-shared"];
src = fetchFromGitHub {
owner = "google";
repo = "flatbuffers";
rev = "v${version}";
sha256 = "sha256-L1B5Y/c897Jg9fGwT2J3+vaXsZ+lfXnskp8Gto1p/Tg=";
};
});
in stdenv.mkDerivation rec {
pname = "libedgetpu";
version = "grouper";
src = fetchFromGitHub {
owner = "google-coral";
repo = pname;
rev = "release-${version}";
sha256 = "sha256-73hwItimf88Iqnb40lk4ul/PzmCNIfdt6Afi+xjNiBE=";
};
makeFlags = ["-f" "makefile_build/Makefile" "libedgetpu" ];
buildInputs = [
libusb1
abseil-cpp
flatbuffers_1_12
];
nativeBuildInputs = [
xxd
];
NIX_CXXSTDLIB_COMPILE = "-std=c++17";
TFROOT = "${fetchFromGitHub {
owner = "tensorflow";
repo = "tensorflow";
rev = "v2.7.4";
sha256 = "sha256-liDbUAdaVllB0b74aBeqNxkYNu/zPy7k3CevzRF5dk0=";
}}";
enableParallelBuilding = false;
installPhase = ''
mkdir -p $out/lib
cp out/direct/k8/libedgetpu.so.1.0 $out/lib
ln -s $out/lib/libedgetpu.so.1.0 $out/lib/libedgetpu.so.1
mkdir -p $out/lib/udev/rules.d
cp debian/edgetpu-accelerator.rules $out/lib/udev/rules.d/99-edgetpu-accelerator.rules
'';
};
gasket = config.boot.kernelPackages.callPackage gasket-driver {};
libedgetpu = pkgs.callPackage libedgetpu-pkg {};
in
{
options.numbus.hardware.pcie-coral = lib.mkEnableOption "PCIe Coral TPU support";
config = lib.mkIf cfg {
services.udev.packages = [ libedgetpu ];
users.groups.plugdev = {};
boot.extraModulePackages = [ gasket ];
};
}
+89
View File
@@ -0,0 +1,89 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.numbus.services.clamav;
clamav_notifier = pkgs.writeScript "clamav-notify.sh" ''
#!${pkgs.bash}/bin/bash
# Check if triggered by Real-time event (file exists)
if [ -f /var/lib/clamav/virus_event.env ]; then
source /var/lib/clamav/virus_event.env
rm /var/lib/clamav/virus_event.env
fi
ADMIN_EMAIL="${config.numbus.mail.adminAddress}"
USER_EMAIL="${config.numbus.mail.userAddress}"
OWNER_NAME="${config.numbus.owner}"
if [ -n "$CLAM_VIRUSEVENT_VIRUSNAME" ]; then
# --- Real-time / VirusEvent Mode ---
SUBJECT="Numbus Server Alert: Virus Detected (Real-time)"
# Retrieve logs from clamav-daemon
LOGS=$(journalctl -u clamav-daemon.service -n 50 --no-pager | grep "FOUND")
TECH_BODY="
ClamAV Real-time Alert:
Server owner: $OWNER_NAME
Virus detected: $CLAM_VIRUSEVENT_VIRUSNAME
File: $CLAM_VIRUSEVENT_FILENAME
Logs:
$LOGS
Action taken: Access blocked (OnAccessPrevention).
Please investigate manually.
"
FRIENDLY_BODY="Cher/Chère $OWNER_NAME,
L'antivirus de votre serveur a détecté et bloqué une menace en temps réel.
Fichier : $CLAM_VIRUSEVENT_FILENAME
Votre administrateur a été notifié.
"
else
# --- Scheduled Scan Summary Mode ---
SUBJECT="Numbus Server Alert: Virus Detected during Scheduled Scan"
# Retrieve logs (clamdscan prints FOUND when a virus is detected)
LOGS=$(journalctl -u clamav-periodic-scan.service -n 100 --no-pager | grep "FOUND")
TECH_BODY="
ClamAV Scan Alert:
Server owner: $OWNER_NAME
Viruses detected:
$LOGS
Action taken: Detection only.
Please investigate manually.
"
FRIENDLY_BODY="Cher/Chère $OWNER_NAME,
L'antivirus de votre serveur a détecté une menace potentielle lors de l'analyse périodique.
Votre administrateur a été notifié avec les détails techniques.
Nous vous conseillons d'être prudent avec vos fichiers récents.
"
fi
printf "Subject: [ADMIN] %s\n\n%s" "$SUBJECT" "$TECH_BODY" | /run/wrappers/bin/sendmail -t "$ADMIN_EMAIL"
printf "Subject: [Alerte] Menace détectée sur votre serveur Numbus\n\n%s\n\nMerci de votre confiance,\nL'équipe de support,\nNumbus-Server." "$FRIENDLY_BODY" | /run/wrappers/bin/sendmail -t "$USER_EMAIL"
'';
in
{
config = mkIf cfg.enable {
systemd.services.clamav-virus-notify = {
description = "Email notification for ClamAV virus detection";
serviceConfig = {
Type = "oneshot";
ExecStart = "${clamav_notifier}";
};
};
};
}
+1
View File
@@ -2,6 +2,7 @@
{
imports = [
./clamav.nix
./smart.nix
./systemd.nix
./smtp.nix
+1
View File
@@ -5,6 +5,7 @@
environment.systemPackages = with pkgs; [
git
screen
ncdu
fastfetch
tpm2-tss
-2
View File
@@ -9,10 +9,8 @@
};
environment.systemPackages = with pkgs; [
podman
podman-compose
podman-tui
passt
slirp4netns
];
}
+51
View File
@@ -0,0 +1,51 @@
{ config, pkgs, lib, ... }:
with lib;
let
# Version tagging
adguardVersion = "latest";
# Helper
helper = import ./lib.nix { inherit config pkgs lib; };
cfg = config.numbus.services.adguard;
# Container config
name = "adguard";
in
helper.mkPodmanService {
inherit name;
description = "AdGuard, feature-rich DNS service";
pod = "false";
defaultPort = "3000";
scheme = "http";
dependencies = [ "network.target" ];
dataDirEnabled = false;
startDelay = 10;
middlewares = [ "secureHeaders" ];
dirPermissions = [
"100999:100 ${cfg.configDir}"
];
# Compose file good
composeText = ''
services:
adguardhome:
image: adguard/adguardhome:${adguardVersion}
container_name: adguard
hostname: adguard
network_mode: pasta
user: '1000:1000'
ports:
- "3000:3000/tcp"
- "53:53/tcp"
- "53:53/udp"
volumes:
- ${cfg.configDir}/work:/opt/adguardhome/work
- ${cfg.configDir}/config:/opt/adguardhome/conf
cap_add:
- SYS_NICE
security_opt:
- no-new-privileges:true
restart: unless-stopped
'';
}
+82 -25
View File
@@ -1,34 +1,91 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.numbus.services.clamav;
onAccessPaths = lib.mapAttrsToList (n: v: v.dataDir) (lib.filterAttrs (n: v:
v ? enable && v.enable && v ? dataDir && v.dataDir != null && v.dataDir != false
) config.numbus.services);
clamonacc_virus_notifier = pkgs.writeScript "clamonacc_virus_notifier.sh" ''
#!${pkgs.bash}/bin/bash
echo "CLAM_VIRUSEVENT_VIRUSNAME=\"$CLAM_VIRUSEVENT_VIRUSNAME\"" > /var/lib/clamav/virus_event.env
echo "CLAM_VIRUSEVENT_FILENAME=\"$CLAM_VIRUSEVENT_FILENAME\"" >> /var/lib/clamav/virus_event.env
/run/wrappers/bin/sudo /run/current-system/sw/bin/systemctl start clamav-virus-notify.service
'';
in
{
environment.systemPackages = [ pkgs.clamav pkgs.curl ];
services.clamav = {
updater.enable = true;
daemon.enable = true;
scanner = {
enable = true;
interval = "*-*-* 04:00:00"; # Everyday at 4am
scanDirectories = [
"/etc"
"/home"
"/var/lib"
"/var/tmp"
"/tmp"
];
options.numbus.services.clamav = {
enable = mkEnableOption "ClamAV open-source anti-virus software";
};
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.clamav pkgs.curl ];
clamonacc.enable = true;
system.activationScripts.clamav-quarantine = ''
mkdir -p /quarantine
chown clamav:clamav /quarantine
chmod 440 /quarantine
'';
daemon.settings = {
OnAccessPrevention = true;
OnAccessIncludePath = "/mnt/data";
security.sudo.extraRules = [{
users = [ "clamav" ];
commands = [{
command = "/run/current-system/sw/bin/systemctl start clamav-virus-notify.service";
options = [ "NOPASSWD" ];
}];
}];
services.clamav = {
updater.enable = true;
clamonacc.enable = true;
scanner = {
enable = true;
interval = "*-*-* 04:00:00"; # Everyday at 4am
scanDirectories = [
"/etc"
"/home"
"/var/lib"
"/var/tmp"
"/tmp"
];
};
daemon = {
enable = true;
settings = {
OnAccessPrevention = true;
OnAccessIncludePath = onAccessPaths;
VirusEvent = "${clamonacc_virus_notifier}";
};
};
};
systemd.services.clamav-periodic-scan = mkIf (onAccessPaths != []) {
description = "Periodic ClamAV virus scan";
after = [ "clamav-daemon.service" "clamav-freshclam.service" ];
requires = [ "clamav-daemon.service" ];
wants = [ "clamav-freshclam.service" ];
onFailure = [ "clamav-virus-notify.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.clamav}/bin/clamdscan --multiscan --fdpass --infected --allmatch --move=/quarantine ${lib.escapeShellArgs onAccessPaths}";
Slice = "system-clamav.slice";
};
};
systemd.timers.clamav-periodic-scan = mkIf (onAccessPaths != []) {
description = "Timer for ClamAV periodic scan";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*-1/3-01 04:00:00";
Persistent = true;
Unit = "clamav-periodic-scan.service";
};
};
};
};
services.clamav.daemon.enable = true;
services.clamav.updater.enable = true;
services.clamav.clamonacc.enable = true;
}
+2
View File
@@ -3,6 +3,7 @@
{
imports = [
# ./adguard.nix
./clamav.nix
./frigate.nix
./gitea.nix
./home-assistant.nix
@@ -12,5 +13,6 @@
./passbolt.nix
./pi-hole.nix
./traefik.nix
./virtualization.nix
];
}
+2 -2
View File
@@ -18,13 +18,13 @@ helper.mkPodmanService {
pod = "home-assistant";
defaultPort = "8971";
scheme = "https";
dependencies = [ "traefik.service" "${config.numbus.services.dns}.service" "home-assistant.service" ];
envFile = "/var/lib/numbus-server/home-assistant/.env";
dependencies = [ "traefik.service" "${config.numbus.services.dns}.service" "home-assistant.service" ];
middlewares = [ "secureHeaders" ];
dirPermissions = [
"1000:100 ${cfg.configDir}"
"1000:100 ${cfg.dataDir}"
];
middlewares = [ "secureHeaders" ];
extraOptions = {
devices = mkOption {
+2 -2
View File
@@ -23,13 +23,13 @@ helper.mkPodmanService {
DB_USERNAME = "xkcdpass -n 2 -d -";
DB_PASSWORD = "xkcdpass -n 8 -d -";
};
middlewares = [ "secureHeaders" ];
dirPermissions = [
"100999:100 ${cfg.configDir}"
"100999:100 ${cfg.configDir}/data"
"100999:100 ${cfg.configDir}/config"
"100999:100 ${cfg.configDir}/database"
];
middlewares = [ "secureHeaders" ];
composeText = ''
services:
@@ -53,7 +53,7 @@ helper.mkPodmanService {
- GITEA__database__USER=$DB_USERNAME
- GITEA__database__PASSWD=$DB_PASSWORD
- GITEA__server__SSH_PORT=2424
- GITEA__server__ROOT_URL=${cfg.subdomain}.${config.numbus.services.domain}
- GITEA__server__ROOT_URL=https://${cfg.subdomain}.${config.numbus.services.domain}
depends_on:
- gitea-database
security_opt:
+12 -12
View File
@@ -22,12 +22,12 @@ helper.mkPodmanService {
HOME_ASSISTANT_MQTT_USER = "xkcdpass -n 2 -d -";
HOME_ASSISTANT_MQTT_PASSWORD = "xkcdpass -n 8 -d -";
};
middlewares = [ "secureHeaders" ];
dirPermissions = [
"1000:100 ${cfg.configDir}"
"1000:100 ${cfg.configDir}/config"
"100999:100 ${cfg.configDir}/mqtt"
];
middlewares = [ "secureHeaders" ];
# Compose file good
composeText = ''
@@ -83,8 +83,8 @@ helper.mkPodmanService {
};
extraConfig = {
systemd.services."${name}-quirk-1" = {
description = "Podman container quirk 1 : ${name}";
systemd.services."${name}-quirk" = {
description = "Podman container quirk : ${name}";
wantedBy = [ "multi-user.target" ];
after = [ "${name}.service" ];
onFailure = [ "service-failure-notify@%n.service" ];
@@ -100,9 +100,9 @@ helper.mkPodmanService {
if [[ -e ${cfg.configDir}/config/configuration.yaml ]]; then
if grep -qF "${config.numbus.networking.ipAddress}/24" ${cfg.configDir}/config/configuration.yaml; then
exit 0
elif grep -qF "use_x_forwarded_for" ${cfg.configDir}/config/configuration.yaml && ! grep -qF "${config.numbus.networking.ipAddress}/24" ${cfg.configDir}/config/configuration.yaml
elif grep -qF "use_x_forwarded_for" ${cfg.configDir}/config/configuration.yaml && ! grep -qF "${config.numbus.networking.ipAddress}/24" ${cfg.configDir}/config/configuration.yaml; then
tmp=$(mktemp)
head -n -4 ${cfg.configDir}/config/configuration.yaml > "$tmp"
head -n -6 ${cfg.configDir}/config/configuration.yaml > "$tmp"
mv "$tmp" ${cfg.configDir}/config/configuration.yaml
fi
fi
@@ -114,7 +114,7 @@ helper.mkPodmanService {
http:
use_x_forwarded_for: true
trusted_proxies: ${config.numbus.networking.ipAddress}/24
trusted_proxies: 10.89.0.0/16
zha:
EOF
@@ -123,11 +123,11 @@ EOF
};
};
systemd.services."${name}-quirk-2" = {
description = "Podman container quirk 2 : ${name}";
wantedBy = [ "multi-user.target" "${name}.service" ];
after = [ "${name}-secrets.service" ];
before = [ "${name}.service" "${name}-permissions.service" ];
systemd.services."mqtt-quirk" = {
description = "Podman container quirk : Home-assistant MQTT";
wantedBy = [ "multi-user.target" "mqtt.service" ];
after = [ "mqtt-secrets.service" ];
before = [ "mqtt.service" "mqtt-permissions.service" ];
onFailure = [ "service-failure-notify@%n.service" ];
startLimitBurst = 5;
startLimitIntervalSec = 600;
@@ -157,7 +157,7 @@ listener 1883
allow_anonymous false
password_file /mosquitto/password.txt
EOF
source /var/lib/numbus-server/${name}/.env
source /var/lib/numbus-server/mqtt/.env
mosquitto_passwd -b ${cfg.configDir}/mqtt/password.txt "$HOME_ASSISTANT_MQTT_USER" "$HOME_ASSISTANT_MQTT_PASSWORD"
chmod 600 ${cfg.configDir}/mqtt/password.txt
'';
+3 -3
View File
@@ -4,7 +4,7 @@ with lib;
let
# Version tagging
immichVersion = "v2.5.6";
immichVersion = "v2.7.5";
redisVersion = "9@sha256:546304417feac0874c3dd576e0952c6bb8f06bb4093ea0c9ca303c73cf458f63";
databaseVersion = "14-vectorchord0.4.3-pgvectors0.2.0@sha256:bcf63357191b76a916ae5eb93464d65c07511da41e3bf7a8416db519b40b1c23";
# Helper
@@ -29,8 +29,9 @@ helper.mkPodmanService {
UPLOAD_LOCATION = "${cfg.dataDir}";
DB_DATA_LOCATION = "${cfg.configDir}/database";
TZ = "${config.time.timeZone}";
IMMICH_VERSION = "v2.5.6";
IMMICH_VERSION = "v2.7.5";
};
middlewares = [ "immichSecureHeaders" ];
dirPermissions = [
"100999:100 ${cfg.configDir}"
"100999:100 ${cfg.configDir}/redis"
@@ -40,7 +41,6 @@ helper.mkPodmanService {
"100999:100 ${cfg.configDir}/database"
"100999:100 ${cfg.dataDir}"
];
middlewares = [ "immichSecureHeaders" ];
# Compose file good
composeText = ''
+2 -2
View File
@@ -17,8 +17,8 @@ helper.mkPodmanService {
description = "IT-tools, useful tools when doing IT";
pod = "false";
defaultPort = "8880";
configDir = false;
dataDir = false;
configDirEnabled = false;
dataDirEnabled = false;
middlewares = [ "secureHeaders" ];
# Compose file good
+5 -7
View File
@@ -87,7 +87,7 @@ with lib;
- "websecure"
service: ${name}
middlewares:
${concatStringsSep "\n" (map (m: " - ${m}") middlewares)}
${concatStringsSep "\n" (map (m: " - ${m}") middlewares)}
tls:
certresolver: "cloudflare"
options: "secureTLS"
@@ -106,18 +106,16 @@ with lib;
onFailure = [ "service-failure-notify@%n.service" ];
startLimitBurst = 5;
startLimitIntervalSec = 600;
path = [ pkgs.podman pkgs.podman-compose pkgs.su pkgs.coreutils ];
path = [ pkgs.podman pkgs.podman-compose pkgs.slirp4netns pkgs.su pkgs.sudo pkgs.coreutils ];
serviceConfig = {
Type = "exec";
User = "numbus-admin";
Group = "users";
TimeoutStartSec = "1000";
ExecStartPre = [
"${pkgs.bash}/bin/bash -c 'sleep $((RANDOM % ${toString startDelay}))'"
"${pkgs.podman-compose}/bin/podman-compose -f /etc/podman/${name}/compose.yaml pull"
"${pkgs.bash}/bin/bash -c 'export PATH=/run/wrappers/bin:$PATH; exec ${pkgs.sudo}/bin/sudo -u numbus-admin podman-compose -f /etc/podman/${name}/compose.yaml pull'"
];
ExecStart = "${pkgs.podman-compose}/bin/podman-compose ${envFileArg} --in-pod ${toString pod} -f /etc/podman/${name}/compose.yaml up --remove-orphans";
ExecStop = "${pkgs.podman-compose}/bin/podman-compose ${envFileArg} --in-pod ${toString pod} -f /etc/podman/${name}/compose.yaml down";
ExecStart = "${pkgs.bash}/bin/bash -c 'export PATH=/run/wrappers/bin:$PATH; exec ${pkgs.sudo}/bin/sudo -u numbus-admin podman-compose ${envFileArg} --in-pod ${toString pod} -f /etc/podman/${name}/compose.yaml up --remove-orphans'";
ExecStop = "${pkgs.bash}/bin/bash -c 'export PATH=/run/wrappers/bin:$PATH; exec ${pkgs.sudo}/bin/sudo -u numbus-admin podman-compose ${envFileArg} --in-pod ${toString pod} -f /etc/podman/${name}/compose.yaml down'";
Restart = "on-failure";
RestartSec = "3m";
};
+81 -47
View File
@@ -4,11 +4,11 @@ with lib;
let
# Version tagging
nextcloudVersion = "32.0.6";
nextcloudVersion = "33.0.5-apache";
redisVersion = "8.6-alpine";
databaseVersion = "11.8";
onlyofficeVersion = "9.2";
whiteboardVersion = "v1.5.6";
onlyofficeVersion = "9.4.0";
whiteboardVersion = "v1.5.9";
# Helper
helper = import ./lib.nix { inherit config pkgs lib; };
cfg = config.numbus.services.nextcloud;
@@ -29,18 +29,19 @@ helper.mkPodmanService {
WHITEBOARD_PASSWORD = "xkcdpass -n 10 -d -";
SMTP_PASSWORD = "cat ${config.numbus.mail.smtpPasswordPath}";
};
middlewares = [ "nextcloudSecureHeaders" ];
dirPermissions = [
"100032:100 ${cfg.dataDir}"
"100032:100 ${cfg.configDir}"
"100032:100 ${cfg.configDir}/web"
"100999:100 ${cfg.configDir}/redis"
"100999:100 ${cfg.configDir}/database"
"100999:100 ${cfg.configDir}/onlyoffice"
"100999:100 ${cfg.configDir}/onlyoffice/log"
"100999:100 ${cfg.configDir}/onlyoffice/cache"
"100999:100 ${cfg.configDir}/onlyoffice/database"
"100032:100 ${cfg.dataDir}"
"1000:100 ${cfg.configDir}/onlyoffice"
"1000:100 ${cfg.configDir}/onlyoffice/log"
"1000:100 ${cfg.configDir}/onlyoffice/cache"
"1000:100 ${cfg.configDir}/onlyoffice/data"
"1000:100 ${cfg.configDir}/onlyoffice/database"
];
middlewares = [ "secureHeaders" "nextcloud-dav" ];
# Compose file good
composeText = ''
@@ -74,12 +75,14 @@ helper.mkPodmanService {
MAIL_DOMAIN: ${config.numbus.services.domain}
APACHE_DISABLE_REWRITE_IP: 1
OVERWRITEPROTOCOL: https
TRUSTED_PROXIES: ${config.numbus.networking.ipAddress}
TRUSTED_PROXIES: 10.89.0.0/16
NC_default_phone_region: "${config.numbus.language}"
NC_default_language: "${config.numbus.language}"
NC_default_locale: "${config.numbus.locale}"
NC_default_timezone: "${config.time.timeZone}"
NC_maintenance_window_start: "1"
PHP_MEMORY_LIMIT: 1024M
PHP_OPCACHE_MEMORY_CONSUMPTION: 256
depends_on:
- nextcloud-database
security_opt:
@@ -122,7 +125,7 @@ helper.mkPodmanService {
- NET_RAW
command:
- "--transaction-isolation=READ-COMMITTED"
- "--binlog-format=ROW"
- "--binlog-format=ROW"
restart: unless-stopped
nextcloud-onlyoffice:
container_name: nextcloud-onlyoffice
@@ -130,14 +133,19 @@ helper.mkPodmanService {
image: docker.io/onlyoffice/documentserver:${onlyofficeVersion}
environment:
- JWT_SECRET=$ONLYOFFICE_PASSWORD
- REDIS_SERVER_HOST=nextcloud-redis
- REDIS_SERVER_PORT=6379
- REDIS_SERVER_PASS=$REDIS_PASSWORD
- ADMINPANEL_ENABLED=false
- EXAMPLE_ENABLED=false
- METRICS_ENABLED=false
ports:
- "9980:80/tcp"
volumes:
- ${cfg.configDir}/onlyoffice/log:/var/log/onlyoffice
- ${cfg.configDir}/onlyoffice/cache:/var/lib/onlyoffice
- ${cfg.configDir}/onlyoffice/data:/var/www/onlyoffice/Data
- ${cfg.configDir}/onlyoffice/database:/var/lib/postgresql
security_opt:
- no-new-privileges:true
cap_drop:
- NET_RAW
restart: unless-stopped
@@ -172,7 +180,7 @@ helper.mkPodmanService {
- "websecure"
service: nextcloud-onlyoffice
middlewares:
- "secureHeaders"
- "nextcloudSecureHeaders"
tls:
certresolver: "cloudflare"
options: "secureTLS"
@@ -203,13 +211,37 @@ helper.mkPodmanService {
- url: "http://host.containers.internal:3002"
'';
environment.etc."traefik/rules/nextcloud-dav.yaml".text = ''
environment.etc."traefik/rules/nextcloudSecureHeaders.yaml".text = ''
http:
middlewares:
nextcloud-dav:
replacePathRegex:
regex: "^/.well-known/ca(l|rd)dav"
replacement: "/remote.php/dav/"
nextcloudSecureHeaders:
headers:
FrameDeny: false
CustomFrameOptionsValue: "SAMEORIGIN"
AddVaryHeader: true
BrowserXssFilter: true
ContentTypeNosniff: true
ForceSTSHeader: true
STSSeconds: 315360000
STSIncludeSubdomains: true
STSPreload: true
AccessControlAllowMethods: "GET,OPTIONS,PUT"
AccessControlAllowOriginList:
- origin-list-or-null
AccessControlMaxAge: 100
ReferrerPolicy: same-origin
PermissionsPolicy: "vibrate=()"
ContentSecurityPolicy: >-
default-src https://onlyoffice.${config.numbus.services.domain} 'self';
script-src https://onlyoffice.${config.numbus.services.domain} 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
connect-src 'self';
img-src 'self' data:;
font-src 'self' data:;
frame-src https://onlyoffice.${config.numbus.services.domain} 'self';
frame-ancestors https://onlyoffice.${config.numbus.services.domain} 'self';
object-src 'none';
base-uri 'self';
'';
systemd.services."${name}-quirk" = {
@@ -219,12 +251,14 @@ helper.mkPodmanService {
onFailure = [ "service-failure-notify@%n.service" ];
startLimitBurst = 5;
startLimitIntervalSec = 600;
path = [ pkgs.coreutils pkgs.sudo pkgs.podman pkgs.systemd ];
path = [ pkgs.coreutils pkgs.sudo pkgs.podman pkgs.systemd pkgs.gnugrep ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
OCC="sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ"
[[ ! -e /var/lib/numbus-server/${name}/.env ]] && systemctl start ${name}-secrets.service
until [[ -e /var/lib/numbus-server/${name}/.env ]]; do
echo "Waiting for secrets generation..."
@@ -232,45 +266,45 @@ helper.mkPodmanService {
done
source /var/lib/numbus-server/${name}/.env
until sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ status >/dev/null 2>&1; do
until $OCC status | grep -iq "installed: true" >/dev/null 2>&1; do
echo "Waiting for Nextcloud to be up and running..."
sleep 10
sleep 60
done
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ db:add-missing-indices
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ maintenance:repair --include-expensive
$OCC db:add-missing-indices
$OCC maintenance:repair --include-expensive
INSTALL_APPS_LIST=( "calendar" "contacts" "mail" "note" "onlyoffice" "cookbook" "whiteboard" )
REMOVE_APPS_LIST=( "activity" "app_api" "federatedfilesharing" "federation" "webhook_listeners" "photos" "recommendations" "sharebymail" "teams" "support" "richdocumentscode" )
CURRENT_APPS_SIGNATURE="$(echo "''${INSTALL_APPS_LIST[@]}" "''${REMOVE_APPS_LIST[@]}")"
APPS_SIGNATURE_FILE="/var/lib/numbus-server/${name}/installed_apps.signature"
INSTALL_APPS_LIST=( "calendar" "contacts" "mail" "notes" "onlyoffice" "cookbook" "whiteboard" )
DISABLE_APPS_LIST=( "activity" "federation" "webhook_listeners" "photos" "recommendations" "sharebymail" "teams" "support" "richdocumentscode" )
if [[ ! -f "$APPS_SIGNATURE_FILE" ]] || [[ "$(cat "$APPS_SIGNATURE_FILE")" != "$CURRENT_APPS_SIGNATURE" ]]; then
for app in ''${INSTALL_APPS_LIST[@]}; do
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ app:install "$app"
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ app:enable "$app"
done
for app in ''${REMOVE_APPS_LIST[@]}; do
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ app:disable "$app"
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ app:remove "$app"
done
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ config:system:set onlyoffice DocumentServerInternalUrl --value="https://onlyoffice.${config.numbus.services.domain}/"
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ config:system:set onlyoffice DocumentServerUrl --value="https://onlyoffice.${config.numbus.services.domain}/"
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ config:system:set onlyoffice jwt_secret --value="$ONLYOFFICE_PASSWORD"
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ config:app:set whiteboard collabBackendUrl --value="https://whiteboard.${config.numbus.services.domain}"
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ config:app:set whiteboard jwt_secret_key --value="$WHITEBOARD_PASSWORD"
echo "$CURRENT_APPS_SIGNATURE" > "$APPS_SIGNATURE_FILE"
fi
for app in ''${INSTALL_APPS_LIST[@]}; do
if ! $OCC --no-warnings app:list | grep -iq "$app:"; then
$OCC --no-warnings app:install "$app"
fi
if $OCC --no-warnings app:list --disabled | grep -iq "$app:"; then
$OCC --no-warnings app:enable "$app"
fi
done
for app in ''${DISABLE_APPS_LIST[@]}; do
if $OCC --no-warnings app:list --enabled | grep -iq "$app:"; then
$OCC --no-warnings app:disable "$app"
fi
done
$OCC --no-warnings config:system:set onlyoffice DocumentServerInternalUrl --value="https://onlyoffice.${config.numbus.services.domain}/"
$OCC --no-warnings config:system:set onlyoffice DocumentServerUrl --value="https://onlyoffice.${config.numbus.services.domain}/"
$OCC --no-warnings config:system:set onlyoffice jwt_secret --value="$ONLYOFFICE_PASSWORD"
$OCC --no-warnings config:app:set whiteboard collabBackendUrl --value="https://whiteboard.${config.numbus.services.domain}"
$OCC --no-warnings config:app:set whiteboard jwt_secret_key --value="$WHITEBOARD_PASSWORD"
if [[ ! -f /var/lib/numbus-server/${name}/croned.true ]]; then
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ background:cron
$OCC background:cron
sudo -u numbus-admin podman exec --user www-data nextcloud-server php -f /var/www/html/cron.php
touch /var/lib/numbus-server/${name}/croned.true
fi
if [[ ! -f /var/lib/numbus-server/${name}/scanned.true ]]; then
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ files:scan --all
sudo -u numbus-admin podman exec --user www-data nextcloud-server php occ files:repair-tree
$OCC files:scan --all
$OCC files:repair-tree
touch /var/lib/numbus-server/${name}/scanned.true
fi
'';
+2 -1
View File
@@ -25,6 +25,7 @@ helper.mkPodmanService {
DB_PASSWORD = "xkcdpass -n 10 -d -";
SMTP_PASSWORD = "cat ${config.numbus.mail.smtpPasswordPath}";
};
middlewares = [ "secureHeaders" ];
dirPermissions = [
"100032:100 ${cfg.configDir}"
"100032:100 ${cfg.configDir}/gpg"
@@ -69,7 +70,7 @@ helper.mkPodmanService {
"0",
"passbolt-database:3306",
"--",
"/docker-entrypoint.sh",
"/docker-entrypoint.sh"
]
depends_on:
- passbolt-database
+6 -6
View File
@@ -19,15 +19,15 @@ helper.mkPodmanService {
defaultPort = "4443";
scheme = "https";
dependencies = [ "network.target" ];
dataDir = false;
dataDirEnabled = false;
startDelay = 10;
generatedSecrets = {
PIHOLE_PASSWORD = "xkcdpass -n 10 -d -";
};
middlewares = [ "secureHeaders" ];
dirPermissions = [
"100999:100 ${cfg.configDir}"
];
middlewares = [ "secureHeaders" ];
# Compose file good
composeText = ''
@@ -51,15 +51,15 @@ helper.mkPodmanService {
FTLCONF_webserver_domain: ${cfg.subdomain}.${config.numbus.services.domain}
FTLCONF_dns_upstreams: 9.9.9.9;149.112.112.112
FTLCONF_dns_hosts: |
${lib.concatStringsSep "" (builtins.filter (x: x != null) (lib.mapAttrsToList (name: service:
${lib.concatStringsSep "" (lib.mapAttrsToList (name: service:
if builtins.isAttrs service && service ? enable && service.enable && service ? subdomain then
" ${config.numbus.networking.ipAddress} ${service.subdomain}.${config.numbus.services.domain}\n" +
(if name == "nextcloud" then
" ${config.numbus.networking.ipAddress} onlyoffice.${config.numbus.services.domain}\n" +
" ${config.numbus.networking.ipAddress} whiteboard.${config.numbus.services.domain}\n"
else null)
else null
) config.numbus.services))}
else "")
else ""
) config.numbus.services)}
FTLCONF_dns_listeningMode: "BIND"
FTLCONF_dns_domain_name: "${config.numbus.services.domain}"
FTLCONF_dns_domain_local: "true"
+2 -2
View File
@@ -4,7 +4,7 @@ with lib;
let
# Version tagging
traefikVersion = "v3.6.8";
traefikVersion = "v3.7.4";
# Helper
helper = import ./lib.nix { inherit config pkgs lib; };
cfg = config.numbus.services.traefik;
@@ -16,7 +16,7 @@ helper.mkPodmanService {
inherit name;
description = "Traefik reverse proxy, one to rule them all";
pod = "false";
dataDir = false;
dataDirEnabled = false;
dependencies = [ "network.target" ];
startDelay = 10;
generatedSecrets = {
+17
View File
@@ -0,0 +1,17 @@
{ config, lib, ... }:
with lib;
let
cfg = config.numbus.services.virtualization;
in
{
options.numbus.services.virtualization = {
enable = mkEnableOption "QEMU/KVM virtualization software";
};
config = mkIf cfg.enable {
virtualisation.libvirtd.enable = true;
};
}