Minecraft Field guide

How to set up a Minecraft Java server on an Ubuntu 24.04 VPS

Set up Minecraft Java with Paper on Ubuntu 24.04, including Java, allowlists, automatic startup, networking and world backups.

How to set up a Minecraft Java server on an Ubuntu 24.04 VPS

Install Paper as a dedicated Linux service, admit players through an allowlist, and keep a recoverable copy of the world. This guide starts with a fresh Ubuntu 24.04 x86_64 VPS with a public IP, SSH access and a user who can run sudo.

Paper supports Java clients and server plugins. Bedrock and Fabric, Forge or NeoForge modpacks need a different installation; technical survival worlds should also check Paper's vanilla differences.

Choose the game version before installing Java#

Select a game version that your players and plugins support. Paper's requirements specify Java 25 for 26.1 and newer; its 1.20–1.21.11 branches recommend Java 21. The commands here target Paper 26.1+ with Java 25, checked on October 12, 2026.

The example reserves a maximum 2 GiB Java heap on a VPS with at least 4 GiB RAM. This is a starting allocation, not a player-capacity estimate. Leave memory for Ubuntu, the JVM's non-heap allocations and any other services. Choose a region near your players; investigate CPU performance once you have an actual workload.

Game traffic passes through both the provider firewall and Ubuntu's firewall. The backup path is separate: stop Paper, archive its directory, then copy the archive to another machine.

Install Java and create the game account#

Run these commands on the VPS. They add the Amazon Corretto repository and install the JDK plus the libraries listed in Paper's Java guide:

bash
sudo apt update
sudo apt install -y ca-certificates curl gnupg nano ufw
curl -fsSLo /tmp/corretto.key https://apt.corretto.aws/corretto.key
sudo gpg --dearmor -o /usr/share/keyrings/corretto-keyring.gpg /tmp/corretto.key
echo 'deb [signed-by=/usr/share/keyrings/corretto-keyring.gpg] https://apt.corretto.aws stable main' | sudo tee /etc/apt/sources.list.d/corretto.list
sudo apt update
sudo apt install -y java-25-amazon-corretto-jdk libxi6 libxtst6 libxrender1
/usr/bin/java -version

Confirm that the selected runtime is Java 25. If it is not, use sudo update-alternatives --config java to select Corretto 25. On a VPS already running other Java applications, use Corretto's absolute executable path in both launch commands below instead of changing their default.

Create an account without administrative privileges:

bash
sudo adduser --system --group --home /srv/minecraft minecraft
sudo install -d -o minecraft -g minecraft -m 750 /srv/minecraft

Download a specific Paper build#

On your computer, open Paper downloads, select the agreed game version and choose a build. Keep its original filename and build number in your administration notes, then rename the downloaded copy to paper.jar.

Upload it from the directory containing that file. Replace SSH_USER and VPS_IP; if SSH uses a custom port, add -P YOUR_SSH_PORT to each scp command.

bash
scp paper.jar SSH_USER@VPS_IP:/tmp/paper.jar

Back on the VPS, install the file, record its checksum and start it:

bash
sudo install -o minecraft -g minecraft -m 640 /tmp/paper.jar /srv/minecraft/paper.jar
sudo -u minecraft /bin/bash -c 'cd /srv/minecraft && sha256sum paper.jar > paper.jar.sha256'
sudo -u minecraft /bin/bash -c 'cd /srv/minecraft && /usr/bin/java -Xms1G -Xmx2G -jar paper.jar --nogui'

The checksum records the exact file you installed; it does not independently authenticate the download. Avoid a script that silently fetches whichever build is newest every time the server starts.

The first launch stops for EULA acceptance. Read the Minecraft EULA, then, if you agree, run sudo -u minecraft nano /srv/minecraft/eula.txt and change eula=false to eula=true. Start Paper with the same launch command again.

Wait for the Done message. In the game server console, enter the following without a leading slash, substituting actual player names:

text
whitelist on
whitelist add YourNickname
whitelist add FriendNickname
op YourNickname
stop

Only the administrator needs operator permissions. Wait for saving to finish and the shell prompt to return before continuing.

Set admission and world options#

Edit sudo -u minecraft nano /srv/minecraft/server.properties. Replace existing values rather than appending duplicate keys:

properties
server-ip=
server-port=25565
online-mode=true
white-list=true
enforce-whitelist=true
enable-rcon=false
gamemode=survival
difficulty=normal
max-players=10
view-distance=8
simulation-distance=6
motd=Our survival world

Keep server-ip empty and account authentication enabled. The allowlist admits named players; max-players sets a connection limit. The distance values are examples to measure against your world, not guaranteed performance settings. See the configuration reference.

Run Paper with systemd#

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

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

[Service]
Type=exec
User=minecraft
Group=minecraft
WorkingDirectory=/srv/minecraft
ExecStart=/usr/bin/java -Xms1G -Xmx2G -jar paper.jar --nogui
Restart=on-failure
RestartSec=10
KillSignal=SIGINT
TimeoutStopSec=180
SuccessExitStatus=0 130 143
NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true

[Install]
WantedBy=multi-user.target

This original unit runs Paper as minecraft, starts it at boot, and retries failures after ten seconds. The stop timeout gives saving three minutes before systemd can force termination; larger worlds may need longer. The systemd service manual documents these settings.

