Host a Minecraft server on a VPS

Run a Minecraft Java server on Paper with Java 25 and systemd, so it starts at boot and restarts on a crash. Memory, firewall, backups and updates.

To host a Minecraft Java server on a VPS, install Java 25, download the Paper server jar, accept Mojang's EULA, and run it as a systemd service on port 25565. For a handful of friends, a server with 4 GB of memory and two vCPUs is comfortable.

This guide does it properly: its own user, a service that starts at boot and comes back after a crash, sensible memory flags, and backups. Commands are for Ubuntu 24.04 and Debian 12 or 13, run as root, with the AlmaLinux and Rocky differences called out.

How big a server you need

Minecraft runs its world on one main thread, so a fast core matters more than many of them. Memory depends on players, view distance and plugins:

  • 1 to 5 players, few plugins: give Minecraft 2 to 3 GB. A 4 GB server leaves room for the system.
  • 5 to 15 players, some plugins: 4 to 6 GB for Minecraft, so an 8 GB server.
  • Modpacks: they want much more. Check the pack's own advice.

Never give Java all the server's memory. The system, disk cache and Java's own overhead need a gigabyte or more on top. How much RAM does your VPS need? explains how to check once it's running.

We use Paper, a fork of the official server that's much faster and runs Bukkit and Spigot plugins. Vanilla clients connect to it without any changes.

Install Java 25

Minecraft 26.1 and later need Java 25. The simplest source that works on every distribution is Eclipse Temurin from Adoptium.

Ubuntu and Debian:

bash
apt update
apt install -y wget gpg jq
wget -qO - https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor -o /etc/apt/trusted.gpg.d/adoptium.gpg
echo "deb https://packages.adoptium.net/artifactory/deb $(. /etc/os-release && echo "$VERSION_CODENAME") main" > /etc/apt/sources.list.d/adoptium.list
apt update
apt install -y temurin-25-jre

AlmaLinux and Rocky Linux:

bash
cat > /etc/yum.repos.d/adoptium.repo <<'EOF'
[Adoptium]
name=Adoptium
baseurl=https://packages.adoptium.net/artifactory/rpm/rhel/$releasever/$basearch
enabled=1
gpgcheck=1
gpgkey=https://packages.adoptium.net/artifactory/api/gpg/key/public
EOF
dnf install -y temurin-25-jre jq

Check it:

bash
java -version

It should say 25. For an older Minecraft version, 1.20.5 to 1.21.x, Java 21 is the one to install instead.

Create a user and download Paper

The server should never run as root. Give it its own user and directory:

bash
useradd --system --create-home --home-dir /opt/minecraft --shell /usr/sbin/nologin minecraft
cd /opt/minecraft

Paper's download service tells you the newest stable build for a version. Set VERSION to the Minecraft version you want (check papermc.io/downloads for the newest one with stable builds) and put your own email in the User-Agent, which Paper asks for:

bash
VERSION=26.3
UA="my-minecraft-server (you@example.com)"
URL=$(curl -fsSL -H "User-Agent: $UA" "https://fill.papermc.io/v3/projects/paper/versions/$VERSION/builds" \
  | jq -r 'first(.[] | select(.channel == "STABLE") | .downloads."server:default".url)')
echo "$URL"
curl -fsSL -H "User-Agent: $UA" -o paper.jar "$URL"

If echo prints null, that version has no stable build yet. Pick the one before it.

Accept the EULA and do a first run

Minecraft won't start until you agree to Mojang's EULA. Read it, then:

bash
echo "eula=true" > eula.txt
chown -R minecraft:minecraft /opt/minecraft

Start it once by hand to generate the world and config files:

bash
sudo -u minecraft java -Xms2G -Xmx2G -jar paper.jar --nogui

When it says Done, make yourself an operator and add yourself to the whitelist, replacing yourname with your Minecraft name, then stop it:

text
op yourname
whitelist add yourname
stop

