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:
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-jreAlmaLinux and Rocky Linux:
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 jqCheck it:
java -versionIt 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:
useradd --system --create-home --home-dir /opt/minecraft --shell /usr/sbin/nologin minecraft
cd /opt/minecraftPaper'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:
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:
echo "eula=true" > eula.txt
chown -R minecraft:minecraft /opt/minecraftStart it once by hand to generate the world and config files:
sudo -u minecraft java -Xms2G -Xmx2G -jar paper.jar --noguiWhen it says Done, make yourself an operator and add yourself to the whitelist, replacing yourname with your Minecraft name, then stop it:
op yourname
whitelist add yourname
stopOnce 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:
[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.targetSet -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:
systemctl daemon-reload
systemctl enable --now minecraft
journalctl -u minecraft -fThe log shows the same output you saw on the first run.
Open the port
Players connect on TCP 25565. With ufw:
ufw allow 25565/tcpOn AlmaLinux or Rocky, with firewalld:
firewall-cmd --permanent --add-port=25565/tcp
firewall-cmd --reloadThen 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-distanceandsimulation-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):
0 5 * * * systemctl stop minecraft; tar czf /root/mc-$(date +\%F).tgz -C /opt/minecraft world world_nether world_the_end; systemctl start minecraftThen 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:
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 minecraftMoving 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 25565on the server, then the firewall. - The service keeps restarting: read
journalctl -u minecraft -n 100. A missingeula=trueor 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
sparkprofiler.
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.