Effortless Minecraft Servers on NixOS | Simple Declarative Setup

A post about one way to declare Minecraft servers with Nix.

Vimjoyer avatar

Vimjoyer


This post is available in video form


There is a surprising overlap between people who Use NixOS, and people who own a minecraft server. And if you happen to be one of them, or want to become one in just a couple of minutes, then this video is for you.

Because NixOS makes creating minecraft servers even easier than it already was. See for yourself, it’s literally just two lines in your nixos configuration, and you don’t even have to worry about installing java, downloading the server, opening ports, setting up a systemd service or anything like that.

And so in this post I’ll show you how to manage a minecraft server on nixos, including declaratively managing all of it’s options, installing mods, or even managing several servers all at once.

So just like I’ve said, the module needed to set up a minecraft server declaratively is already built into NixOS, meaning all we have to do is add these two lines to your configuration.nix, to get a fully working server accessible at the default 25565 port.

# configuration.nix. Example of all options that are explained below.
 
{ pkgs, lib,}: {
  services.minecraft = {
    enable = true;
    eula = true;
    declarative = true;
 
    package = pkgs.minecraft-server-1-12;
    dataDir =/var/lib/someotherdir;
 
    serverProperties = {
      gamemode =survival;
      difficulty =hard;
      simulation-distance = 10;
      level-seed =4;
    };
 
    whitelist = {
      vimjoyer = “3f96da12-a55c-4871-8e26-09256adac319;
    };
 
    jvmOpts =-Xms4092M -Xmx4092M -XX:+UseG1GC;
  };
}

After enabling these and rebuilding your nixos configuration, you’ll find your server in the /var/lib/minecraft directory, which can be changed using the dataDir option if you want.

The server will automatically be started as a systemd service. meaning you can use the regular systemctl commands, to restart it, or check the logs.

And by default, the server will run the latest available version of minecraft packaged in your current channel of nixpkgs, which you can check by searching for the minecraft-server package on search.nixos.org. It can, of course, be changed to anything you like using the package option.

And nixpkgs provides packages for all major versions from 1.2 to the most recent version, and also a couple of other versions like PaperMC.

It unfortunately does not provide any modded versions at the moment, but I’ll show you how you can enable those later.

But first, let’s see how we can cofigure this server declaratively.

Because while you can just straight up edit any files in the generated server directory, a more nix way to do it would be using the declarative option.

And what this option does, is allow us to define server properties and server’s whitelist using serverProperties and whitelist options respectively. I must say that I find this option rather confusing, because the other two could have been of type attribute set or null to check if they are enabled without any additional steps for the users. But I’m assuming this is just a remnant of the past because the module is more than 10 years old at this point.

Anyway, everything you put into the server properties option will be translated into the usual ini format, meaning you can define everything from gamemode and difficulty to simulation-distance and level-seed here. The whitelist also works more or less like how you would expect it to, so by assigning usernames to user IDs you can select just a handful of accounts that can access your server.

And last but not least, You can also define jvmOpts here, which will be appended to your Java start command to start the server.

So we now know how to quickly roll out simple vanilla servers for you and your friends.

But for more complicated servers with mods or plugins, the builtin module will simply not be sufficient. And so now, I’ll show you an alternative nix solution that you can use to define more complex servers.

Nix-minecraft

Accessible with a flake, nix-minecraft provides a module, that allows you to define and run multiple minecraft servers simultaneously, while also giving you access to way more many different version of minecraft including all versions of Fabric, Quilt, Paper, Velocity, and of course Vanilla in it’s overlay.

To include nix-minecraft in your nixos configuration, add this url to your flake’s inputs, and make sure that the inputs are passed all the way to your nixos modules with specialArgs.

# flake input
nix-minecraft.url =github:Infinidoge/nix-minecraft”;
# configuration.nix. Example of all options that are explained below.
 
{ pkgs, lib, inputs, }:
 
