2024-05-31 10:36:14 +02:00
|
|
|
{ pkgs, state-version, inputs, ... }:
|
|
|
|
let hostVolumeDir = "/var/lib/container-storage/";
|
|
|
|
hostBackupDir = "/mnt/backup";
|
|
|
|
lib = import ./lib.nix { inherit pkgs; } // inputs // {
|
|
|
|
inherit hostVolumeDir hostBackupDir;
|
|
|
|
};
|
2024-05-25 15:12:56 +02:00
|
|
|
services = with builtins;
|
2024-05-24 22:30:04 +02:00
|
|
|
let services_no_ip =
|
2024-05-25 15:12:56 +02:00
|
|
|
map (s: import (./services + "/${s}") { inherit pkgs lib; })
|
2024-05-24 22:30:04 +02:00
|
|
|
(filter (s: ! isNull (match ".*\.nix" s))
|
|
|
|
(attrNames (readDir ./services)));
|
|
|
|
in genList (i: elemAt services_no_ip i // { ip = "10.10.0.${toString (i+2)}"; }) (length services_no_ip);
|
|
|
|
|
|
|
|
hostIp = "10.10.0.1";
|
2024-05-23 10:59:42 +02:00
|
|
|
in
|
2024-05-23 12:08:06 +02:00
|
|
|
|
2024-05-24 22:30:04 +02:00
|
|
|
{
|
|
|
|
containers =
|
2024-05-25 01:01:07 +02:00
|
|
|
lib.flatMap ({ name, config, ip, ports, volumes, ... }:
|
2024-05-23 10:59:42 +02:00
|
|
|
{
|
2024-05-24 22:30:04 +02:00
|
|
|
${name} = {
|
|
|
|
autoStart = true;
|
|
|
|
ephemeral = true;
|
|
|
|
privateNetwork = true;
|
|
|
|
hostAddress = hostIp;
|
|
|
|
localAddress = ip;
|
2024-05-31 10:36:14 +02:00
|
|
|
bindMounts = lib.flatMap (volume@{ name, mountPoint, ... }:
|
2024-05-25 01:01:07 +02:00
|
|
|
{
|
|
|
|
"${name}" = {
|
|
|
|
inherit mountPoint;
|
|
|
|
isReadOnly = if volume ? readOnly then volume.readOnly else false;
|
|
|
|
hostPath = hostVolumeDir + name;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
) volumes;
|
2024-05-25 15:12:56 +02:00
|
|
|
forwardPorts = builtins.map ({ container, host, proto }: {
|
|
|
|
containerPort = container;
|
|
|
|
hostPort = host;
|
|
|
|
protocol = proto;
|
|
|
|
}) ports.forward;
|
2024-05-24 22:30:04 +02:00
|
|
|
config = config // {
|
|
|
|
boot.isContainer = true;
|
|
|
|
|
|
|
|
networking = {
|
|
|
|
hostName = "${name}";
|
|
|
|
|
2024-05-25 01:01:07 +02:00
|
|
|
hosts = lib.flatMap ({ name, ip, ...}:
|
2024-05-24 22:30:04 +02:00
|
|
|
{ "${ip}" = [ "${name}.containers" "${name}" ]; }
|
|
|
|
) services;
|
|
|
|
|
|
|
|
firewall.enable = true;
|
|
|
|
firewall.allowedTCPPorts = ports.tcp;
|
|
|
|
firewall.allowedUDPPorts = ports.udp;
|
|
|
|
};
|
|
|
|
|
2024-06-20 16:51:29 +02:00
|
|
|
security.sudo.enable = false;
|
|
|
|
|
2024-05-24 22:30:04 +02:00
|
|
|
system.stateVersion = state-version;
|
|
|
|
};
|
2024-05-24 11:13:36 +02:00
|
|
|
};
|
2024-05-23 12:08:06 +02:00
|
|
|
}
|
2024-05-24 22:30:04 +02:00
|
|
|
) services;
|
|
|
|
}
|
2024-05-23 12:08:06 +02:00
|
|
|
|
|
|
|
//
|
2024-05-23 10:59:42 +02:00
|
|
|
|
2024-05-25 15:12:56 +02:00
|
|
|
|
2024-05-23 12:08:06 +02:00
|
|
|
{
|
2024-05-25 01:01:07 +02:00
|
|
|
|
2024-05-25 15:12:56 +02:00
|
|
|
imports = builtins.map (service:
|
|
|
|
if service ? hostConfig
|
|
|
|
then service.hostConfig
|
|
|
|
else {}) services;
|
|
|
|
|
2024-05-25 01:01:07 +02:00
|
|
|
system.activationScripts.makeBindMounts = with builtins;
|
|
|
|
lib.flatMapS (name: ''
|
|
|
|
mkdir -p ${hostVolumeDir + name}
|
|
|
|
'')
|
|
|
|
(concatMap (s: map (v: v.name) s.volumes) services);
|
|
|
|
|
2024-05-23 10:59:42 +02:00
|
|
|
# [NGINX]
|
|
|
|
services.nginx = {
|
|
|
|
enable = true;
|
|
|
|
recommendedProxySettings = true;
|
2024-05-31 10:36:14 +02:00
|
|
|
recommendedOptimisation = true;
|
2024-05-23 12:08:06 +02:00
|
|
|
virtualHosts =
|
2024-05-25 01:01:07 +02:00
|
|
|
lib.flatMap ({ ports, hosts, ip, ... }:
|
|
|
|
lib.flatMap (host:
|
2024-05-24 22:30:04 +02:00
|
|
|
if (builtins.isNull ports.http)
|
|
|
|
then {}
|
|
|
|
else {
|
|
|
|
"${host}" = {
|
2024-05-31 10:36:14 +02:00
|
|
|
# enableACME = true;
|
2024-05-24 22:30:04 +02:00
|
|
|
locations."/".proxyPass =
|
|
|
|
"http://${ip}:${builtins.toString ports.http}";
|
|
|
|
};
|
|
|
|
}
|
2024-05-23 12:08:06 +02:00
|
|
|
) hosts
|
|
|
|
) services;
|
2024-05-23 10:59:42 +02:00
|
|
|
};
|
|
|
|
|
2024-05-24 22:30:04 +02:00
|
|
|
# [SSHD]
|
|
|
|
services.openssh = {
|
|
|
|
enable = true;
|
2024-05-25 15:12:56 +02:00
|
|
|
ports = [ 222 ];
|
2024-05-24 22:30:04 +02:00
|
|
|
settings = {
|
|
|
|
PermitRootLogin = "no";
|
|
|
|
PasswordAuthentication = false;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-05-23 10:59:42 +02:00
|
|
|
# [NETWORK]
|
2024-05-24 22:30:04 +02:00
|
|
|
networking = {
|
|
|
|
hostName = "cafe";
|
|
|
|
|
2024-05-25 15:12:56 +02:00
|
|
|
firewall.allowedTCPPorts = [ 22 222 80 443 ];
|
2024-05-24 22:30:04 +02:00
|
|
|
firewall.allowedUDPPorts = [ ];
|
|
|
|
|
|
|
|
nat = {
|
|
|
|
enable = true;
|
|
|
|
internalInterfaces = ["ve-+"];
|
|
|
|
externalInterface = "lo";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
# [USER]
|
|
|
|
users.users.admin = {
|
|
|
|
isNormalUser = true;
|
|
|
|
group = "admin";
|
|
|
|
extraGroups = [ "wheel" ];
|
|
|
|
hashedPassword = pkgs.lib.removeSuffix "\n"
|
|
|
|
(builtins.readFile ./secrets/admin_password);
|
|
|
|
openssh.authorizedKeys.keyFiles = [ ./secrets/id_ed25519.pub ];
|
|
|
|
};
|
2024-05-23 11:21:24 +02:00
|
|
|
users.groups.admin = {};
|
2024-05-23 10:59:42 +02:00
|
|
|
|
2024-05-24 22:30:04 +02:00
|
|
|
# [SOFTWARE]
|
|
|
|
programs.bash.interactiveShellInit = ''
|
|
|
|
set -o vi
|
2024-05-31 10:36:14 +02:00
|
|
|
alias doas=sudo
|
2024-05-24 22:30:04 +02:00
|
|
|
'';
|
|
|
|
|
|
|
|
# [NIX]
|
|
|
|
nix = {
|
|
|
|
settings = {
|
|
|
|
experimental-features = [ "nix-command" "flakes" ];
|
|
|
|
auto-optimise-store = true;
|
2024-06-20 14:56:34 +02:00
|
|
|
trusted-users = [ "@wheel" ];
|
2024-05-24 22:30:04 +02:00
|
|
|
};
|
|
|
|
gc = {
|
|
|
|
automatic = true;
|
|
|
|
dates = "monthly";
|
|
|
|
options = "--delete-older-than 30d";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-05-31 10:36:14 +02:00
|
|
|
# [BACKUPS]
|
|
|
|
systemd = {
|
|
|
|
timers.backup-container-storage = {
|
|
|
|
enable = true;
|
|
|
|
description = "Backup container volumes";
|
|
|
|
wantedBy = ["multi-user.target"];
|
|
|
|
timerConfig = {
|
|
|
|
OnCalendar = "*-*-* 02:00:00";
|
|
|
|
Unit = "backup-container-storage.service";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
services.backup-container-storage = {
|
|
|
|
description = "Backup container volumes";
|
|
|
|
startLimitBurst = 1;
|
|
|
|
startLimitIntervalSec = 1800;
|
|
|
|
script = with builtins; let
|
|
|
|
volumes = concatMap (s: s.volumes) services;
|
|
|
|
backupVolumes = filter (v: if v ? backup then v.backup else true) volumes;
|
|
|
|
backupMountpoints = map (v: hostVolumeDir + v.name) backupVolumes;
|
|
|
|
in ''
|
|
|
|
PATH="$PATH:${pkgs.lib.makeBinPath [
|
|
|
|
pkgs.gnutar
|
|
|
|
pkgs.gzip
|
|
|
|
]}"
|
|
|
|
mountpoint ${hostBackupDir} || {
|
|
|
|
echo "${hostBackupDir} is not a mountpoint!"
|
|
|
|
exit 7
|
|
|
|
}
|
|
|
|
echo "Starting Backup"
|
|
|
|
# 7 days of backups
|
|
|
|
rm -rf ${hostBackupDir}/backup.7.tgz
|
|
|
|
for x in $(seq 6); do
|
|
|
|
mv "${hostBackupDir}/backup.$x.tgz" "${hostBackupDir}/backup.$((x+1)).tgz"
|
|
|
|
done
|
|
|
|
tar -zcvpf ${hostBackupDir}/backup.1.tgz ${toString backupMountpoints}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
# [SECURITY]
|
|
|
|
security.sudo.execWheelOnly = true;
|
2024-05-24 22:30:04 +02:00
|
|
|
|
2024-05-24 11:13:36 +02:00
|
|
|
system.stateVersion = state-version;
|
2024-05-23 10:59:42 +02:00
|
|
|
|
|
|
|
}
|