Running #Minecraft in a Windows Container using #DockerPublished on 21 Jun 2016
Last year I blogged about running a Minecraft server for friends and family. Today I will explain how I have banished it into a Windows container using Docker! This is another step avoiding Java on the host. But let’s start at the beginning.
Minecraft has a very inconvenient dependency - it is based on Java for which we have seen many as well as serious security bulletins in the last few years. I could have isolated the Minecraft server in a virtual machine but I did not want to accept the overhead of another operating system instance with the sole purpose of serving Minecraft.
A container sounds like a great opportunity to reduce the overhead while isolating the processes from the host at the same time. When Windows Server 2016 Technical Preview 5 was released I was thrilled about the management experience using Docker on Windows as well as the advantages of integrating PowerShell Desired State Configuration into containers.
Note that I have published an updated guide to running Minecraft in a container.
After those first steps with Docker, I decided to start building a container for Minecraft. Like I said, this requires Java. I found an interesting article about Java in Windows containers which gave me a head start. Building on this I created a container image and published it on Ducker Hub: nicholasdille/javaruntime.
I have also published the corresponding Dockerfile:
FROM windowsservercore MAINTAINER firstname.lastname@example.org ADD http://javadl.oracle.com/webapps/download/AutoDL?BundleId=207775 c:\jre-8u91-windows-x64.exe RUN powershell -Command \ Start-Process -FilePath C:\jre-8u91-windows-x64.exe -PassThru -Wait -ArgumentList \"/s /L c:\Java64.log\" RUN del c:\jre-8u91-windows-x64.exe
As you can see from the code above I decided to use the
ADD instruction to download the Java installation package. This does not require the container to have internet access. Note that the Dockerfile comes with a script called
docker-build.cmd which is responsible for building the container image using
docker build. It also takes care of tagging the image because right now it used Java 1.8.0u91 (tagged as 8u91 as well as latest). When a new patch is released you can easily update the Dockerfile and the build script.–>
Important note: The
Dockerfile included above displays outdated code for this image. But due to recent enhancements, please inspect the repository for my Java image.
Adding Minecraft … Not!
I am using SpigotMC for the Minecraft server which may not be distributed as a JAR file. Therefore, I decided to use the container as a pure runtime environment without adding the Minecraft directory to the container. The following Dockerfile prepares a simple container image for Minecraft:
FROM nicholasdille/javaruntime:8u91 MAINTAINER email@example.com EXPOSE 25565 EXPOSE 25575 VOLUME c:\\minecraft ADD minecraft.ps1 / CMD powershell -command c:\minecraft.ps1
The container builds on top of the Java container described above and adds the following:
- It exposes the server port (25565) as well as the remote console port (25575)
- It defines a volume for the Minecraft server directory (containing configuration files, plugins, worlds etc.)
It adds a PowerShell script for launching the minecraft server:
Set-Location -Path \minecraft $LatestJar = Get-ChildItem spigot-*.jar | Sort-Object LastWriteTime | Select-Object -Last 1 -ExpandProperty Name & "$Env:ProgramFiles\Java\jre1.8.0_91\bin\Java.exe" -Xmx1024M -Xms32M -jar $LatestJar -W .\worlds
Note that I am dynamically selecting the youngest spigot-*.jar so that updating does not require changing any script.
In the end, I have added a PowerShell-based wrapper script for launching the Minecraft container (nicholasdille/spigotmc) which only requires you to adjust the local path for the volume:
docker run -d --name minecraft -v D:\Apps\MinecraftSpigot:c:\minecraft -p 25565:25565 -p 25575:25575 nicholasdille/spigotmc
Managing the Minecraft Container
You can easily look at the server starting up inside the container:
docker logs -f minecraft
If the server requires any kind of intervention, use the remote console (RCON) to interact with the server.
I have the feeling I have not found the best solution for handling the Minecraft server directory. The container built in this post simply mounts a local directory into the container. If any of you Docker veterans has a better solution, please get in touch with me on Twitter.