How to set up a Minecraft Java server on Ubuntu Linux VPS from scratch
Step-by-step guide to set up a Minecraft Java Edition server on an Ubuntu 24.04 Linux VPS using Paper, systemd, firewall, backups, and plugin support ready for production.
Running a Minecraft Java Edition server on a Linux VPS gives you total control that shared servers can’t offer — a dedicated port, guaranteed RAM, root access to install custom plugins and mods, and backups whenever you want. But the path from scratch involves details that many first-time owners get wrong: running as root, leaving the JVM defaults, forgetting the firewall, or closing SSH and watching the server die.
This tutorial covers the complete production setup on an Ubuntu 24.04 LTS VPS: installing Java 21 (required by Minecraft 1.20.5+), downloading Paper (the server that nearly every serious Java server runs today), creating a dedicated user, configuring systemd so the service starts on its own, UFW firewall, and an automated backup script. The estimated time is 25-35 minutes for someone familiar with the Linux terminal.
The target persona is someone who has never run a Minecraft server on Linux but has basic SSH experience. We won’t cover Bedrock Edition (Geyser is another tutorial), nor Forge mods (same) — the focus is Java Edition vanilla or with Bukkit/Paper plugins.
Prerequisites
A VPS running Ubuntu 24.04 LTS (22.04 also works), root access via SSH, at least 2 GB of RAM dedicated to the server, 20 GB of free disk space, and basic knowledge of Linux commands. If the VPS is new, do the minimum hardening first: change the root password, create a sudo user, and disable root password login over SSH.
Ubuntu 24.04 LTS 2 GB 21 (Temurin) 25565 The Java version matters: Minecraft 1.20.5 and later require Java 21. Older versions (1.17 to 1.20.4) run on Java 17. Servers 1.16 and older accept Java 8 or 11. This tutorial assumes 1.21.x — the current stable version — so Java 21 is the right path.
Preparing the base system
Before downloading Paper, update the system and install dependencies. Running as root directly is unnecessary and dangerous — the service will run with a dedicated user later.
Connect to the VPS via SSH and update the packages:
sudo apt update && sudo apt upgrade -yThis command reads the repositories and applies all pending security updates. If it’s your first time on the VPS, the upgrade may take 2-5 minutes.
Install basic dependencies: download utilities, screen for persistent sessions (a fallback if systemd doesn’t run well), and the Adoptium (Eclipse Temurin) repository for Java 21:
sudo apt install -y wget curl screen ca-certificates apt-transport-https gnupgAdd the Adoptium repository and install Java 21:
wget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | \
sudo gpg --dearmor -o /etc/apt/keyrings/adoptium.gpg
echo "deb [signed-by=/etc/apt/keyrings/adoptium.gpg] \
https://packages.adoptium.net/artifactory/deb $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/adoptium.list
sudo apt update
sudo apt install -y temurin-21-jreConfirm with java -version — it should show “Temurin-21”.
Temurin (formerly AdoptOpenJDK) is the official distribution from the Eclipse Adoptium project, maintained by the same team behind upstream OpenJDK. Identical performance, but with more predictable releases and extended LTS support. Production Minecraft servers run Temurin or Azul Zulu — rarely Ubuntu’s openjdk-21-jre, which can take a while to receive critical patches.
Creating a dedicated user and directory structure
Running Minecraft as root is a classic anti-pattern. If a malicious plugin is installed, it has root access to the entire system. A dedicated user isolates the process.
Create a user without interactive login and a base directory:
sudo useradd -r -m -U -d /opt/minecraft -s /bin/bash minecraft
sudo mkdir -p /opt/minecraft/server
sudo chown -R minecraft:minecraft /opt/minecraftThe -r flag creates a system user (without a human UID), -m creates
the home directory, -U creates a group with the same name.
Switch to the minecraft user and enter the server directory:
sudo -u minecraft -i
cd /opt/minecraft/serverAll commands from here on run as minecraft until you restart the
session. To exit, exit.
Downloading and configuring Paper
Paper is distributed via an official API — always grab the latest build of the target version.
Download Paper 1.21.x (replace VERSION and BUILD with the current values from PaperMC downloads):
PAPER_VERSION="1.21.4"
PAPER_BUILD="latest"
wget -O paper.jar \
"https://api.papermc.io/v2/projects/paper/versions/${PAPER_VERSION}/builds/${PAPER_BUILD}/downloads/paper-${PAPER_VERSION}-${PAPER_BUILD}.jar"If the “latest” build doesn’t work, query the API manually at
https://api.papermc.io/v2/projects/paper/versions/1.21.4 to get the
most recent build number.
Accept the EULA. Without this, the server refuses to start:
echo "eula=true" > eula.txtRun it for the first time to generate configuration files:
java -Xms1G -Xmx2G -jar paper.jar noguiIt will generate server.properties, create the world/ folder, and
stop at the server prompt. Type stop and press Enter to shut it down.
-Xmx2G allocates 2 GB of heap to the JVM. If your VPS has 4 GB of
total RAM, use -Xmx3G leaving 1 GB for the system. Never allocate
100% of the RAM — the operating system and the JVM itself (metaspace,
threads, GC) need overhead. If the VPS has 2 GB, use -Xmx1500M at
most.
Configuring systemd to run 24/7
Without systemd, closing SSH brings the server down. With systemd, the service starts on boot, restarts on crash, and logs go to journalctl.
Exit the minecraft user (exit) and create the unit file as root:
sudo nano /etc/systemd/system/minecraft.servicePaste the content below:
[Unit]
Description=Minecraft Java Server (Paper)
After=network.target
[Service]
Type=simple
User=minecraft
Group=minecraft
WorkingDirectory=/opt/minecraft/server
ExecStart=/usr/bin/java -Xms1G -Xmx2G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -jar paper.jar nogui
Restart=on-failure
RestartSec=15s
SuccessExitStatus=0 143
[Install]
WantedBy=multi-user.targetReload systemd, enable the service, and start it:
sudo systemctl daemon-reload
sudo systemctl enable minecraft
sudo systemctl start minecraftConfirm it’s running:
sudo systemctl status minecraft
sudo journalctl -u minecraft -fThe second command shows logs in real time — Ctrl+C to exit. Look for the line “Done (X.XXXs)! For help, type help” — it’s the sign of an operational server.
Opening the port on the firewall
UFW comes installed on Ubuntu but is usually disabled. Enable it carefully so you don’t lock yourself out.
Allow SSH before anything else, then the Minecraft port:
sudo ufw allow 22/tcp
sudo ufw allow 25565/tcp
sudo ufw enableConfirm with sudo ufw status. It should list 22/tcp and 25565/tcp as
ALLOW IN.
If the VPS uses SSH on a non-standard port (e.g., 2222), allow it
BEFORE ufw enable. Enabling UFW without allowing the active SSH port
locks you out — recoverable only via the provider’s web console.
Automated backup script
Minecraft worlds get corrupted. Plugins break worlds. A player with WorldEdit deletes the spawn. A daily backup is your peaceful-night insurance.
Create the script as the minecraft user:
sudo -u minecraft -i
mkdir -p /opt/minecraft/backups
nano /opt/minecraft/backup.shContent:
#!/bin/bash
BACKUP_DIR="/opt/minecraft/backups"
SERVER_DIR="/opt/minecraft/server"
DATE=$(date +%Y%m%d-%H%M)
tar -czf "${BACKUP_DIR}/world-${DATE}.tar.gz" -C "${SERVER_DIR}" world world_nether world_the_end
find "${BACKUP_DIR}" -name "world-*.tar.gz" -mtime +7 -deleteMake it executable:
chmod +x /opt/minecraft/backup.shSchedule it with cron to run daily at 4 AM:
crontab -eAdd:
0 4 * * * /opt/minecraft/backup.shThe script keeps 7 days of automatic backups, deleting the oldest.
Final verification
To confirm everything works:
# Service status
sudo systemctl status minecraft
# Port listening
sudo ss -tlnp | grep 25565
# External connectivity (from your desktop)
nc -vz <VPS_IP> 25565
Open the Minecraft Java client, go to “Multiplayer”, “Add Server”, and use the VPS IP. If it connects without timing out, you’re ready.
Troubleshooting common issues
Server starts but crashes in seconds
Check logs with sudo journalctl -u minecraft -n 100. Frequent causes:
wrong Java version (1.21+ requires Java 21), Xmx greater than available
RAM, or EULA not accepted.
”Connection refused” on the client
Usually firewall — confirm sudo ufw status lists 25565. If the VPS
has an external firewall (on the provider’s panel), allow it there
too. The local UFW doesn’t see the provider’s firewall.
Heavy lag with few players
Before upgrading the plan, tune view-distance in server.properties
to 8 or 6 (default is 10). Each reduction drastically cuts CPU use on
chunks. Enable simulation-distance=6 as well.
Next steps
- Install the EssentialsX plugin for basic commands (
/home,/spawn,/tpa) — drop it in/opt/minecraft/server/plugins/and restart the service. - Configure RCON for remote administration without needing SSH —
enable-rcon=truein server.properties. - Add an anti-cheat (Matrix, Vulcan) if the server is public.
- Configure a DNS A record to point your domain at the VPS — players connect by name instead of IP.
- If you’re scaling to 30+ players or hosting a serious community, a Hostini dedicated VPS with DDoS protection is the technical floor — a public Minecraft server is a constant target for L4 attacks that take down port 25565 entirely without adequate protection.
Frequently asked questions
How much RAM does a Minecraft Java server need?
For 5-10 players without heavy mods, 2 GB is enough with Paper. For 10-20 players or large worlds, plan for 4 GB. Complex mods (Forge with 50+ mods) may require 6-8 GB. The rule of thumb is to size 256-512 MB per active player, added to the 1 GB baseline of the server.
Can I run Minecraft Java on a 1 GB RAM VPS?
Technically yes, but with severe restrictions — view-distance 4, no more than 3 players, and zero heavy plugins. The JVM needs overhead, so with 1 GB you allocate at most 768 MB to the server and the system runs tight. For any server with real-world ambitions, 2 GB is the practical floor.
What's the difference between Paper, Spigot, and Vanilla?
Vanilla is Mojang's official server — the reference, but slow and without plugin support. Spigot is an optimized fork with a plugin API. Paper is a Spigot fork with significant performance optimizations (async chunks, rewritten redstone) and exploit fixes — it's the de facto standard for Java servers since 2018.
Do I need to open port 25565 on the firewall even if the VPS is public?
Yes. The VPS network interface accepts packets from the internet, but Linux iptables/UFW blocks non-allowed ports by default. Without `ufw allow 25565`, players trying to connect get a timeout — the port doesn't even respond. If you change the default port in server.properties, open the new port before restarting.
How do I keep the server running after I close SSH?
Don't use `java -jar paper.jar` directly in the SSH session — closing the terminal kills the process. Use systemd (covered in this tutorial) or screen/tmux. Systemd is superior because it restarts automatically if the server crashes, records logs in journalctl, and comes up with the VPS boot after a reboot.
Does the world backup need to stop the server?
No — but you need to tell the server to flush data to disk first. The `save-off` command disables automatic saves, `save-all flush` forces a pending write, then you tar the directory, and `save-on` re-enables it. The backup script in this tutorial does this via RCON without disconnecting players.