bash
sudo systemctl daemon-reload
sudo systemctl enable --now minecraft
sudo systemctl status minecraft --no-pager
sudo journalctl -u minecraft -n 80 --no-pager
sudo ss -ltnp 'sport = :25565'

Look for Done in the log and a TCP listener on port 25565. An active service alone does not establish game readiness. For future configuration changes, use sudo systemctl restart minecraft, then inspect the log again. Under this service, operators can administer the allowlist through in-game commands; journalctl displays output and does not provide an interactive game console.

If you later want browser-based administration, Nexardo's panel for your own VPS is an option. Enrolling that VPS and configuring a server in the panel is a separate setup step.

Open the port and test a real connection#

Before enabling UFW, allow your actual SSH port. Keep this SSH session open and verify a second connection afterwards.

The example uses SSH port 22. Substitute your actual port and preserve any existing rules for other services:

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

These rules follow Ubuntu's firewall guide. Also allow TCP 25565 in the provider's firewall, if present. Opening UDP alone will not allow Java clients to join this installation.

In Minecraft Java, add VPS_IP:25565 under Multiplayer and use the server's game version. If joining fails, follow the evidence:

SymptomCheckFix to test
UnsupportedClassVersionError at startup/usr/bin/java -version and the selected Paper branchSelect the matching Java runtime; check ExecStart too
Connection refusedss and the startup logFix startup or the listening address/port
Connection timed outPublic IP, UFW and provider firewallCorrect the address or missing TCP rule
Client/server version mismatchClient release and downloaded buildUse matching versions
Player is not allowlistedExact account name in whitelist.jsonAs an operator, run /whitelist add PlayerName

If joining works but play is slow, continue with measuring Minecraft lag using spark.

Make an offline backup and copy it off the VPS#

Warn players about the interruption, stop the service and inspect the final save messages:

bash
sudo systemctl stop minecraft
sudo journalctl -u minecraft -n 40 --no-pager
sudo systemctl show minecraft -p ActiveState -p Result

Continue only after a clean stop. A timeout or forced kill is not a clean save. Check available disk space with df -h /srv /var/backups, then archive the entire server directory:

bash
(
set -e
sudo install -d -m 700 /var/backups/minecraft
MC_BACKUP="/var/backups/minecraft/backup-$(date +%F-%H%M%S).tar.gz"
sudo tar -C /srv -czf "$MC_BACKUP" minecraft
sudo tar -tzf "$MC_BACKUP" > /dev/null
sudo install -m 600 -o "$(id -un)" "$MC_BACKUP" "$HOME/minecraft-backup.tar.gz"
sudo systemctl start minecraft
)

Check each command's result before continuing. If creating or validating the archive fails, resolve that failure; you can restart Paper to end the maintenance window, but do not count the archive as a backup. This directory archive covers the worlds, JAR, plugins and local configuration; external plugin databases need their own backup.

On your computer, retrieve the staged archive:

bash
scp SSH_USER@VPS_IP:minecraft-backup.tar.gz ./minecraft-backup.tar.gz

Store it with restricted access: player data and plugin configuration can be sensitive. A second archive on the VPS's own disk does not protect against losing that VPS.

Inspect restoration before you need it#

To check your own retrieved archive without overwriting a live world, run these commands on a separate Linux machine or test VPS:

bash
MC_RESTORE_DIR="$(mktemp -d)"
tar -xzf minecraft-backup.tar.gz -C "$MC_RESTORE_DIR"
ls "$MC_RESTORE_DIR/minecraft"
cd "$MC_RESTORE_DIR/minecraft"
sha256sum -c paper.jar.sha256

Confirm that the expected world folders, server.properties, plugins and JAR are present. This checks extraction and the recorded JAR fingerprint; it is not a successful game restore test. For that, run the restored copy on a separate Java-compatible test server, keep it isolated from players, and verify the world in the game.

If you need to restore on the original VPS, upload the chosen archive to /tmp/minecraft-restore.tar.gz. On the VPS, stop Paper, confirm a clean stop as above, and then:

bash
(
set -e
MC_RESTORE_STAGE="$(mktemp -d)"
sudo tar -xzf /tmp/minecraft-restore.tar.gz -C "$MC_RESTORE_STAGE"
sudo test -f "$MC_RESTORE_STAGE/minecraft/paper.jar"
sudo test -f "$MC_RESTORE_STAGE/minecraft/server.properties"
sudo mv /srv/minecraft "/srv/minecraft.before-restore-$(date +%F-%H%M%S)"
sudo mv "$MC_RESTORE_STAGE/minecraft" /srv/minecraft
sudo chown -R minecraft:minecraft /srv/minecraft
sudo systemctl start minecraft
sudo journalctl -u minecraft -n 80 --no-pager
)

Use only an archive you created and trust; stop if any check fails. Keeping the old directory allows rollback. Restoring replaces the world with the backup's state, so players lose changes made after that backup. Match Java to the archived Paper version and verify readiness and player access again.

Before updating, make and retrieve a backup, stop the service, and replace the JAR with your chosen compatible build. Record the new build and checksum. Paper's update guide covers the files to preserve; retain the old JAR with the old world, because an upgraded world may not safely downgrade.

References#