Update 2020-November-12

I used to suggest using the image openjdk:8-alpine but it wasn’t updated in a year, so I now suggest using openjdk:8-jre which seems to be actively maintained!

Moving your existing server to Docker!

This guide assumes you already have a Minecraft server set up on your host machine. We will simply be moving to Docker, while keeping our files in the host file system. If not done already, you can set up a Minecraft server as normal, and then come back to this guide for the Docker setup.

Let’s assume your host machine has a Minecraft server set up, running as the user minecraft and with its data directory (with the Minecraft server.jar) in /home/minecraft/server-vanilla/ and let us also assume that the user minecraft has the user and group ID of 1001.

First, you will have to stop your currently running Minecraft server. Don’t forget to announce the maintenance to your players. You might also want to run save-all before shutting down, if applicable.

We’ll be using the openjdk:8-alpine image. Pull it with docker pull openjdk:8-alpine.

The command

docker run --user 1001:1001 -tid -p 25565:25565 --name minecraft-vanilla --mount type=bind,src=/home/minecraft/server-vanilla,target=/srv/minecraft -w="/srv/minecraft" --restart always openjdk:8-jre java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xmx1024M -Xms1024M -jar server.jar nogui

Breaking down the meaning

docker run This will run a specific command, using a specific docker image. You can pass options to it, which in this case are:

--user 1001:1001 This will specify the user and group to run as, inside the container. Use the same IDs as your host’s minecraft user and group. This is important as we’re going to be accessing the host’s files.

-tid Run in background (daemon) but attach a psudo-tty with and keep the input open.

-p 25565:25565 Port forward from the host’s 25565 port to the container’s 25565 port. This is so that your server will be accessible from outside.

--name minecraft-vanilla Optional but useful. Gives the specified name to the Docker container. This makes it easier to stop it later and other things.

--mount type=bind,src=/home/minecraft/server-vanilla,target=/srv/minecraft Bind mount the source directory from the host into the container’s target directory. This is to access the host’s Minecraft server files from the container under the specified path of /srv/minecraft.

-w="/srv/minecraft" Set the working directory inside the container. This is so that we can run our command from inside that directory later. In this case this will be java.

--restart always Make sure the container will always restart. This means once our command (java) ends running, it will automatically start it again. Useful when java or our Minecraft server crashes.

openjdk:8-alpine The docker image to use. In this case a minimal Alpine Linux with OpenJDK 8, the officially supported Java version for Minecraft.

java The actual command (application) to run inside the container.

-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap Options to optimize java for running inside a Docker container as stated in the official OpenJDK Docker documentation.

-Xmx1024M -Xms1024M -jar server.jar nogui The Minecraft server command as usual, as stated in the official Minecraft documentation.

Conclusion

It is straightforward to run your Minecraft server in Docker, for additional isolation from the host system. Make sure that the container user matches the host user as stated above, to access the data files. In theory, you could move the data files into a Docker volume for enhanced isolation.

That’s all there is to it! I hope this helped.

Pro Tip

You can attach and detach the container to do server admin tasks as described here!

External Links