Legendary Paper Minecraft Java Container

Minecraft Docker Paper Minecraft Server
Minecraft Docker Paper Minecraft Server

This is a containerized version of my Paper Minecraft Java server. The image works great on all Docker platforms including Raspberry Pi!

There is also a version that has Geyser + Floodgate installed which will let Minecraft Bedrock players connect to your Java server!

The official GitHub repository is located here.

The official Docker Hub repository is located here.

The Minecraft Bedrock version of the container is located here. This is for the Java version.

It’s now possible to convert your worlds between Bedrock and Java versions. Check out my guide on Chunker here for more information.

Features

  • Sets up fully operational Minecraft server in less than a couple of minutes
  • Runs the highly efficient “Paper” Minecraft server
  • Plugin support for Paper / Spigot / Bukkit
  • Uses named Docker volume for safe and easy to access storage of server data files (which enables more advanced Docker features such as automatic volume backups)
  • Installs and configures OpenJDK 18
  • Automatic backups to minecraft/backups when server restarts
  • Full logging available in minecraft/logs folder
  • Updates automatically to the latest version when server is started
  • Runs on all Docker platforms including Raspberry Pi

Usage

First you must create a named Docker volume. This can be done with:

docker volume create yourvolumename

Now you may launch the server and open the ports necessary with one of the following Docker launch commands.

With default port:

docker run -it -v yourvolumename:/minecraft -p 25565:25565 --restart unless-stopped 05jchambers/legendary-java-minecraft-paper:latest

With custom port:

docker run -it -v yourvolumename:/minecraft -p 12345:12345 -e Port=12345 --restart unless-stopped 05jchambers/legendary-java-minecraft-paper:latest

With a custom Minecraft version (add -e Version=1.X.X, must be present on Paper’s API servers to work):

docker run -it -v yourvolumename:/minecraft -p 25565:25565 -e Version=1.17.1 --restart unless-stopped 05jchambers/legendary-java-minecraft-paper:latest

With a maximum memory limit in megabytes (optional, prevents crashes on platforms with limited memory, -e MaxMemory=2048):

docker run -it -v yourvolumename:/minecraft -p 25565:25565 -e MaxMemory=2048 --restart unless-stopped 05jchambers/legendary-java-minecraft-paper:latest

Using a different timezone:

docker run -it -v yourvolumename:/minecraft -p 25565:25565 -e TZ="America/Denver" --restart unless-stopped 05jchambers/legendary-java-minecraft-paper:latest

Skipping backups on a certain folder:

docker run -it -v yourvolumename:/minecraft -p 25565:25565 -e NoBackup="plugins" --restart unless-stopped 05jchambers/legendary-java-minecraft-paper:latest

Skipping permissions check:

docker run -it -v yourvolumename:/minecraft -p 25565:25565 -e NoPermCheck="Y" --restart unless-stopped 05jchambers/legendary-java-minecraft-paper:latest

Configuration / Accessing Server Files

The server data is stored where Docker stores your volumes. This is typically a folder on the host OS that is shared and mounted with the container. I’ll give the usual locations here but if you’re having trouble just do some Googling for your exact platform and you should find where Docker is storing the volume files.

You can find your exact path by typing:

docker volume inspect yourvolumename

This will give you the fully qualified path to your volume like this:

{
        "CreatedAt": "2022-05-09T21:08:34-06:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/yourvolumename/_data",
        "Name": "yourvolumename",
        "Options": {},
        "Scope": "local"
}

On Linux it’s typically available at:

/var/lib/docker/volumes/yourvolumename/_data

On Windows it’s at

C:\ProgramData\DockerDesktop

but may be located at something more like

\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\

if you are using WSL (Windows Subsystem for Linux).



On Mac it’s typically

~/Library/Containers/com.docker.docker/Data/vms/0/

If you are using Docker Desktop on Mac then you need to access the Docker VM with the following command first:
screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
You can then normally access the Docker volumes using the path you found in the first step with docker volume inspect

Most people will want to edit server.properties. You can make the changes to the file and then restart the container to make them effective.

Backups are stored in the “backups” folder

Log files with timestamps are stored in the “logs” folder.

Plugin Support for Paper / Spigot / Bukkit

This is a “Paper” Minecraft server which has plugin compatibility with Paper / Spigot / Bukkit.

Installation is simple. There is a “plugins” folder on your Docker named volume.

Navigate to your server files on your host operating system (see accessing server files section if you don’t know where this is) and you will see the “plugins” folder.

You just need to drop the extracted version of the plugin (a .jar file) into this folder and restart the container. That’s it!

