For one reason or another, I had to set up a Minecraft server and, given that there is no OpenBSD port, I had to set it up from scratch.

These notes are mostly for myself in case I have to re-do in the future, but may be used by others. I'm not liable for any issues this may cause. Use at your own risk. You have been warned!

Since we don't want to run anything as root, we'll need to create a dedicate user which will run the server.jar for us:


	$ doas useradd -k /var/empty -g=uid -L daemon -d /var/minecraft -m -s /sbin/nologin -u 998 _minecraft

Ignore the:


	useradd: No "dot" initialisation files found

I couldn't find a way to disable that warning bar 2>/dev/null and we simply neither need, nor want, the files from /etc/skel there.

Use an UID which is neither currently in use, nor does it clash with any of the UIDs used by OpenBSD ports/packages - https://cvsweb.openbsd.org/ports/infrastructure/db/user.list

System usernames start with an underscore '_' by convention.

It's probably safest to use the next available regular user UID but I like to distinguish these from system users, hence using 998 as 999 is already used by another service.

Everything else should be self-explanatory.

Once done, we need to download the Minecraft server.jar file either from

In order to run it, we'll obviously need to have Java installed:


	$ doas pkg_add jdk--%21

There's no need to add to /usr/local/jdk-21/bin to $PATH as we'll only use it to run Minecraft server.

Still in the same directory, we have to run it at least once in the directory structure to be created, edit license files, change default settings, etc.:


	$ doas -u _minecraft /usr/local/jdk-21/bin/java -Xmx4G -Xms4G -jar server.jar --nogui

Then, we need to accept the EULA:


	$ doas -u _minecraft sed -i '/^eula/s/false/true/' /var/minecraft/eula.txt

Now edit server.properties should we wish to adjust anything.

Finally, we need to create an rc.d file:


	#!/bin/ksh

	java_version=21
	java=/usr/local/jdk-${java_version}/bin/java
	daemon_jar="server.jar"
	daemon_execdir=/var/minecraft
	daemon_user="_minecraft"
	daemon="$java"
	daemon_flags="-Xmx4G -Xms4G -jar ${daemon_execdir}/${daemon_jar} --nogui"
	daemon_fifo=/var/run/minecraft

	. /etc/rc.d/rc.subr

	rc_bg=YES

	rc_reload=NO

	rc_pre() {
		test -p $daemon_fifo || mkfifo -m 0600 $daemon_fifo
		chown $daemon_user $daemon_fifo
	}

	rc_start() {
		rc_exec "tail -f $daemon_fifo | ${pexp} >/dev/null 2>&1"
	}

	rc_stop() {
		rc_exec "echo stop | tee -a $daemon_fifo"
	}

	rc_post() {
		pkill -f "tail -f $daemon_fifo"
		rm -f $daemon_fifo
	}

	rc_cmd $1

Given that the server is an interactive process, which runs in the forground, if we'd like to have any runtime control, we need to talk to its STDIN and check its output /var/minecraft/logs/latest.log. As per above, for the former, we can use a named pipe FIFO, and for the latter, tail(1):


	$ tail -f /var/minecraft/logs/latest.log

Once all is set up, we can enable the service and start it:


	$ doas rcctl enable minecraft
	$ doas rcctl start minecraft

Afterwards, we need to wait until the spawn area gets prepared. Once done, all we need to do is enable the whitelist - otherwise any Tom, Dick, or Harry will be able to connect to our server, should it be running on a machine exposed to the wider Internet, which might not be what we want:


	$ echo whitelist on | doas -u _minecraft tee -a /var/run/minecraft >/dev/null

Then, all we need is to add the usernames allowed to connect:


	$ echo whitelist add your_registered_minecraft_userame | doas -u _minecraft tee -a /var/run/minecraft >/dev/null

Run help for a full list of commands:


	$ echo help | doas -u _minecraft tee -a /var/run/minecraft >/dev/null

That's about it. Do let me know should you have suggestions regarding any of the above - specially the rc.d script.

BTW, creating an OpenBSD port is out of this post's scope.