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

What you need before starting

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.

System Ubuntu 24.04 LTS
Minimum RAM 2 GB
Java 21 (Temurin)
Default port 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.

01

Connect to the VPS via SSH and update the packages:

sudo apt update && sudo apt upgrade -y

This 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.

02

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 gnupg
03

Add 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-jre

Confirm with java -version — it should show “Temurin-21”.

Why Temurin and not Ubuntu's OpenJDK?

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.

04

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/minecraft

The -r flag creates a system user (without a human UID), -m creates the home directory, -U creates a group with the same name.

05

Switch to the minecraft user and enter the server directory:

sudo -u minecraft -i
cd /opt/minecraft/server

All 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.

06

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.

07

Accept the EULA. Without this, the server refuses to start:

echo "eula=true" > eula.txt
08

Run it for the first time to generate configuration files:

java -Xms1G -Xmx2G -jar paper.jar nogui

It will generate server.properties, create the world/ folder, and stop at the server prompt. Type stop and press Enter to shut it down.

Tune Xmx to your VPS plan

-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.

09

Exit the minecraft user (exit) and create the unit file as root:

sudo nano /etc/systemd/system/minecraft.service

Paste 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.target
10

Reload systemd, enable the service, and start it:

sudo systemctl daemon-reload
sudo systemctl enable minecraft
sudo systemctl start minecraft
11

Confirm it’s running:

sudo systemctl status minecraft
sudo journalctl -u minecraft -f

The 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.

12

Allow SSH before anything else, then the Minecraft port:

sudo ufw allow 22/tcp
sudo ufw allow 25565/tcp
sudo ufw enable

Confirm with sudo ufw status. It should list 22/tcp and 25565/tcp as ALLOW IN.

Be careful when changing the SSH port

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.

13

Create the script as the minecraft user:

sudo -u minecraft -i
mkdir -p /opt/minecraft/backups
nano /opt/minecraft/backup.sh

Content:

#!/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 -delete

Make it executable:

chmod +x /opt/minecraft/backup.sh
14

Schedule it with cron to run daily at 4 AM:

crontab -e

Add:

0 4 * * * /opt/minecraft/backup.sh

The 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=true in 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.

Topics:
Next steps VPS, dedicated or managed panel for FiveM, SAMP, MTA, Tibia and more.Host your game server with Hostini →
Was this tutorial helpful?
Chat on WhatsApp