Tutorials
goetia
Software
0x53.net

Managing minecraft servers

The following tutorial will show how to setup one or more minecraft server under a dedicated user and user supervision tree, to illustrate the following points:

Requirements

Setting up the user supervision tree

Set up a user supervision tree for the user minecraft as described in the user supervision tree tutorial. It can be named however desired, for this tutorial it will be called server.

Thus, the server/run-image/service/ and server/src/*/ subdirectories of the configuration directory need to be populated.

Setting up the system service to start the user supervision tree

The user supervision tree set up above, will manage each individual minecraft server that is set up below. To do that, however, it has to be first started itself. This is done via a system service that drops privileges to the user minecraft and then proceeds to start the user supervision tree server.

The system service source directory has to be created inside the system configuration directory:

src/usertree/minecraft-server-init
├── dependencies.d
│   ├── mount             # empty/arbitrary
│   └── minecraft-tmpfs   # empty/arbitrary
├── no-ml                 # empty/arbitrary
├── run                   # see below
└── type                  # longrun
        	

run script:

#!/bin/execlineb -P

s6-setuidgid minecraft

export USER minecraft
export USERTREE server

user-init
			

Additionally a user writable tmpfs to hold the user runtime directory needs to be prepared. This is done through a minecraft-tmpfs service:

src/usertree/minecraft-tmpfs
├── up                 # see below
└── type               # oneshot
				

up script:

#!/bin/execlineb -P

fdmove -c 2 1

export USER minecraft

user-tmpfs
				

Setting up a service for each server

Each minecraft server will have its own service and thus source directory. In general, those will look as follows:

server/src/minecraft/@SERVERNAME@-srv
├── producer-for      # @SERVERNAME@-log
├── run               # see below
└── type              # longrun
        	

run script:

#!/bin/execlineb -P

fdmove -c 2 1

pipeline { grep -F enable-rcon @PATH/TO/SERVER/DIRECTORY@/server.properties }
pipeline { cut -d= -f 2 }
withstdinas -E MCRCON_TRUE

if { eltest ${MCRCON_TRUE} = true }

execline-cd @PATH/TO/SERVER/DIRECTORY@

trap -x
{
	SIGTERM {
		pipeline { grep -F rcon.port @PATH/TO/SERVER/DIRECTORY@/server.properties }
		pipeline { cut -d= -f 2 }
		withstdinas MCRCON_PORT
		pipeline { grep -F rcon.password @PATH/TO/SERVER/DIRECTORY@/server.properties }
		pipeline { cut -d= -f 2 }
		withstdinas MCRCON_PASS
		foreground { mcrcon save-all }
		foreground { mcrcon stop }
	}
}

@JAVA@ @ARGS@ -jar @JAR@ nogui
        	

This run script is a bit more complicated than usual. This has the reason that it is not possible to stop a minecraft server by sending it a signal. Thus, the signal sent by s6-supervise upon stopping the server is trapped and causes mcrcon to be used to cleanly stop the server. For this reason, the script begins with a check, whether rcon is enabled in the configuration file server.properties and only proceeds it that is the case.

Make sure to replace the following variables with their proper counterparts:

This procedure may now be repeated for each minecraft server one wants to run.

Finally, each server that should be automatically started when the user supervision tree is started (e.g. at boot time), needs to be added to the bundle default:

server/src/bundles/default
├── contents.d
│   ├── @SERVERNAME1@   # empty/arbitrary
│   ├── @SERVERNAME2@   # empty/arbitrary
│   └── @SERVERNAME3@   # empty/arbitrary
└── type                # bundle