Once the server runs as a service there's no console to type into, so do this now. As an operator, you can run the same commands in the game's chat with a / in front.

Run it as a service

Create /etc/systemd/system/minecraft.service:

ini
[Unit]
Description=Minecraft server (Paper)
After=network-online.target
Wants=network-online.target

[Service]
User=minecraft
WorkingDirectory=/opt/minecraft
ExecStart=/usr/bin/java -Xms3G -Xmx3G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -jar paper.jar --nogui
Restart=on-failure
RestartSec=10
SuccessExitStatus=0 143

[Install]
WantedBy=multi-user.target

Set -Xms and -Xmx to the same value: 3G on a 4 GB server, 6G on an 8 GB one. On Ubuntu and Debian, Temurin may put Java somewhere else; readlink -f "$(command -v java)" shows the path, so use that in ExecStart if /usr/bin/java doesn't exist.

Start it, and have it start at boot:

bash
systemctl daemon-reload
systemctl enable --now minecraft
journalctl -u minecraft -f

The log shows the same output you saw on the first run.

Open the port

Players connect on TCP 25565. With ufw:

bash
ufw allow 25565/tcp

On AlmaLinux or Rocky, with firewalld:

bash
firewall-cmd --permanent --add-port=25565/tcp
firewall-cmd --reload

Then connect from Minecraft with your server's address, for example 203.0.113.10. If you have a domain, an A record like mc.example.com pointing at the server is easier to share.

Settings worth changing

In /opt/minecraft/server.properties, then systemctl restart minecraft:

  • white-list=true, then add players in-game with /whitelist add name. On a public IP, scanners find a new server within hours. A whitelist keeps out strangers.
  • view-distance and simulation-distance: lower them (say 8 and 6) if the server struggles. They make the biggest difference to CPU and memory.
  • motd: the line shown in the server list.

Backups

The world lives in /opt/minecraft/world, world_nether and world_the_end. A copy taken while the server writes to it can be inconsistent, so the safe way is to stop, copy and start. The ; between the steps means the server starts again even if the copy fails. Run this nightly from root's crontab (crontab -e):

bash
0 5 * * * systemctl stop minecraft; tar czf /root/mc-$(date +\%F).tgz -C /opt/minecraft world world_nether world_the_end; systemctl start minecraft

Then copy those files off the server. Backups you should run shows how, and how to delete old ones.

Updating

Paper puts out new builds often. To update, stop the server, back up, download the new jar with the commands above, and start it:

bash
systemctl stop minecraft
cd /opt/minecraft && cp paper.jar paper.jar.old
# download the new paper.jar as above
chown minecraft:minecraft paper.jar
systemctl start minecraft

Moving to a new Minecraft version is a one-way trip for the world. Take a backup first, and check your plugins support the new version.

When it goes wrong

  • "UnsupportedClassVersionError": Java is too old for this Paper version. Install Java 25 and check java -version.
  • Players get "Connection timed out": the port isn't open. Check ss -tlnp | grep 25565 on the server, then the firewall.
  • The service keeps restarting: read journalctl -u minecraft -n 100. A missing eula=true or a typo in the Java path is the usual cause.
  • Lag with free memory to spare: the main thread is the limit, not memory. Lower the view distance and find the heavy plugin or farm with Paper's built-in spark profiler.

Doing it on VPSNine

The Minecraft one-click app does everything up to the EULA for you: Java and the latest Paper in /opt/minecraft, its own user, and the systemd unit. You read the EULA, set eula=true, run systemctl enable --now minecraft, and connect.

It needs at least the Standard plan, with 4 GB of memory. For more than a handful of players or a modded server, take Extreme. The plans page has the specs.

Be first when orders open

Join the waitlist and we'll send you one email when VPSNine launches. Pick a plan if you already know which one you want, and we'll size the first servers around it.

  • One email, on launch day
  • Monthly, or a year up front in Bitcoin
  • 14-day money-back guarantee