Huge update. Reorganized folders. Added post-install logic. Have to do testing to check if everything works.

This commit is contained in:
Raphaël Numbus
2025-12-31 13:18:49 +01:00
parent 9559b232dc
commit 984d5454ac
44 changed files with 1052 additions and 581 deletions
+156
View File
@@ -0,0 +1,156 @@
{ modulesPath, config, lib, pkgs, inputs, ... }:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
(modulesPath + "/profiles/qemu-guest.nix")
inputs.sops-nix.nixosModules.sops
./disks/disko.nix
# ./disks/snapraid.nix
# ./disks/pcr-check.nix
# ./pcie-coral/coral.nix
];
# Hardware settings
hardware.enableRedistributableFirmware = true;
hardware.cpu.intel.updateMicrocode = true;
hardware.cpu.amd.updateMicrocode = true;
# Secrets management
sops.defaultSopsFile = ./secrets/secrets.yaml;
sops.age.sshKeyPaths = [ "/home/numbus-admin/.ssh/id_ed25519" ];
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
sops.age.generateKey = true;
sops.secrets."ssh_public_keys" = { owner = "numbus-admin"; path = "/etc/ssh/authorized_keys.d/numbus-admin"; };
sops.secrets."sender_email_address_password" = {};
sops.secrets."podman/frigate" = { owner = "numbus-admin"; path = "/etc/podman/frigate/.env"; };
sops.secrets."podman/gitea" = { owner = "numbus-admin"; path = "/etc/podman/gitea/.env"; };
sops.secrets."podman/home_assistant" = { owner = "numbus-admin"; path = "/etc/podman/home-assistant/.env"; };
sops.secrets."podman/immich" = { owner = "numbus-admin"; path = "/etc/podman/immich/.env"; };
sops.secrets."podman/it_tools" = { owner = "numbus-admin"; path = "/etc/podman/immich/.env"; };
sops.secrets."podman/nextcloud" = { owner = "numbus-admin"; path = "/etc/podman/nextcloud/.env"; };
sops.secrets."podman/passbolt" = { owner = "numbus-admin"; path = "/etc/podman/passbolt/.env"; };
sops.secrets."podman/pi_hole" = { owner = "numbus-admin"; path = "/etc/podman/pi-hole/.env"; };
sops.secrets."podman/traefik" = { owner = "numbus-admin"; path = "/etc/podman/traefik/.env"; };
# Bootloader options
boot.initrd.systemd.enable = true;
boot.initrd.systemd.tpm2.enable = true;
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# TPM2 PCR check
# systemIdentity.enable = true;
# systemIdentity.pcr15 = "PCR_HASH";
# Timezone
time.timeZone = "Europe/Paris";
# Internationalisation properties.
i18n.defaultLocale = "fr_FR.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "fr_FR.UTF-8";
LC_IDENTIFICATION = "fr_FR.UTF-8";
LC_MEASUREMENT = "fr_FR.UTF-8";
LC_MONETARY = "fr_FR.UTF-8";
LC_NAME = "fr_FR.UTF-8";
LC_NUMERIC = "fr_FR.UTF-8";
LC_PAPER = "fr_FR.UTF-8";
LC_TELEPHONE = "fr_FR.UTF-8";
LC_TIME = "fr_FR.UTF-8";
};
# Keyboard mapping
console.keyMap = "fr";
services.xserver.xkb = {
layout = "fr";
variant = "";
};
# Enable SSH
services.openssh.enable = true;
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
# Install packages
environment.systemPackages = with pkgs; [
ncdu
fastfetch
tpm2-tss
sops
age
powertop
pciutils
hdparm
hd-idle
hddtemp
smartmontools
cpufrequtils
intel-gpu-tools
podman
podman-compose
podman-tui
];
# Power savings
services.autoaspm.enable = true;
powerManagement.powertop.enable = true;
boot.kernelParams = [
"pcie_aspm=force"
"consoleblank=60"
];
# Enable cron service
services.cron = {
enable = true;
systemCronJobs = [
];
};
# Enable Podman
virtualisation.podman.enable = true;
virtualisation.podman.defaultNetwork.settings.dns_enabled = true;
# User account
users.users.numbus-admin = {
isNormalUser = true;
description = "Numbus Admin";
extraGroups = [ "networkmanager" "wheel" ];
uid = 1000;
initialPassword = "changeMe!";
};
# Login message
environment.loginShellInit = ''
if [ "$(id -u)" -eq 1000 ]; then
if [ -n "$SSH_TTY" ]; then
fastfetch
echo -e "\n\nWelcome to numbus.eu server !\n\n- This system is managed by NixOS\n- All changes are futile\n- Please consider buying support if you can't get your server running\n- Have a nice day and enjoy !"
fi
fi
'';
# Enable auto updates
system.autoUpgrade = {
enable = true;
allowReboot = true;
flake = inputs.self.outPath;
flags = [ "--print-build-logs" ];
dates = "02:00";
randomizedDelaySec = "45min";
};
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 7d";
};
# Enable NixOS flakes
nix.settings.experimental-features = [ "nix-command" "flakes" ];
# Enable auto nix-store optimization
nix.settings.auto-optimise-store = true;
system.stateVersion = "25.05";
}
+57
View File
@@ -0,0 +1,57 @@
{ lib, ... }:
{
disko.devices = {
# Boot disk LVM configuration
lvm_vg = {
pool = {
type = "lvm_vg";
lvs = {
root = {
size = "100%FREE";
content.type = "filesystem";
content.format = "btrfs";
content.mountpoint = "/";
};
swap = {
size = "16G";
content.type = "swap";
};
};
};
};
disk = {
# Boot disk
"system-1" = {
type = "disk";
device = "${BOOT_DISK_1_ID}";
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted-boot-1";
settings = {
keyFile = "/etc/secrets/disks/boot-disk-1";
allowDiscards = true;
};
content = {
type = "lvm_pv";
vg = "pool";
};
};
};
};
};
};
+74
View File
@@ -0,0 +1,74 @@
{ lib, ... }:
{
disko.devices = {
disk = {
"system-1" = {
type = "disk";
device = "${BOOT_DISK_1_ID}";
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
crypt_p1 = {
size = "100%";
content = {
type = "luks";
name = "crypted-boot-1";
settings = {
keyFile = "/etc/secrets/disks/boot-disk-2";
allowDiscards = true;
};
};
};
};
};
};
"system-2" = {
type = "disk";
device = "${BOOT_DISK_2_ID}";
content = {
type = "gpt";
partitions = {
crypt_p2 = {
size = "100%";
content = {
type = "luks";
name = "crypted-boot-2";
settings = {
allowDiscards = true;
};
content = {
type = "btrfs";
extraArgs = [
"-d raid1"
"/dev/mapper/crypted-boot-1"
];
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [
"rw"
"relatime"
"ssd"
];
};
"/swap" = {
mountpoint = "none";
swap.size = "16G";
};
};
};
};
};
};
};
};
+22
View File
@@ -0,0 +1,22 @@
"content-${j}" = {
type = "disk";
device = "${CONTENT_DISK_ID}";
content = {
type = "gpt";
partitions = {
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted-content-${j}";
settings.keyFile = "/etc/secrets/disks/content-disk-${j}";
content = {
type = "filesystem";
format = "xfs";
mountpoint = "/mnt/content-${j}";
};
};
};
};
};
};
+43
View File
@@ -0,0 +1,43 @@
};
# Data mirror configuration generated by deploy.sh
disk = {
"content-1" = {
type = "disk";
device = "${CONTENT_DISK_ID}";
content = {
type = "gpt";
partitions = {
"data-1" = {
size = "100%";
content = {
type = "luks";
name = "crypted-content-1";
settings.keyFile = "/etc/secrets/disks/content-disk-1";
};
};
};
};
};
"parity-1" = {
type = "disk";
device = "${PARITY_DISK_ID}";
content = {
type = "gpt";
partitions = {
"parity-1" = {
size = "100%";
content = {
type = "luks";
name = "crypted-parity-1";
settings.keyFile = "/etc/secrets/disks/parity-disk-1";
};
};
};
};
};
};
mdadm.raid-devices = [ "/dev/mapper/crypted-content-1" "/dev/mapper/crypted-parity-1" ];
fs."/dev/md/data-storage" = {
type = "xfs";
label = "data-storage";
mountpoint = "/mnt/data-storage";
+22
View File
@@ -0,0 +1,22 @@
"parity-${j}" = {
type = "disk";
device = "${PARITY_DISK_ID}";
content = {
type = "gpt";
partitions = {
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted-parity-${j}";
settings.keyFile = "/etc/secrets/disks/parity-disk-${j}";
content = {
type = "filesystem";
format = "xfs";
mountpoint = "/mnt/parity-${j}";
};
};
};
};
};
};
+124
View File
@@ -0,0 +1,124 @@
{ lib, utils, config, ... }:
let
inherit (lib)
head
optional
foldl'
nameValuePair
listToAttrs
optionals
concatStringsSep
sortOn
mkIf
mkEnableOption
mkOption
types
;
in
{
options = {
systemIdentity = {
enable = mkEnableOption "hashing of Luks values into PCR 15 and subsequent checks";
pcr15 = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
The expected value of PCR 15 after all luks partitions have been unlocked
Should be a 64 character hex string as ouput by the sha256 field of
'systemd-analyze pcrs 15 --json=short'
If set to null (the default) it will not check the value.
If the check fails the boot will abort and you will be dropped into an emergency shell, if enabled.
In ermergency shell type:
'systemctl disable check-pcrs'
'systemctl default'
to continue booting
'';
};
};
boot.initrd.luks.devices = lib.mkOption {
type =
with lib.types;
attrsOf (submodule {
config.crypttabExtraOpts = optionals config.systemIdentity.enable [
"tpm2-device=auto"
"tpm2-measure-pcr=yes"
];
});
};
};
config = mkIf config.systemIdentity.enable {
boot.kernelParams = [
"rd.luks=no"
];
boot.initrd.systemd.services =
{
check-pcrs = mkIf (config.systemIdentity.pcr15 != null) {
script = ''
echo "Checking PCR 15 value"
if [[ $(systemd-analyze pcrs 15 --json=short | jq -r ".[0].sha256") != "${config.systemIdentity.pcr15}" ]] ; then
echo "PCR 15 check failed"
exit 1
else
echo "PCR 15 check succeeded"
fi
'';
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
unitConfig.DefaultDependencies = "no";
after = [ "cryptsetup.target" ];
before = [ "sysroot.mount" ];
requiredBy = [ "sysroot.mount" ];
};
}
// (listToAttrs (
foldl' (
acc: attrs:
let
extraOpts = attrs.value.crypttabExtraOpts ++ (optional attrs.value.allowDiscards "discard");
cfg = config.boot.initrd.systemd;
in
[
(nameValuePair "cryptsetup-${attrs.name}" {
unitConfig = {
Description = "Cryptography setup for ${attrs.name}";
DefaultDependencies = "no";
IgnoreOnIsolate = true;
Conflicts = [ "umount.target" ];
BindsTo = "${utils.escapeSystemdPath attrs.value.device}.device";
};
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
TimeoutSec = "infinity";
KeyringMode = "shared";
OOMScoreAdjust = 500;
ImportCredential = "cryptsetup.*";
ExecStart = ''${cfg.package}/bin/systemd-cryptsetup attach '${attrs.name}' '${attrs.value.device}' '-' '${concatStringsSep "," extraOpts}' '';
ExecStop = ''${cfg.package}/bin/systemd-cryptsetup detach '${attrs.name}' '';
};
after =
[
"cryptsetup-pre.target"
"systemd-udevd-kernel.socket"
"${utils.escapeSystemdPath attrs.value.device}.device"
]
++ (optional cfg.tpm2.enable "systemd-tpm2-setup-early.service")
++ optional (acc != [ ]) "${(head acc).name}.service";
before = [
"blockdev@dev-mapper-${attrs.name}.target"
"cryptsetup.target"
"umount.target"
];
wants = [ "blockdev@dev-mapper-${attrs.name}.target" ];
requiredBy = [ "sysroot.mount" ];
})
]
++ acc
) [ ] (sortOn (x: x.name) (lib.attrsets.attrsToList config.boot.initrd.luks.devices))
));
};
}
+44
View File
@@ -0,0 +1,44 @@
{ config, lib, ... }:
let
### --> SnapRAID disks research
contentDiskMounts = lib.attrsets.attrNames (
lib.attrsets.filterAttrs (name: value: lib.strings.hasPrefix "/mnt/content-" name) config.fileSystems
);
parityDiskMounts = lib.attrsets.attrNames (
lib.attrsets.filterAttrs (name: value: lib.strings.hasPrefix "/mnt/parity-" name) config.fileSystems
);
snapraidDataDisks = lib.lists.foldl'
(acc: path: acc // { "d${toString (acc.i + 1)}" = path; i = acc.i + 1; })
{ i = 0; }
contentDiskMounts;
### SnapRAID disks research <--
in
### --> MergerFS setup
{
fileSystems."/mnt/data-storage" = {
device = "mergerfs";
fsType = "fuse";
options = [
"defaults"
"allow_other"
"use_ino"
"cache.files=off"
"moveonenospc=true"
"category.create=mfs"
"srcmounts=${lib.strings.concatStringsSep ":" contentDiskMounts}"
];
};
### MergerFS setup <--
### --> SnapRAID setup
services.snapraid = {
enable = true;
contentFiles = map (disk: "${disk}/snapraid.content") contentDiskMounts;
parityFiles = map (disk: "${disk}/snapraid.parity") parityDiskMounts;
dataDisks = builtins.removeAttrs snapraidDataDisks [ "i" ];
};
### SnapRAID setup <--
}
+17
View File
@@ -0,0 +1,17 @@
{ config, pkgs, lib, ... }:
### --> Disk spindown
systemd.services.hd-idle = {
description = "External HD spin down daemon";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
ExecStart =
let
idleTime = toString 1800;
hardDriveParameter = lib.strings.concatMapStringsSep " " (x: "-a ${x} -i ${idleTime}") hardDrives;
in
"${pkgs.hd-idle}/bin/hd-idle -i 0 ${hardDriveParameter}";
};
};
### Disk spindown <--
+51
View File
@@ -0,0 +1,51 @@
{
inputs = {
# Core Nixpkgs
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
# Diskpartitioning helper
disko.url = "github:nix-community/disko";
disko.inputs.nixpkgs.follows = "nixpkgs";
# Secrets handling
sops-nix.url = "github:Mic92/sops-nix";
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
# Power savings
autoaspm.url = "github:notthebee/AutoASPM";
autoaspm.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, disko, sops-nix, ... }@inputs: let
# System definition
system = "x86_64-linux";
pkgs = import nixpkgs {
inherit system;
config.allowUnfree = true;
};
# Helper: collect every *.nix file inside ./docker as a list
dockerModules = let
dir = ../docker;
entries = builtins.readDir dir;
names = builtins.attrNames entries;
nixNames = builtins.filter (n: builtins.match ".*\\.nix" n != null) names;
in map (name: "${dir}/${name}") nixNames;
in {
nixosConfigurations = {
numbus-server = nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = { inherit inputs; };
modules = [
# Diskpartitioning helper
disko.nixosModules.disko
# Secrets handling
sops-nix.nixosModules.sops
# Power savings
inputs.autoaspm.nixosModules.autoaspm
# Core host configuration
./configuration.nix
./hardware-configuration.nix
# Docker services automatically added from ./docker/*.nix
] ++ dockerModules;
};
};
};
}
+72
View File
@@ -0,0 +1,72 @@
{ config, pkgs, lib, ... }:
let
cfg = config.email;
in
### --> Mail notifications configuration
{
options.email = {
enable = lib.mkEnableOption "Email sending functionality";
fromAddress = lib.mkOption {
description = "The 'from' address";
type = lib.types.str;
default = "no-reply@${DOMAIN_NAME}";
};
toAddress = lib.mkOption {
description = "The 'to' address";
type = lib.types.str;
default = "${EMAIL_ADDRESS}";
};
smtpServer = lib.mkOption {
description = "The SMTP server address";
type = lib.types.str;
default = "${SENDER_EMAIL_DOMAIN}";
};
smtpUsername = lib.mkOption {
description = "The SMTP username";
type = lib.types.str;
default = "${SENDER_EMAIL_ADDRESS}";
};
smtpPasswordPath = lib.mkOption {
description = "Path to the secret containing SMTP password";
type = lib.types.path;
default = config.sops.secrets.sender_email_address_password.path;
};
};
config = lib.mkIf cfg.enable {
programs.msmtp = {
enable = true;
accounts.default = {
auth = true;
host = config.email.smtpServer;
from = config.email.fromAddress;
user = config.email.smtpUsername;
tls = true;
passwordeval = "${pkgs.coreutils}/bin/cat ${config.email.smtpPasswordPath}";
};
};
};
### Mail notifications configuration <--
### --> SMART disk heath
services.smartd = {
enable = true;
defaults.autodetected = "-a -o on -S on -s (S/../.././00|L/../../6/01) -n standby,q";
notifications = {
wall = {
enable = true;
};
mail = {
enable = true;
sender = config.email.fromAddress;
recipient = config.email.toAddress;
};
};
};
### SMART disk heath <--
}
+37
View File
@@ -0,0 +1,37 @@
{ config, pkgs, lib, ... }:
{
# Hostname
networking.hostName = "numbus-server";
# Enable networking and firewall
networking.interfaces.eth0.ipv4.addresses = [
{
address = "HOME_SERVER_IP";
prefixLength = 24;
}
];
networking.defaultGateway = "HOME_ROUTER_IP";
networking.nameservers = [ "HOME_SERVER_IP" "9.9.9.9" ];
networking.networkmanager.enable = true;
networking.nftables.enable = true;
networking.firewall.enable = true;
networking.nftables.tables.nat = {
family = "ip";
content = ''
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
tcp dport 80 redirect to :8080
tcp dport 443 redirect to :8443
tcp dport 53 redirect to :5353
udp dport 53 redirect to :5353
}
'';
};
# Open ports in the firewall
networking.firewall.allowPing = true;
networking.firewall.allowedTCPPorts = [ 53 80 443 ];
networking.firewall.allowedUDPPorts = [ 53 ];
}
+12
View File
@@ -0,0 +1,12 @@
{ config, pkgs, ... }:
let
libedgetpu = pkgs.callPackage ./libedgetpu.nix {};
gasket = config.boot.kernelPackages.callPackage ./gasket.nix {};
in
{
services.udev.packages = [ libedgetpu ];
users.groups.plugdev = {};
boot.extraModulePackages = [ gasket ];
}
@@ -0,0 +1,35 @@
{ 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 = [ lib.maintainers.kylehendricks ];
platforms = platforms.linux;
};
}
@@ -0,0 +1,59 @@
{ 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
'';
}
+76
View File
@@ -0,0 +1,76 @@
{ config, pkgs, ... }:
let
container_name = "frigate";
compose_file = "podman/frigate/compose.yaml";
config_dir = "/mnt/config/frigate";
data_dir = "/mnt/data/frigate";
in
{
config = {
environment.etc."${compose_file}".text =
/*
yaml
*/
''
services:
frigate:
image: ghcr.io/blakeblackshear/frigate:stable
container_name: ${container_name}
shm_size: "512MB"
networks:
hass_frontend:
hass_backend:
volumes:
- ${config_dir}:/config
- ${data_dir}/clips:/media/frigate/clips
- ${data_dir}/recordings:/media/frigate/recordings
- ${data_dir}/exports:/media/frigate/exports
- /etc/localtime:/etc/localtime:ro
- type: tmpfs
target: /tmp/cache
tmpfs:
size: 2000000000
environment:
FRIGATE_MQTT_USER: $FRIGATE_MQTT_USER
FRIGATE_MQTT_PASSWORD: $FRIGATE_MQTT_PASSWORD
# --- frigate devices --- #
labels:
- traefik.enable=true
- traefik.http.services.frigate.loadbalancer.server.port=8971
- traefik.http.services.frigate.loadbalancer.server.scheme=http
- traefik.http.routers.frigate-https.entrypoints=websecure
- traefik.http.routers.frigate-https.rule=Host(`${container_name}.$DOMAIN_NAME`)
- traefik.http.routers.frigate-https.tls=true
- traefik.http.routers.frigate-https.tls.certresolver=cloudflare
restart: unless-stopped
networks:
hass_backend:
external: true
hass_frontend:
external: true
'';
systemd.services.frigate = {
description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ];
requires = [ "network.target" ];
wantedBy = ["multi-user.target"];
path = [ pkgs.podman-compose ];
serviceConfig = {
Type = "exec";
# Pull the latest image before running
ExecStartPre = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} pull";
# Bring the service up
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure";
};
};
};
}
+90
View File
@@ -0,0 +1,90 @@
{ config, pkgs, ... }:
let
container_name = "gitea";
compose_file = "podman/gitea/compose.yaml";
config_dir = "/mnt/config/gitea";
data_dir = "/mnt/data/gitea";
in
{
config = {
environment.etc."${compose_file}".text =
/*
yaml
*/
''
services:
gitea:
image: gitea/gitea:latest
container_name: ${container_name}
networks:
gitea_frontend:
gitea_backend:
volumes:
- ${data_dir}:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=$POSTGRES_HOST:$POSTGRES_PORT
- GITEA__database__NAME=$DB_NAME
- GITEA__database__USER=$DB_USERNAME
- GITEA__database__PASSWD=$DB_PASSWORD
- GITEA__server__SSH_PORT=2424
- GITEA__server__ROOT_URL=gitea.$DOMAIN_NAME
labels:
- traefik.enable=true
- traefik.http.services.gitea.loadbalancer.server.port=3000
- traefik.http.services.gitea.loadbalancer.server.scheme=http
- traefik.http.routers.gitea-https.entrypoints=websecure
- traefik.http.routers.gitea-https.rule=Host(`${container_name}.$DOMAIN_NAME`)
- traefik.http.routers.gitea-https.tls=true
- traefik.http.routers.gitea-https.tls.certresolver=cloudflare
depends_on:
- gitea-database
restart: unless-stopped
gitea-database:
image: docker.io/library/postgres:17.5
container_name: gitea-database
environment:
- POSTGRES_USER=$DB_USERNAME
- POSTGRES_PASSWORD=$DB_PASSWORD
- POSTGRES_DB=$DB_NAME
networks:
gitea_backend:
volumes:
- ${config_dir}:/var/lib/postgresql/data
restart: unless-stopped
networks:
gitea_frontend:
external: true
gitea_backend:
external: true
'';
systemd.services.gitea = {
description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ];
requires = [ "network.target" ];
wantedBy = ["multi-user.target"];
path = [ pkgs.podman-compose ];
serviceConfig = {
Type = "exec";
# Pull the latest image before running
ExecStartPre = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} pull";
# Bring the service up
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure";
};
};
};
}
@@ -0,0 +1,76 @@
{ config, pkgs, ... }:
let
container_name = "home-assistant";
compose_file = "podman/home-assistant/compose.yaml";
config_dir_1 = "/mnt/config/home-assistant";
config_dir_2 = "/mnt/config/mqtt";
in
{
config = {
environment.etc."${compose_file}".text =
/*
yaml
*/
''
services:
home-assistant:
image: ghcr.io/home-assistant/home-assistant:latest
container_name: ${container_name}
networks:
hass_frontend:
hass_backend:
volumes:
- ${config_dir_1}:/config
- /etc/localtime:/etc/localtime:ro
- /run/dbus:/run/dbus:ro
# --- hass devices --- #
labels:
- traefik.enable=true
- traefik.http.services.home-assistant.loadbalancer.server.port=8123
- traefik.http.services.home-assistant.loadbalancer.server.scheme=http
- traefik.http.routers.home-assistant-https.entrypoints=websecure
- traefik.http.routers.home-assistant-https.rule=Host(`${container_name}.$DOMAIN_NAME`)
- traefik.http.routers.home-assistant-https.tls=true
- traefik.http.routers.home-assistant-https.tls.certresolver=cloudflare
restart: unless-stopped
frigate-mqtt:
image: eclipse-mosquitto
container_name: mqtt
user: 1000:1000
networks:
hass_backend:
volumes:
- ${config_dir_2}:/mosquitto
restart: unless-stopped
networks:
hass_backend:
external: true
hass_frontend:
external: true
'';
systemd.services.hass = {
description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ];
requires = [ "network.target" ];
wantedBy = ["multi-user.target"];
path = [ pkgs.podman-compose ];
serviceConfig = {
Type = "exec";
# Pull the latest image before running
ExecStartPre = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} pull";
# Bring the service up
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure";
};
};
};
}
+112
View File
@@ -0,0 +1,112 @@
{ config, pkgs, ... }:
let
container_name = "immich";
compose_file = "podman/immich/compose.yaml";
config_dir = "/mnt/config/immich";
data_dir = "/mnt/data/immich";
in
{
config = {
environment.etc."${compose_file}".text =
/*
yaml
*/
''
services:
immich-server:
image: ghcr.io/immich-app/immich-server:$IMMICH_VERSION
container_name: ${container_name}-server
networks:
immich_frontend:
immich_backend:
volumes:
- $UPLOAD_LOCATION:/data
- /etc/localtime:/etc/localtime:ro
# --- immich devices --- #
labels:
- traefik.enable=true
- traefik.http.services.immich.loadbalancer.server.port=2283
- traefik.http.services.immich.loadbalancer.server.scheme=http
- traefik.http.routers.immich-https.entrypoints=websecure
- traefik.http.routers.immich-https.rule=Host(`${container_name}.$DOMAIN_NAME`)
- traefik.http.routers.immich-https.tls=true
- traefik.http.routers.immich-https.tls.certresolver=cloudflare
env_file:
- .env
depends_on:
- immich-redis
- immich-database
restart: always
healthcheck:
disable: false
immich-machine-learning:
container_name: ${container_name}-machine-learning
image: ghcr.io/immich-app/immich-machine-learning:$IMMICH_VERSION
networks:
immich_backend:
volumes:
- ${config_dir}/models:/cache
env_file:
- .env
restart: always
healthcheck:
disable: false
immich-redis:
container_name: ${container_name}-redis
image: docker.io/valkey/valkey:8-bookworm@sha256:a137a2b60aca1a75130022d6bb96af423fefae4eb55faf395732db3544803280
networks:
immich_backend:
healthcheck:
test: redis-cli ping || exit 1
restart: always
immich-database:
container_name: ${container_name}-database
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:32324a2f41df5de9efe1af166b7008c3f55646f8d0e00d9550c16c9822366b4a
networks:
immich_backend:
shm_size: 128mb
volumes:
# Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
- $DB_DATA_LOCATION:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: $DB_PASSWORD
POSTGRES_USER: $DB_USERNAME
POSTGRES_DB: $DB_DATABASE_NAME
POSTGRES_INITDB_ARGS: '--data-checksums'
restart: always
healthcheck:
disable: false
networks:
immich_backend:
external: true
immich_frontend:
external: true
'';
systemd.services.immich = {
description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ];
requires = [ "network.target" ];
wantedBy = ["multi-user.target"];
path = [ pkgs.podman-compose ];
serviceConfig = {
Type = "exec";
# Pull the latest image before running
ExecStartPre = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} pull";
# Bring the service up
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure";
};
};
};
}
+55
View File
@@ -0,0 +1,55 @@
{ config, pkgs, ... }:
let
container_name = "it-tools";
compose_file = "podman/it-tools/compose.yaml";
in
{
config = {
environment.etc."${compose_file}".text =
/*
yaml
*/
''
services:
it-tools:
container_name: ${container_name}
image: corentinth/it-tools
networks:
it-tools:
labels:
- traefik.enable=true
- traefik.http.services.it-tools.loadbalancer.server.port=80
- traefik.http.services.it-tools.loadbalancer.server.scheme=http
- traefik.http.routers.it-tools-https.entrypoints=websecure
- traefik.http.routers.it-tools-https.rule=Host(`${container_name}.$DOMAIN_NAME`)
- traefik.http.routers.it-tools-https.tls=true
- traefik.http.routers.it-tools-https.tls.certresolver=cloudflare
restart: unless-stopped
networks:
it-tools:
external: true
'';
systemd.services.it-tools = {
description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ];
requires = [ "network.target" ];
wantedBy = ["multi-user.target"];
path = [ pkgs.podman-compose ];
serviceConfig = {
Type = "exec";
# Pull the latest image before running
ExecStartPre = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} pull";
# Bring the service up
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure";
};
};
};
}
+78
View File
@@ -0,0 +1,78 @@
{ config, pkgs, ... }:
let
container_name = "nextcloud";
compose_file = "podman/nextcloud/compose.yaml";
data_dir = "/mnt/data/nextcloud";
in
{
config = {
environment.etc."${compose_file}".text =
/*
yaml
*/
''
services:
nextcloud-aio-mastercontainer:
image: nextcloud/all-in-one:latest
container_name: ${container_name}-aio-mastercontainer
networks:
nextcloud-aio:
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
APACHE_PORT: 11000
NEXTCLOUD_TRUSTED_DOMAINS: nextcloud.$DOMAIN_NAME nextcloud-aio.$DOMAIN_NAME
TRUSTED_PROXIES: 172.16.1.253
APACHE_IP_BINDING: 127.0.0.1
NEXTCLOUD_DATADIR: ${data_dir}
NEXTCLOUD_ENABLE_DRI_DEVICE: $NEXTCLOUD_ENABLE_DRI_DEVICE
NEXTCLOUD_UPLOAD_LIMIT: 16G
NEXTCLOUD_MAX_TIME: 3600
NEXTCLOUD_MEMORY_LIMIT: 2048M
SKIP_DOMAIN_VALIDATION: true
NEXTCLOUD_ADDITIONAL_APKS: imagemagick
NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS: imagick
labels:
- traefik.enable=true
- traefik.http.services.nextcloud-aio.loadbalancer.server.port=8080
- traefik.http.services.nextcloud-aio.loadbalancer.server.scheme=https
- traefik.http.routers.nextcloud-aio-https.entrypoints=websecure
- traefik.http.routers.nextcloud-aio-https.rule=Host(`${container_name}-aio.$DOMAIN_NAME`)
- traefik.http.routers.nextcloud-aio-https.tls=true
- traefik.http.routers.nextcloud-aio-https.tls.certresolver=cloudflare
init: true
restart: always
networks:
nextcloud-aio:
external: true
volumes:
nextcloud_aio_mastercontainer:
name: nextcloud_aio_mastercontainer
'';
systemd.services.nextcloud = {
description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ];
requires = [ "network.target" ];
wantedBy = ["multi-user.target"];
path = [ pkgs.podman-compose ];
serviceConfig = {
Type = "exec";
# Pull the latest image before running
ExecStartPre = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} pull";
# Bring the service up
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure";
};
};
};
}
+107
View File
@@ -0,0 +1,107 @@
{ config, pkgs, ... }:
let
container_name = "passbolt";
compose_file = "podman/passbolt/compose.yaml";
in
{
config = {
environment.etc."${compose_file}".text =
/*
yaml
*/
''
services:
passbolt:
image: passbolt/passbolt:latest-ce-non-root
container_name: ${container_name}
networks:
passbolt_frontend:
passbolt_backend:
volumes:
- passbolt-gpg:/etc/passbolt/gpg
- passbolt-jwt:/etc/passbolt/jwt
environment:
APP_DEFAULT_TIMEZONE: $TZ
APP_FULL_BASE_URL: https://passbolt.$DOMAIN_NAME
DATASOURCES_DEFAULT_HOST: "passbolt-database"
DATASOURCES_DEFAULT_USERNAME: $PASSBOLT_MYSQL_USER
DATASOURCES_DEFAULT_PASSWORD: $PASSBOLT_MYSQL_PASSWORD
DATASOURCES_DEFAULT_DATABASE: $PASSBOLT_MYSQL_DATABASE
EMAIL_DEFAULT_FROM_NAME: "Passbolt"
EMAIL_TRANSPORT_DEFAULT_HOST: $SENDER_EMAIL_DOMAIN
EMAIL_TRANSPORT_DEFAULT_PORT: $SENDER_EMAIL_PORT
EMAIL_TRANSPORT_DEFAULT_USERNAME: $SENDER_EMAIL_ADDRESS
EMAIL_TRANSPORT_DEFAULT_PASSWORD: $SENDER_EMAIL_ADDRESS_PASSWORD
EMAIL_TRANSPORT_DEFAULT_TLS: true
EMAIL_DEFAULT_FROM: $EMAIL_ADDRESS
PASSBOLT_SSL_FORCE: true
labels:
- traefik.enable=true
- traefik.http.services.passbolt.loadbalancer.server.port=4433
- traefik.http.services.passbolt.loadbalancer.server.scheme=https
- traefik.http.routers.passbolt-https.entrypoints=websecure
- traefik.http.routers.passbolt-https.rule=Host(`passbolt.$DOMAIN_NAME`)
- traefik.http.routers.passbolt-https.tls=true
- traefik.http.routers.passbolt-https.tls.certresolver=cloudflare
command:
[
"/usr/bin/wait-for.sh",
"-t",
"0",
"passbolt-database:3306",
"--",
"/docker-entrypoint.sh",
]
depends_on:
- passbolt-database
restart: unless-stopped
passbolt-database:
image: mariadb:11.3
container_name: ${container_name}-database
networks:
passbolt_backend:
volumes:
- passbolt-database:/var/lib/mysql
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "true"
MYSQL_DATABASE: $PASSBOLT_MYSQL_DATABASE
MYSQL_USER: $PASSBOLT_MYSQL_USER
MYSQL_PASSWORD: $PASSBOLT_MYSQL_PASSWORD
restart: unless-stopped
networks:
passbolt_backend:
external: true
passbolt_frontend:
external: true
volumes:
passbolt-database:
passbolt-gpg:
passbolt-jwt:
'';
systemd.services.passbolt = {
description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ];
requires = [ "network.target" ];
wantedBy = ["multi-user.target"];
path = [ pkgs.podman-compose ];
serviceConfig = {
Type = "exec";
# Pull the latest image before running
ExecStartPre = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} pull";
# Bring the service up
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure";
};
};
};
}
+85
View File
@@ -0,0 +1,85 @@
{ config, pkgs, ... }:
let
container_name = "pihole";
compose_file = "podman/pihole/compose.yaml";
config_dir = "/mnt/config/pihole";
in
{
config = {
environment.etc."${compose_file}".text =
/*
yaml
*/
''
services:
pihole:
image: pihole/pihole:latest
container_name: ${container_name}
networks:
pihole:
ports:
# DNS Ports
- "53:53/tcp"
- "53:53/udp"
environment:
TZ: $TZ
FTLCONF_webserver_api_password: $FTLCONF_webserver_api_password
FTLCONF_dns_listeningMode: all
FTLCONF_dns_revServers: true,$HOME_ROUTER_SUBNET,$HOME_ROUTER_IP,home
FTLCONF_dns_domain_name: home
FTLCONF_dns_domain_local: true
FTLCONF_dns_hosts: |
$HOME_SERVER_IP dns.$DOMAIN_NAME
$HOME_SERVER_IP reverse.$DOMAIN_NAME
$HOME_SERVER_IP nextcloud.$DOMAIN_NAME
$HOME_SERVER_IP nextcloud-aio.$DOMAIN_NAME
$HOME_SERVER_IP hass.$DOMAIN_NAME
$HOME_SERVER_IP passbolt.$DOMAIN_NAME
FTLCONF_dhcp_active: false
FTLCONF_dns_upstreams: 9.9.9.11;149.112.112.11
PIHOLE_UID: 1000
PIHOLE_GID: 1000
volumes:
- ${config_dir}:/etc/pihole
cap_add:
- SYS_TIME
- SYS_NICE
labels:
- traefik.enable=true
- traefik.http.services.pihole.loadbalancer.server.port=443
- traefik.http.services.pihole.loadbalancer.server.scheme=https
- traefik.http.routers.pihole-https.entrypoints=websecure
- traefik.http.routers.pihole-https.rule=Host(`${container_name}.$DOMAIN_NAME`)
- traefik.http.routers.pihole-https.tls=true
- traefik.http.routers.pihole-https.tls.certresolver=cloudflare
restart: unless-stopped
networks:
pihole:
external: true
'';
systemd.services.pihole = {
description = "Podman container : ${container_name}";
after = [ "network.target" "traefik.service" ];
requires = [ "network.target" ];
wantedBy = ["multi-user.target"];
path = [ pkgs.podman-compose ];
serviceConfig = {
Type = "exec";
# Pull the latest image before running
ExecStartPre = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} pull";
# Bring the service up
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure";
};
};
};
}
+154
View File
@@ -0,0 +1,154 @@
{ config, pkgs, ... }:
let
container_name = "traefik";
compose_file = "podman/traefik/compose.yaml";
config_dir = "/mnt/config/traefik";
in
{
config = {
environment.etc."${compose_file}".text =
/*
yaml
*/
''
services:
traefik:
image: docker.io/library/traefik:latest
container_name: ${container_name}
networks:
nextcloud-aio:
ipv4_address: 172.16.1.253
passbolt_frontend:
ipv4_address: 172.16.20.253
pihole:
ipv4_address: 172.16.3.253
hass_frontend:
ipv4_address: 172.16.40.253
immich_frontend:
ipv4_address: 172.16.50.253
gitea_frontend:
ipv4_address: 172.16.60.253
it-tools:
ipv4_address: 172.16.7.253
ports:
- 80:80
- 443:443
volumes:
- /run/user/1000/podman/podman.sock:/run/docker.sock:ro
- ${config_dir}/rules/:/etc/traefik/conf/:ro
- ${config_dir}/traefik.yaml:/etc/traefik/traefik.yaml:ro
- ${config_dir}/certs/:/var/traefik/certs/:rw
environment:
- CF_DNS_API_TOKEN=$CF_DNS_API_TOKEN
labels:
- traefik.enable=true
- traefik.http.services.traefik.loadbalancer.server.port=8080
- traefik.http.services.traefik.loadbalancer.server.scheme=http
- traefik.http.routers.traefik-https.entrypoints=websecure
- traefik.http.routers.traefik-https.rule=Host(`${container_name}.$DOMAIN_NAME`)
- traefik.http.routers.traefik-https.tls=true
- traefik.http.routers.traefik-https.tls.certresolver=cloudflare
restart: always
networks:
nextcloud-aio:
name: nextcloud-aio
driver: bridge
ipam:
config:
- subnet: "172.16.1.0/24"
gateway: "172.16.1.254"
passbolt_backend:
name: passbolt_backend
driver: bridge
ipam:
config:
- subnet: "172.16.2.0/24"
gateway: "172.16.2.254"
passbolt_frontend:
name: passbolt_frontend
driver: bridge
ipam:
config:
- subnet: "172.16.20.0/24"
gateway: "172.16.20.254"
pihole:
name: pihole
driver: bridge
ipam:
config:
- subnet: "172.16.3.0/24"
gateway: "172.16.3.254"
hass_backend:
name: hass_backend
driver: bridge
ipam:
config:
- subnet: "172.16.4.0/24"
gateway: "172.16.4.254"
hass_frontend:
name: hass_frontend
driver: bridge
ipam:
config:
- subnet: "172.16.40.0/24"
gateway: "172.16.40.254"
immich_backend:
name: immich_backend
driver: bridge
ipam:
config:
- subnet: "172.16.5.0/24"
gateway: "172.16.5.254"
immich_frontend:
name: immich_frontend
driver: bridge
ipam:
config:
- subnet: "172.16.50.0/24"
gateway: "172.16.50.254"
gitea_backend:
name: gitea_backend
driver: bridge
ipam:
config:
- subnet: "172.16.6.0/24"
gateway: "172.16.6.254"
gitea_frontend:
name: gitea_frontend
driver: bridge
ipam:
config:
- subnet: "172.16.60.0/24"
gateway: "172.16.60.254"
it-tools:
name: it-tools
driver: bridge
ipam:
config:
- subnet: "172.16.7.0/24"
gateway: "172.16.7.254"
'';
systemd.services.traefik = {
description = "Podman container : ${container_name}";
after = [ "network.target" "docker.socket" ];
requires = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
path = [ pkgs.podman-compose ];
serviceConfig = {
Type = "exec";
# Pull the latest image before running
ExecStartPre = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} pull";
# Bring the service up
ExecStart = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} up --remove-orphans";
# Take it down gracefully
ExecStop = "${pkgs.podman-compose}/bin/podman-compose -f /etc/${compose_file} down";
Restart = "on-failure";
};
};
};
}
+9
View File
@@ -0,0 +1,9 @@
# .sops.yaml
keys:
- &primary $SOPS_PUBLIC_KEY
creation_rules:
- path_regex: secrets/secrets.yaml$
key_groups:
- age:
- *primary
@@ -0,0 +1,68 @@
ssh_public_keys: "${SSH_PUBLIC_KEY}"
sender_email_address_password: "${SENDER_EMAIL_ADDRESS_PASSWORD}"
podman:
frigate: |
DOMAIN_NAME="${DOMAIN_NAME}"
FRIGATE_MQTT_USER="${HOME_ASSISTANT_MQTT_USER}"
FRIGATE_MQTT_PASSWORD="${HOME_ASSISTANT_MQTT_PASSWORD}"
gitea: |
DOMAIN_NAME="${DOMAIN_NAME}"
DB_NAME="${GITEA_DB_NAME}"
DB_USERNAME="${GITEA_DB_USERNAME}"
DB_PASSWORD="${GITEA_DB_PASSWORD}"
POSTGRES_HOST="gitea-database"
POSTGRES_PORT="5432"
home_assistant: |
DOMAIN_NAME="${DOMAIN_NAME}"
HOME_ASSISTANT_MQTT_USER="${HOME_ASSISTANT_MQTT_USER}"
HOME_ASSISTANT_MQTT_PASSWORD="${HOME_ASSISTANT_MQTT_PASSWORD}"
immich: |
DOMAIN_NAME="${DOMAIN_NAME}"
DB_DATABASE_NAME="${IMMICH_DB_NAME}"
DB_USERNAME="${IMMICH_DB_USERNAME}"
DB_PASSWORD="${IMMICH_DB_PASSWORD}"
IMMICH_VERSION="release"
IMMICH_TRUSTED_PROXIES="172.16.50.253"
REDIS_HOSTNAME="immich-redis"
DB_HOSTNAME="immich-database"
UPLOAD_LOCATION="/mnt/data/immich"
DB_DATA_LOCATION="/mnt/config/immich/database"
TZ="Europe/Paris"
it_tools: |
DOMAIN_NAME="${DOMAIN_NAME}"
nextcloud: |
DOMAIN_NAME="${DOMAIN_NAME}"
NEXTCLOUD_ENABLE_DRI_DEVICE="${TARGET_GRAPHICS}"
passbolt: |
DOMAIN_NAME="${DOMAIN_NAME}"
PASSBOLT_MYSQL_DATABASE="${PASSBOLT_DB_NAME}"
PASSBOLT_MYSQL_USER="${PASSBOLT_DB_USERNAME}"
PASSBOLT_MYSQL_PASSWORD="${PASSBOLT_DB_PASSWORD}"
SENDER_EMAIL_ADDRESS="${SENDER_EMAIL_ADDRESS}"
SENDER_EMAIL_ADDRESS_PASSWORD="${SENDER_EMAIL_ADDRESS_PASSWORD}"
SENDER_EMAIL_DOMAIN="${SENDER_EMAIL_DOMAIN}"
SENDER_EMAIL_PORT="${SENDER_EMAIL_PORT}"
EMAIL_ADDRESS="${EMAIL_ADDRESS}"
TZ="Europe/Paris"
pi_hole: |
DOMAIN_NAME="${DOMAIN_NAME}"
HOME_ROUTER_SUBNET="${HOME_ROUTER_SUBNET}"
HOME_ROUTER_IP="${HOME_ROUTER_IP}"
HOME_SERVER_IP="${HOME_SERVER_IP}"
FTLCONF_webserver_api_password=$FTLCONF_WEBSERVER_PASSWORD
TZ="Europe/Paris"
traefik: |
DOMAIN_NAME="${DOMAIN_NAME}"
CF_DNS_API_TOKEN="${CF_DNS_API_TOKEN}"
disks:
content-disk-1: "${CONTENT_DISK_1_KEY:-Undefined}"
content-disk-2: "${CONTENT_DISK_2_KEY:-Undefined}"
content-disk-3: "${CONTENT_DISK_3_KEY:-Undefined}"
content-disk-4: "${CONTENT_DISK_4_KEY:-Undefined}"
content-disk-5: "${CONTENT_DISK_5_KEY:-Undefined}"
content-disk-6: "${CONTENT_DISK_6_KEY:-Undefined}"
parity-disk-1: "${PARITY_DISK_1_KEY:-Undefined}"
parity-disk-2: "${PARITY_DISK_2_KEY:-Undefined}"
parity-disk-3: "${PARITY_DISK_3_KEY:-Undefined}"