Some plugins have dependencies so make sure you read the installation guide first for the plugin you are looking at.

A popular place to get plugins is: dev.bukkit.org

Troubleshooting Note – Oracle Virtual Machines

A very common problem people have with the Oracle Virtual Machine tutorials out there that typically show you how to use a free VM is that the VM is much more difficult to configure than just about any other product / offering out there.

It is because there are several steps you need to take to open the ports on the Oracle VM. You need to both:

  • Set the ingress ports (TCP/UDP) in the Virtual Cloud Network (VCN) security list
  • *and* set the ingress ports in a Network Security Group assigned to your instance

Both of these settings are typically required before you will be able to connect to your VM instance. This is purely configuration related and has nothing to do with the script or the Minecraft server itself.

I do not recommend this platform due to the configuration difficulty but the people who have gone through the pain of configuring an Oracle VM have had good experiences with it after that point. Just keep in mind it’s going to be a rough ride through the configuration for most people.

Troubleshooting Note – Hyper-V

There is a weird bug in Hyper-V that breaks UDP connections on the Minecraft server. The easy workaround for this is that you have to use a Generation 1 VM with the Legacy LAN network driver.

There is a second fix that was shared by bpsimons here. For that fix you need to install ethtool first with sudo apt install ethtool. Next in your /etc/network/interfaces file add “offload-tx off” to the bottom as the issue appears to be with TX offloading.

Here’s an example:

# The primary network interface
auto eth0
iface eth0 inet static
address 192.168.1.5
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.1
offload-tx off

This can also be done non-persistently with the following ethtool command:

ethtool -K eth0 tx off

Additional Support

The comments section right here is the best place for support. The second best place is the GitHub issues section.

I will add additional documentation based on what problems people are running into / questions people are asking because right now I’m not really sure what those will be yet. Definitely let me know if you need any of these things!

Subscribe
Notify of
guest

46 Comments
Inline Feedbacks
View all comments
David
David
1 year ago

Thanks for all your work and your long thorough explanations that you do.

I’m going to start a new world for our Minecraft server and put it in docker as you explained. The question I have is this – On my old server I would run an incremental backup of the world folder every hour or so in case some friends light our house on fire or something like that. In my testing the docker volumes folder (linux /var/lib/docker/volumes/…) is only able to be opened by root. Is there any way I can set up my server so those can be read by a normal user? I’ve tried changing the folder permissions and even doing a chown to change the ownership but it seems to revert back to root at some point. Do you have any suggestions?

Thanks so much.

Doug
Doug
1 year ago

When starting the server for the first time, using docker-compose, how do I tell Minecraft to create a superflat map?

Josh
Josh
1 year ago

Thanks so much for this! I’ve used your previous Raspberry Pi version and am migrating over to the Docker version now. Have Docker up and running on my Raspberry Pi and was able to test that it is working with a simple ‘hello-world’ container.

Created the volume as you instructed and tested with just the basic default port command. It seemed like it completed all the pulls, but wasn’t able to finish. This was the output:

latest: Pulling from 05jchambers/legendary-java-minecraft-paper
ceab7032a497: Pull complete
754d4bf25883: Pull complete
a20ecc4dce1a: Pull complete
2d9f2c5a8117: Pull complete
3701130af22e: Pull complete
46e29ec769d1: Pull complete
c78a83a27926: Pull complete
09bbe066d6ff: Pull complete
Digest: sha256:4d735e5c2ffdf871e6da23fc276e24766797f5a80ce1ede75ea6288c90cc9aae
Status: Downloaded newer image for 05jchambers/legendary-java-minecraft-paper:latest
Paper Minecraft Java Server Docker script by James A. Chambers
Latest version always at https://github.com/TheRemote/Legendary-Java-Minecraft-Paper
Don't forget to set up port forwarding on your router! The default port is 25565
Port used: 25565
Taking ownership of all server files/folders in /minecraft...
Complete
No daily restart scheduled
Updating to most recent paperclip version ...
Unable to connect to update website (internet connection may be down). Skipping update ...
Starting Minecraft server...
Error: Unable to access jarfile /minecraft/paperclip.jar

I can confirm that the server can access the internet and other containers are able to pull and work. Any ideas?

Josh
Josh
1 year ago

Thanks, James. Followed your advice. Completely wiped the SD card and started fresh with the latest version of Bullseye. I did choose the 64bit Lite version, I hope that’s okay. Updated and upgraded to make sure everything was up to date. Configured Memory Split to 16, but aside from hostname and SSH, left most of the system untouched. Installed docker and ran the ‘docker run hello-world’ command to make sure it was working correctly. (I did add the ‘pi’ user to the docker group so I wouldn’t have to always run docker commands with sudo.)

