Files
nix/modules/gameservers/valheim/default.nix
T
2026-09-10 13:23:15 -05:00

149 lines
4.5 KiB
Nix

{
pkgs,
config,
lib,
inputs,
...
}: let
nixservice = "podman-valheim";
service = "valheim";
cfg = config.gameservers.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.gameservers.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 2456;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/gameservers/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
motd_gs = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
default = ["podman-valheim"];
};
backup = lib.mkOption {
type = lib.types.bool;
default = false;
description = "enable backups for ${service}";
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/var/backup/gameservers/valheim";
description = "path to take hourly backups to with borg!";
};
offsite_user = lib.mkOption {
type = lib.types.str;
default = "lifeboat";
description = "user to connect to offsite host with";
};
offsite_target = lib.mkOption {
type = lib.types.str;
default = "lifeboat.holocron.blue";
description = "ip or domain for offsite backups";
};
offsite_dir = lib.mkOption {
type = lib.types.str;
default = "lifeboat/holocron/archives/gameservers";
description = "path to rsync offsite backups to";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [];
};
virtualisation.oci-containers.containers = {
${service} = {
image = "ghcr.io/community-valheim-tools/valheim-server";
autoStart = true;
extraOptions = [
"--cap-add=sys_nice"
"--stop-timeout=120"
];
ports = [
"2456-2457:2456-2457/udp"
"2456:80/tcp"
];
volumes = [
"${cfg.data_dir}/config:/config"
"${cfg.data_dir}/data:/opt/valheim"
];
environment = {
SERVER_NAME = "recpro";
SERVER_PASS = "recoil727pro";
WORLD_NAME = "";
TZ = homelab.tz;
PUID = toString config.users.users.${service}.uid;
PGID = toString config.users.groups.${service}.gid;
};
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
};
# open firewall
networking.firewall.allowedTCPPorts = [cfg.port];
networking.firewall.allowedUDPPorts = [2456 2457];
# backups valhiem with borg!
services.borgbackup.jobs.${service} = {
archiveBaseName = service;
repo = cfg.backup_repo;
paths = cfg.data_dir;
compression = "auto,zstd";
#preHook = "systemctl start mysql-backup.service";
postHook = ''
${pkgs.sshpass}/bin/sshpass -f ${sec."lifeboat_rsync".path} \
${pkgs.rsync}/bin/rsync -aHAX --partial --numeric-ids --info=progress2,name1,stats2 --delete \
-e "ssh -o StrictHostKeyChecking=no" \
${toString cfg.backup_repo} \
${cfg.offsite_user}@${cfg.offsite_target}::${cfg.offsite_dir}
'';
startAt = "*-*-* *:00:00";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${config.sops.secrets."borg_passwd".path}";
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
hourly = 24;
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
};
}