Minecraft is the most-sold video game of all time, but for some reason running your own minecraft server with sensible defaults and resource limits involves a lot of research and confusing errors. Here is a quick guide to running your own minecraft server in a docker container by building spigot from scratch using BuildTools so you can automate updates and build the versions you want.
Building the container image
This step is rather simple. I assume you have a recent version of docker and the docker-compose plugin installed already. To build our container image, we first create a file called Dockerfile
:
FROM debian:stable as builder
RUN mkdir /build
WORKDIR /build
RUN apt update
RUN apt install bash ca-certificates wget git -y # install first to avoid openjdk install bug
RUN apt install openjdk-17-jre-headless -y
RUN wget -O BuildTools.jar https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
RUN git config --global --unset core.autocrlf || exit 0
RUN java -jar BuildTools.jar --rev latest #change to specific version if you don't want latest STABLE release
RUN mv spigot-*.jar spigot.jar
FROM debian:stable
RUN apt update
RUN apt install openjdk-17-jre-headless bash -y
RUN mkdir /server /minecraft
RUN adduser --system --shell /bin/bash --group minecraft
COPY --from=builder --chown=minecraft:minecraft /build/spigot.jar /server
RUN chown -R minecraft:minecraft /server
RUN chown -R minecraft:minecraft /minecraft
USER minecraft
WORKDIR /minecraft
CMD ["java", "-Xms4G", "-Xmx4G", "-XX:+UseG1GC", "-jar", "/server/spigot.jar", "nogui"]
This file will build the latest stable version of the spigot server. When minecraft releases new updates, it may take some time before the new server version becomes stable. If you want to build a different version, you can change the --rev latest
in line 9 to for example --rev 1.20
to build a server for minecraft version 1.20 specifically, even if that is not the current latest stable version. A list of all versions available can be found here.
Automating with docker-compose
To ensure we don't have to do everything manually, we create a file called docker-compose.yml
in the same directory as our Dockerfile
:
version: "3.8"
services:
server:
image: minecraft_server
build: .
container_name: minecraft-spigot
restart: on-failure
stdin_open: true
tty: true
ports:
- 25565:25565
volumes:
- $PWD/server_data:/minecraft
deploy:
resources:
limits:
cpus: "3.0"
memory: 6G
This contains all the information about the state we want our server to have, such as being accessible on port 25565 (default minecraft port), where it should store it's data and enabling automatic restarts after crashes.
Setting up the server
Now that these two files are in place, we can prepare our server. Don't worry, you'll only do this once, no need to run this again later when you update to new versions.
First, create a directory called server_data
next to the docker-compose.yml
file. Inside it, create a file called eula.txt
with contents eula=true
inside. Lastly, ensure the server_data
directory and all files inside are writable by all users.
On linux, this can be done quickly from the terminal:
mkdir server_data
echo "eula=true" > server_data/eula.txt
chmod -R 777 server_data
As a last step, build the container image:
docker compose build
This may take a while as it builds the image for our minecraft server container. Luckily, it is fully automatic so you don't have to stick around to watch it if you have better things to do.
Starting and stopping the server
Starting can be done by simply calling
docker compose up -d
The first time you start the server will take a little longer than normal because it has to generate the world. Later starts will be faster. Once the server has started for the first time, you can adjust server settings like name, player limit and whitelist settings in server_data/server.properties
.
To stop it again, run
docker compose down -v
If you want to access the server directly, for example to run commands or read the logs, use
docker attach minecraft-spigot
Important: To detach from your server again press ctrl
+p
followed by ctrl
+q
. If you press ctrl
+c
instead, the server will shutdown!
Adjusting resource limits
The sample config above runs the server with 4gb of memory and 3 cpu cores, with a hard memory limit of 6gb for the entire container. These values are considered sane minimums for recent minecraft servers. To change the amount of cpu available to the server, change the line cpus: 3.0
in docker-compose.yml
to the desired value. This setting is relative, so even values like 0.5
for "half the power of one cpu core" can be configured.
To change the memory limit, you need to change two files. First, set the total limit you want the container to have by adjusting the line memory: 6g
in docker-compose.yml
. This is the limit your server will never physically exceed (if it does, it will crash and restart instead). Next, change the values for "Xms4G"
and "Xmx4G"
in the last line of Dockerfile
. The number in those values represents the amount of gb memory available to the minecraft server process (so "Xmx6g"
would give it 6gb memory for example). Make sure to change both Xms4G
and Xmx4G
and give them the same value. Note that this should be 1-2gb BELOW the total limit you configured in docker-compose.yml
, because the jvm inside the container may exceed the limit temporarily.
Updating to a new Minecraft version
First, build a docker image for the new minecraft version:
docker compose build
This may take a while. Your old server can stay running while you do this.
Once this process is done, simply restart your server:
docker compose down -v docker compose up -d
Making backups
If you want to make a backup of your minecraft server, simply stop it and copy the entire server_data
directory somewhere safe (or put it in a zip/rar/7z archive). Make sure the server is not running while you do this!