This time when I ran the docker command, I got a different set of errors:

System has not been booted with systemd as init system (PID 1). Can’t operate.
Failed to connect to bus: Host is down
Scheduling daily restart:
Updating to most recent paperclip version …
/scripts/start.sh: line 148: {“error”:”Version not found.”} + 0: syntax error: operand expected (error token is “{“error”:”Version not found.”} + 0″)
Starting Minecraft server…
Error: Unable to access jarfile /minecraft/paperclip.jar

Was about to dig into the systemd issue, but thought I would check with you first and see if you had see this before.

Thanks again for all the help!

Josh
Josh
1 year ago

Ah! I feel foolish! All set now, it’s working and I was able to connect with the Minecraft client.

I ran it without the -d flag, so had to quit out of the Minecraft instance after starting it. I tried running the command with the -d flag, but it gave me an error that the port was already allocated and when I tried to connect the server was running again. I’m not used to not having to fiddle with things! I’m new to docker so I need to read up on it and get used to how it works.

I found your old notes explaining why with your old scripts you recommended running it on 32bit Raspberry Pi OS, is that still your recommendation? I have a Raspberry Pi 4 Model B with 4GB of RAM, which seems to run the 64bit version well. But I’m wondering if it’ll have the same negative impact on running the Minecraft server.

Anyway, thanks again for all the help on this!

Josh
Josh
1 year ago

Awesome! You’ve been such a great help. Just sent a donation through CashApp.

Last question (I think!). In the previous version, since you were using ‘screen’ to launch Minecraft, it was easy to connect to the console (‘screen -r minecraft’) and then run commands on the server (like making a user operator, for example). I can’t figure out how to do something similar with the new docker set up. Can you point me in the right direction?

Josh
Josh
1 year ago

Again, feel silly I didn’t figure that out! Getting the container id seems so obvious now! One thing I noticed. Ctrl+A followed by Ctrl+D didn’t detach, but looking around a bit, it seems that Ctrl+P followed by Ctrl+Q does it. Tested and that seemed to work for me.

A conceptual question. As I’m researching and learning about docker more, it seems like the ‘run’ command is the equivalent of ‘create’ and ‘start’ for a container. So once the container is created, is there a way to change the environment variables that were passed to it? Say I wanted to change the backup time or adjust MaxMemory. (Also, are there more environment variables than the ones specified above?)

I read a bit about the ‘commit’ command, but have to admit that I wasn’t quite sure how that worked.

The other idea I had is that I could stop the running container and remove it. (Thinking to remove at this stage so there aren’t errors when trying to bind the new container to the same port.) The data should still be preserved in the volume, right? Then I could create a new container using the same ‘run’ command, but this time with different environment variables. Since it’s still pointing to the same volume for the data, the properties and state of the world should be preserved, right? Is my logic sound here? Or is there a better way to do it?

Josh
Josh
1 year ago

Excellent! Thanks so much. Double for pushing me to finally explore docker. I haven’t been avoiding it per se, but never really had a good reason to give it a shot until now!

Josh
Josh
1 year ago

Yes, I remember wrestling with the Java version issues with the previous scripts. (You did an excellent job of making it as easy as possible for us users, though!)

For me it was having an aversion to virtual machines going back to work I did with Java in the early days and it was such a resource hog. The tax on resources put me off using anything that is a layer of abstraction between the process and the hardware, especially when resources are scarce. And I know docker isn’t quite the same thing, but the similarity made me skeptical, even as others were praising it. Which is dumb because I’ve used other virtual machines for others servers in the meantime and even run some servers in a RAM disk, so I can’t really explain why it took me so long to come around!

And all the security advantages and deployability across different distros and OSes is great. I didn’t even think about the log4j thing! Anyway, I’m on board now. Thanks again!

Rob
Rob
1 year ago

After changing the paper global & world defaults here:

/var/lib/docker/volumes/mcvol/_data/config

and relaunching with:

sudo docker run -it -v mcvol:/minecraft -p 25565:25565 -p 19132:19132/udp -p 19132:19132 05jchambers/legendary-minecraft-geyser-floodgate:latest

They reset to defaults on restart. Where do I need to be changing the configs to prevent them from being overwritten?

Rob
Rob
1 year ago

Just a couple true/false options nothing invalid. No errors, or config resets in the console when it starts up. I was specifically changing Collisions, and Xray:

Under Global:

collisions:
enable-player-collisions: false

Under world:

anticheat:
anti-xray:
enabled: true
engine-mode: 2