{
  imports = [ inputs.nix-minecraft.nixosModules.minecraft-servers ];
  nixpkgs.overlays = [ inputs.nix-minecraft.overlay ];
 
  services.minecraft-servers = {
    enable = true;
    eula = true;
    
    package = pkgs.minecraft-server-1-12;
    dataDir =/var/lib/someotherdir;
 
    servers = {
      cool-server1 = {
        enable = true;
        package = pkgs.fabricServers.fabric-1_18_2;
 
        serverProperties = {/* */};
        whitelist = {/* */};
 
        symlinks = 
        let
          modpack = (pkgs.fetchPackwizModpack {
            url =https://github.com/Misterio77/Modpack/raw/0.2.9/pack.toml;
            packHash =sha256-L5RiSktqtSQBDecVfGj1iDaXV+E90zrNEcf4jtsg+wk=”;
          })
        in
          # Modpack example
          # “mods” = ”${modpack}/mods”;
 
          # Directories
          # “mods” = ./mods;
 
          # Fetching from the internet
          # “mods” = pkgs.linkFarmFromDrvs “mods” (builtins.attrValues {
          #   Starlight = fetchurl { url = “https://cdn.modrinth.com/data/H8CaAYZC/versions/XGIsoVGT/starlight-1.1.2%2Bfabric.dbc156f.jar”; sha512 = “6b0e363fc2d6cd2f73b466ab9ba4f16582bb079b8449b7f3ed6e11aa365734af66a9735a7203cf90f8bc9b24e7ce6409eb04d20f84e04c7c6b8e34f4cc8578bb”; };
          #   Lithium = fetchurl { url = “https://cdn.modrinth.com/data/gvQqBUqZ/versions/ZSNsJrPI/lithium-fabric-mc1.20.1-0.11.2.jar”; sha512 = “d1b5c90ba8b4879814df7fbf6e67412febbb2870e8131858c211130e9b5546e86b213b768b912fc7a2efa37831ad91caf28d6d71ba972274618ffd59937e5d0d”; };
          #   FerriteCore = fetchurl { url = “https://cdn.modrinth.com/data/uXXizFIs/versions/ULSumfl4/ferritecore-6.0.0-forge.jar”; sha512 = “e78ddd02cca0a4553eb135dbb3ec6cbc59200dd23febf3491d112c47a0b7e9fe2b97f97a3d43bb44d69f1a10aad01143dcd84dc575dfa5a9eaa315a3ec182b37”; };
          #   Krypton = fetchurl { url = “https://cdn.modrinth.com/data/fQEb0iXm/versions/jiDwS0W1/krypton-0.2.3.jar”; sha512 = “92b73a70737cfc1daebca211bd1525de7684b554be392714ee29cbd558f2a27a8bdda22accbe9176d6e531d74f9bf77798c28c3e8559c970f607422b6038bc9e”; };
          #   LazyDFU = fetchurl { url = “https://cdn.modrinth.com/data/hvFnDODi/versions/0.1.3/lazydfu-0.1.3.jar”; sha512 = “dc3766352c645f6da92b13000dffa80584ee58093c925c2154eb3c125a2b2f9a3af298202e2658b039c6ee41e81ca9a2e9d4b942561f7085239dd4421e0cce0a”; };
          #   C2ME = fetchurl { url = “https://cdn.modrinth.com/data/VSNURh3q/versions/t4juSkze/c2me-fabric-mc1.20.1-0.2.0%2Balpha.10.91.jar”; sha512 = “562c87a50f380c6cd7312f90b957f369625b3cf5f948e7bee286cd8075694a7206af4d0c8447879daa7a3bfe217c5092a7847247f0098cb1f5417e41c678f0c1”; };
          # });
        };
      };
      cool-server2 = {
        enable = true;
        package = pkgs.vanillaServers.vanilla-1_21
      };
    };
  };
 
  # …
}

Afterwards, open your configuration.nix, and here, include the module in the imports, to get access to all new options provided by nix-minecraft, and an overlay to get the server packages in your pkgs instance.

Now we can simply enable the newly added service, and get back to creating servers.

Like I’ve said earlier, nix-minecraft allows you to define multiple servers at once, so to demonstrate, let’s define one by simply adding an attribute named whatever you want to the servers set.

Every server you add here, can be cofigured with options very similar to the ones we applied to the builtin module, with just a couple of differences.

We obviously don’t have to accept the eula for every server, since we can simply set it to true it the service set , and the options like serverProperties and whitelist work the same way, except you don’t even have to enable the declarative option, because here is everything handled automatically, just like you would expect it to.

And if you decide to create multiple servers, don’t forget to assign unique ports to each one of them, because otherwise they will clash to claim the default 25565

Just like with the default service, we can select the version of our server using the package option, which can be assigned to various packages from the overlay.

To avoid collisions with nixpkgs, all servers live within their own set, following a simple naming convention.

So you’ll find every vanilla server in the vanillaServers set of your pkgs, every Fabric server in the fabricServers, and so on.

But be careful here, because every fabric package is also named after a minecraft version, so if you need some specific version of fabric itself, we can override the package, and set the loaderVersion there.

But of course, who needs a modloader without any mods, so to install mods on your server, nix-minecraft does not try to reinvent the wheel, and simply gives you a qiuck access to your servers directory through the symlinks option.

Meaning you can simply assign it to an existing mods directory from your filesystem, or generate one by fetching every mod with fetchurl, or even, straight up extract it from a modpack using a fetchPackwizModpack function.

This convinient function lets you fetch a packwiz modpack from the internet, and just like any fetch function, to use it, you can simply input your desired url, give it a fake hash, and wait for it to fail during rebuild, so you can replace the hash with a correct one.

Then we can simply access the content of the modpack as if it was a normal directory.

Like in this example where I am only linking the mods directory from it, but you could also access any other files or directories.

And after all of that, you can rebuild your system, and once again find your server running as a systemd service, albeit with a slightly different service name. Actually, every server you enable will get it’s own service and directory, so you don’t have to worry about them overriding one another.

By default you’ll find every server in it’s own subdirectory of /srv/minecraft, but that can of course be changed with the now shared dataDir option

So nix-minecraft can easily be used to define complex servers, and the only major thing it’s missing at the moment is probably forge support.

But now I want to quickly run through other alternatives you may want to know about.

Flux

So one of them is called flux, which lets you define various game servers, including of course minecraft ones. And it’s primary advantage is that it uses mcman, so if you know how to use that, you can give it a try,

And another one is this git repo called mkaito/nixos-modded-minecraft-servers, which works similarly to nix-minecraft, except it lets you write a start script yourself, so you can basically use any modpack you want. But it does not seem to be actively maintained anymore.