Is there a way I can set a create a template for a service like this? Minecraft servers aren’t that different and the only differences arent that huge.
If the thing changing is one string, you can use systemd template units (systemd: Template unit files - Fedora Magazine), although be warned that declaring them in NixOS requires a bit of tweaking to make them work as intended.
If you need something more complicated, you can do the templating in Nix by writing a custom function to create the unit defintion:
{ pkgs, ... }:
let
mkMinecraftServerService = {name, user}: {
enable = true;
unitConfig = {
Description = "${name}'s minecraft server";
Wants = "network-online.target";
After = "network-online.target";
};
serviceConfig = {
User = user;
WorkingDirectory = "/home/${user}/minecraft/${name}/";
ExecStart = "${pkgs.jre}/bin/java -jar server.jar";
};
wantedBy = [ "multi-user.target" ];
};
in {
systemd.services = {
alice = mkMinecraftServerService { name = "alice"; user = "alice"; };
bob = mkMinecraftServerService { name = "bob"; user = "bob"; };
bobModded = mkMinectaftService { name = "moddedBob"; user = "bob"; };
};
}
{ ... }:
{
systemd.services."minecraft@" = {
description = "%i's minecraft server";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after [ "network-online.target" ];
serviceConfig = {
DynamicUser = true; # or set a user if wanted/needed
StateDirectory = "minecraft/%i";
StateDirectoryMode = "0775";
WorkingDirectory = "%S/minecraft/%i";
ExecStart = "${pkgs.jre}/bin/java -jar server.jar";
};
};
}
then you can spin them up dynamically via systemctl start minecarft@timmy.service, or have them start automatically via some syntax that is escaping me at the moment
systemctl enable doesn’t work on NixOS, because /etc/systemd/system is a symlink into the readonly nix store. It’s expected that you would do something like systemd.targets.multi-user.wants = ["mincraft@foo.service"]; or something to that effect in your nixos config.