I did notice your script paths referenced /minecraft/XConfigFiles

Where I am changing these options under ‘/var/lib/docker/volumes/mcvol/_data/config’ for the given docker volume you create.

The only minecraft folder I see, is in a random /proc/nnnn/minecraft folder presumably generated when the docker image launches. Interestingly if you change the configs over there it automagically changes them in the /var/lib…./_data/config.

either way they reset to defaults on restart, in my own ignorance I’m probably doing it wrong ( likely ) 🙂

This runs on a PC, under a DietPi(for x86) build I was testing. So there isn’t anything additional running, or wacky configs. Pretty basic.
I stop the server, ssh over to the var/lib/ folders change the two config files, and relaunch with the aforementioned sudo docker run -it -v mcvol:/minecraft ~~etc~~
That’s it.

Thanks for the response – appreciated .

Yui
Yui
1 year ago

Hi James,

Hope you’re well!

I decided to get my feet wet into Docker as you’ve come up with yet another fantastic way to spin up a Minecraft server. I have everything working – but the GeyserMC Bedrock plugin for Spigot. I had no issues exposing the port suggested on wiki.geysermc.org on the original Minecraft server script for Linux, but for the life of me I cannot get the port exposed through Docker even after many deep dives through their Wiki’s. Adding -p :/udp to your Docker run command doesn’t seem to work, even though it should… and the port is open on my TP-LINK router.

The issue isn’t urgent but any ideas would be much appreciated!

Cheers, Yui

Yui
Yui
1 year ago

Hi James,

Thanks for your suggestion of forwarding both TCP and UDP ports. I think I was just compeltely went over my head and I blamed it on networking jank, lol. Geyser + Floodgate seems to be working perfectly now.

Strangely enough, even when I have a client connected through a console or PC Bedrock, the port still doesn’t show as open on sites like portchecker.co . Maybe this has to do with the way docker exposes to the host and not to the internet?

Anyways, thanks for the prompt help – you really are amazing! Take care 🙂

Cheers, Yui

Drew
Drew
1 year ago

This is exactly what I’ve been looking for! But there seams to be a problem, the docker container closes after a few seconds of running. Are you able to help? I am running it on an Unraid server that was recently set up. I am very happy to answer questions about my setup. It creates the following files in the volume before closing: bukkit.yml eula.txt paper.yml paperclip.jar server.properties spigot.yml

Drew
Drew
1 year ago

No logs were created. I used {docker inspect } to look for the exit code, which turned out to be 1.

Drew
Drew
1 year ago
Reply to  Drew

Ah, found the problem, it appears that I can’t set a ram limit grater than 4GB (4,096MB). I was attempting 16GB (16384MB). It’s not much of a worry as I have 64GB of ram. Though it would be nice to have the ability to do larger capacities.

Drew
Drew
1 year ago

Happy to help any way possible, thanks for being so responsive. One last thing of note, I keep getting this error every minute in logs
:[io.netty.channel.epoll.EpollEventLoop] Unexpected exception in the selector loop.[0m
.channel.unix.Errors$NativeIoException: epoll_wait(..) failed: Function not implemented

Drew
Drew
1 year ago

Well that worked wonders. The error is gone and I was able to connect for the first time! My server is running two Xeon(R) CPU E5-2690 0 @ 2.90GHz and eight HPE 8GB DDR3 1600 MHz ECC RAM; On a HPE ProLiant DL380p Gen8 Server.

What is different is my command for making the server:
/usr/local/emhttp/plugins/dynamix.docker.manager/scripts/docker create --name='vasher_con_legendary' --net='bridge' --privileged=true -e TZ="America/Los_Angeles" -e HOST_OS="Unraid" -p '25565:25565/tcp' -p '25565:25565/udp' -p '25575:25575/tcp' -p '25575:25575/udp' -v '/mnt/user/Services/minecraftserver/vasher_con_legendary/':'/minecraft':'rw' '05jchambers/legendary-java-minecraft-paper'

Drew
Drew
1 year ago

Thank you very much for the help! You have a good day.

Drew
Drew
1 year ago

Unraid is Slackware-based Linux distribution.

Will Charles
Will Charles
1 year ago

Dumb question, but with the Docker container, how and where can one specify the MaxMemory environment variable?

EDIT: Actually, to answer my own question: docker run -e MaxMemory=

Will Charles
Will Charles
1 year ago

Thanks for the reply, and great job on the Docker work. Super easy to use. I was only asking as I am running both your Bedrock and Java images and I want to limit (even on a 8GiB RaspberryPi 4) the Java instance. Java being Java!