...

Minecraft Java Server on a Linux VPS: Setup Guide

Minecraft Java Server on a Linux VPS - Setup Guide

Set Up a Minecraft Java Server on a Linux VPS

To set up a Minecraft Java server on a Linux VPS, install the Java version your server release requires, download the official server JAR, review the EULA, and configure player access. Then create a systemd service, open the game port, and test both a player connection and a backup restore.

We use Ubuntu 24.04 LTS and the official Vanilla server in this guide. The Java 25 commands suit the Minecraft 26.3 setup described here. Use the same Minecraft release on the server and player clients. Check the release notes before applying these commands to another version.

This setup covers Java Edition. For Bedrock or home-PC hosting, start with our Minecraft server setup guide.

Check Your VPS and Minecraft Requirements

A VPS gives us control over the operating system, game files, and update schedule. It also makes us responsible for Linux updates, access rules, backups, and recovery.

Before starting, prepare:

  • A fresh Ubuntu 24.04 LTS VPS with systemd.
  • An administrator account with SSH and sudo access.
  • Access to the provider’s recovery console.
  • A public IP address, or the provider’s documented port mapping.
  • A Minecraft Java Edition account and matching client release.
  • Storage for the world, working files, and backup copies.

For a small private test world, we can start with 4 GB of VPS memory and a 2 GB maximum Java heap. This is a starting configuration, not a player-capacity promise. World activity, CPU performance, view distance, and other processes change the requirements.

Leave memory for Linux and for Java allocations outside the heap. More RAM will not fix a slow or heavily shared CPU.

Choose One Server Type

Server software Main use Scope of this guide
Vanilla Official Minecraft behavior Full setup below
Paper Server plugins and additional administration options Separate installation and migration checks
Fabric or NeoForge Compatible mods and modpacks Follow the selected loader and pack requirements

Paper and mod loaders have their own release requirements. Do not swap server files on an existing world without a backup and compatibility check. Paper’s setup documentation explains its installation path.

Keep These Setup Values Consistent

Item Value used here
Linux service account minecraft
Live server directory /opt/minecraft/server
Server file /opt/minecraft/server/server.jar
Fixed Java launcher /opt/minecraft/java
Service name minecraft.service
Game port TCP 25565
Starting heap 1G
Maximum heap 2G
Local backup directory /var/backups/minecraft

Run Linux commands through your administrator SSH session unless a step says otherwise. Blocks labeled Minecraft console contain game commands, not Linux commands.

Step 1. Connect to the VPS and Prepare Linux

On your computer, replace ADMIN_USER and VPS_IP with your details:

ssh ADMIN_USER@VPS_IP

If your provider uses a custom SSH port, add -p PORT to that command.

On the VPS, check the operating system, architecture, memory, and disk:

cat /etc/os-release
uname -m
free -h
df -h /
sudo -v

Confirm Ubuntu 24.04 before using this package setup. Then update the fresh host and install the tools we need:

sudo apt update
sudo apt upgrade
sudo apt install curl ca-certificates gpg nano ufw unzip

If Linux requests a reboot, restart now and reconnect. Keep the provider console available while changing network rules later.

Step 2. Install the Required Java Version

Minecraft and Java have separate version numbers. Installing Java 21 does not make every newer Minecraft server work. Mojang’s Minecraft 26.1 release notes specify Java 25.

For this Java 25 setup, we use Eclipse Temurin through the official Adoptium package repository. The JDK includes the runtime needed to launch Minecraft.

Download the repository key:

curl -fsSL https://packages.adoptium.net/artifactory/api/gpg/key/public \
  -o /tmp/adoptium-key.asc
gpg --dearmor --output /tmp/adoptium-key.gpg /tmp/adoptium-key.asc
sudo install -m 0644 /tmp/adoptium-key.gpg /usr/share/keyrings/adoptium.gpg

Stop if a command fails. Add the repository for Ubuntu 24.04, whose release name is noble:

echo 'deb [signed-by=/usr/share/keyrings/adoptium.gpg] https://packages.adoptium.net/artifactory/deb noble main' \
  | sudo tee /etc/apt/sources.list.d/adoptium.list
sudo apt update
sudo apt install temurin-25-jdk

Find the Java executable installed by that package:

JAVA_BIN=$(dpkg -L temurin-25-jdk | awk '/\/bin\/java$/ {print; exit}')
printf '%s\n' "$JAVA_BIN"
"$JAVA_BIN" -version

The output must identify Java 25. If the path is empty or the version differs, stop and check the installation.

Create a fixed launcher path for the game service:

sudo install -d -m 0755 /opt/minecraft
sudo ln -s "$JAVA_BIN" /opt/minecraft/java
/opt/minecraft/java -version

We use this launcher in every later command. It avoids accidentally running Minecraft through another Java version selected as the system default. Check it again after Java package changes.

Step 3. Create a Separate Minecraft Account

Run the game under its own Linux account. Keep administrative access in your normal sudo account.

sudo useradd --system --user-group \
  --home-dir /opt/minecraft \
  --shell /usr/sbin/nologin minecraft
sudo install -d -o minecraft -g minecraft -m 0750 /opt/minecraft/server

The minecraft account owns the game directory. It does not need an interactive login shell.

Check ownership:

ls -ld /opt/minecraft/server

Both the owner and group should be minecraft. Do not use chmod 777 to work around permission errors.

Step 4. Download the Official Server JAR

Open the official Minecraft Java server download page or the 26.3 release page. Copy the server JAR link for the release you selected.

Replace the placeholder below with that link:

sudo -u minecraft curl -fL \
  'PASTE_OFFICIAL_SERVER_JAR_URL_HERE' \
  -o /opt/minecraft/server/server.jar

Check that the download completed and that the archive is readable:

sudo -u minecraft ls -lh /opt/minecraft/server/server.jar
sudo -u minecraft unzip -t /opt/minecraft/server/server.jar

An archive check can find a broken file, but it does not prove its origin. Use the official HTTPS download and compare its hash with official release metadata when available.

Record the release for future recovery:

printf 'Minecraft Java 26.3\n' \
  | sudo -u minecraft tee /opt/minecraft/server/installed-version.txt

Change that text if you selected another release. Keep the download version, client version, and record in agreement.

Step 5. Review the EULA and Start the Server Once

For the initial setup, bind Minecraft to the VPS loopback address. This prevents direct remote game connections while we prepare access controls.

On this fresh installation, create the initial settings:

sudo -u minecraft tee /opt/minecraft/server/server.properties > /dev/null <<'EOF'
server-ip=127.0.0.1
server-port=25565
online-mode=true
white-list=true
enforce-whitelist=true
enable-rcon=false
EOF

Move into the game directory and run the server:

sudo -u minecraft /bin/bash -c \
  'cd /opt/minecraft/server && exec /opt/minecraft/java -Xms1G -Xmx2G -jar server.jar nogui'
Option Meaning
-Xms1G Start with a 1 GB Java heap
-Xmx2G Allow the heap to grow to 2 GB
-jar server.jar Run the downloaded server file
nogui Run without the graphical server window

The first launch normally stops and creates eula.txt. Read the Minecraft EULA. If you agree, edit the file:

sudo -u minecraft nano /opt/minecraft/server/eula.txt

Change eula=false να eula=true, save, and run the launch command again.

Wait for world preparation to finish and the console to report that startup is complete. Startup time depends on the host and world. Do not treat a fixed number of seconds as a pass condition.

Add Approved Players

In the Minecraft console, replace the example names:

whitelist add YourJavaName
whitelist add FriendJavaName
op YourJavaName

Grant operator access only to people who need administration rights. A player does not need operator rights simply to join.

Stop the server through the Minecraft console:

stop

Wait for the world-saving messages and the return of the Linux prompt.

Step 6. Set Player Access and World Options

With Minecraft stopped, open the settings file:

sudo -u minecraft nano /opt/minecraft/server/server.properties

Update existing entries rather than adding duplicate keys.

Setting Starting value Purpose
server-ip Leave empty Allow listening on the host’s available interfaces
server-port 25565 Set the game TCP port
online-mode true Keep account authentication active
white-list true Restrict access to approved players
enforce-whitelist true Enforce the approved-player list
max-players 10 Set an example admission limit
gamemode survival Set the default game mode
difficulty normal Set game difficulty
level-name world Use the world folder created earlier
view-distance 8 Set an initial chunk viewing distance
simulation-distance 6 Set an initial simulation distance
enable-rcon false Keep remote-console access off

The empty address entry should read server-ip=. Do not enter a public address that the VPS does not own on its network interface.

These values are starting choices. A ten-player limit does not promise ten-player performance on every VPS.

Set access rules explicitly. Mojang changed the default white-list value in Minecraft 26.3, so old tutorials may describe different defaults.

Step 7. Start Minecraft Automatically with systemd

systemd manages the Minecraft process after SSH closes and can start it when the VPS boots. It also gives us one place to check status and logs.

Create the service file:

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

Add:

[Unit]
Description=Minecraft Java Server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=minecraft
Group=minecraft
WorkingDirectory=/opt/minecraft/server
ExecStart=/opt/minecraft/java -Xms1G -Xmx2G -jar server.jar nogui
Restart=on-failure
RestartSec=10
TimeoutStopSec=180
KillSignal=SIGTERM
UMask=0027
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Reload systemd and enable the service:

sudo systemctl daemon-reload
sudo systemctl enable --now minecraft
sudo systemctl status minecraft --no-pager
sudo journalctl -u minecraft -n 60 --no-pager

active (running) shows that the process is running. Also inspect the logs for successful world startup. A process can run before the world is ready.

Use these commands for daily control:

sudo systemctl stop minecraft
sudo systemctl start minecraft
sudo systemctl restart minecraft
sudo journalctl -u minecraft -f

Press Ctrl+C to leave the log viewer. That does not stop the service.

journalctl shows output; it is not a Minecraft command console. Once connected, an operator can run approved game commands from in-game chat, with a leading /.

Check a controlled stop before relying on backups. The service sends SIGTERM and allows up to 180 seconds before forced termination. Confirm world-saving messages and a clean stop in your logs. If the server times out, fix the shutdown problem or allow more time before proceeding.

Step 8. Open the Firewall and Join the Server

A public IP does not prove that the game port is reachable. The operating-system firewall and the provider’s network rules can each block a connection.

Preserve SSH Access First

Inspect the existing rules:

sudo ufw status verbose

For SSH on the standard TCP port 22, allow:

sudo ufw allow 22/tcp

If SSH uses another port, allow that actual port instead. Keep the current session open and the recovery console available.

Allow the Minecraft port, then enable UFW if it is not already active:

sudo ufw allow 25565/tcp
sudo ufw enable
sudo ufw status verbose

Open a second SSH session to confirm that administrative access still works. Ubuntu’s firewall documentation explains UFW rule management.

In your provider panel, allow inbound TCP 25565 if a separate cloud firewall applies. Preserve the provider’s SSH rule as well. A NAT-based VPS also needs the provider’s assigned external port mapping.

A VPS with a directly assigned public address does not need a port-forwarding rule on your home router.

Check the Listener and Join

On the VPS:

sudo ss -ltnp 'sport = :25565'

Look for a Java listener on a reachable interface, rather than only 127.0.0.1.

From another computer, use a TCP test if available:

nc -vz VPS_IP 25565

On Windows PowerShell, the equivalent check is:

Test-NetConnection VPS_IP -Port 25565

Then open the matching Minecraft Java client:

  1. Select Multiplayer.
  2. Select Add Server.
  3. Enter VPS_IP:25565.
  4. Join with an approved account.

Walk through the world and make a small change that you can recognize later. A TCP probe alone cannot confirm player authentication, release compatibility, or world access.

Log out of SSH and confirm the game remains available. Then announce a brief interruption, reboot the VPS, and check that players can rejoin:

sudo reboot

Use a Domain Name

Create a DNS A record such as play.example.com pointing to the public IPv4 address. With the default game port, players can usually enter that name without a port suffix.

Use DNS-only mode unless your DNS provider offers a specific Minecraft-compatible proxy service. Add an AAAA record only when IPv6 connectivity and firewall rules work end to end.

An SRV record can advertise a custom port. It does not open a firewall or hide the underlying server address.

Step 9. Back Up the Server and Test Recovery

For this first server, we use a stopped backup. The job briefly takes the game offline, waits for shutdown, copies the server directory, and starts the service again.

This approach is simpler to inspect than a live backup that depends on remote-console save commands. Schedule it during a quiet period and tell players about the interruption.

Create the Backup Job

Create a private backup location:

sudo install -d -o root -g root -m 0700 /var/backups/minecraft
sudo nano /usr/local/sbin/minecraft-backup

Add this script:

#!/usr/bin/env bash
set -euo pipefail
umask 077

exec 9>/run/lock/minecraft-backup.lock
flock -n 9 || exit 1

was_running=0
if systemctl is-active --quiet minecraft; then
  was_running=1
fi

restart_if_needed() {
  if [ "$was_running" -eq 1 ]; then
    systemctl start minecraft
  fi
}
trap restart_if_needed EXIT

systemctl stop minecraft
if systemctl is-active --quiet minecraft; then
  echo 'Backup stopped: Minecraft is still active.' >&2
  exit 1
fi

result=$(systemctl show minecraft -p Result --value)
if [ "$result" != 'success' ]; then
  echo "Backup stopped: service result is $result." >&2
  exit 1
fi

stamp=$(date -u +%Y%m%dT%H%M%S%NZ)
archive="/var/backups/minecraft/server-$stamp.tar.gz"

tar -czf "$archive.partial" -C /opt/minecraft server
tar -tzf "$archive.partial" >/dev/null
mv "$archive.partial" "$archive"
printf 'Created %s\n' "$archive"

Set permissions and run it once:

sudo chmod 0750 /usr/local/sbin/minecraft-backup
sudo /usr/local/sbin/minecraft-backup
sudo systemctl status minecraft --no-pager
sudo ls -lh /var/backups/minecraft

The script keeps the JAR, version record, world files, configuration, and player lists in the archive. It does not remove older backups. Check available disk space and remove old copies only after confirming your retention needs and off-server copies.

If the copy fails, inspect the error and any .partial archive. The script attempts to restart a service that was running before the backup, but check the logs and confirm players can reconnect.

Schedule the Backup

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

[Unit]
Description=Back up Minecraft with a short service stop

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/minecraft-backup

Create /etc/systemd/system/minecraft-backup.timer:

[Unit]
Description=Daily Minecraft backup

[Timer]
OnCalendar=*-*-* 04:00:00
Unit=minecraft-backup.service

[Install]
WantedBy=timers.target

The schedule uses the VPS time zone. Check it with timedatectl, then enable the timer:

sudo systemctl daemon-reload
sudo systemctl enable --now minecraft-backup.timer
sudo systemctl list-timers minecraft-backup.timer

Review job results regularly:

sudo journalctl -u minecraft-backup.service -n 50 --no-pager
sudo systemctl --failed

This timer runs at the scheduled time when the VPS is online; it does not catch up a missed run at boot. Choose a schedule and monitoring method that meet your recovery needs.

Keep a copy outside the VPS. A local archive does not protect against loss of the VPS disk. Also save the service unit and backup job configuration in your recovery records.

Restore a Copy Before You Need It

Choose a completed archive from the backup listing. Replace BACKUP_FILENAME.tar.gz below with its exact name:

sudo install -d -o minecraft -g minecraft -m 0750 /opt/minecraft/restore-test
sudo tar -xzf /var/backups/minecraft/BACKUP_FILENAME.tar.gz \
  -C /opt/minecraft/restore-test
sudo chown -R minecraft:minecraft /opt/minecraft/restore-test

Use a fresh test directory for each exercise. Edit the restored settings with sudo -u minecraft nano /opt/minecraft/restore-test/server/server.properties so they use:

server-ip=127.0.0.1
server-port=25566

Keep authentication and the allowlist active. On a small VPS, stop the live server during this test so two Java processes do not exhaust memory:

sudo systemctl stop minecraft-backup.timer
sudo systemctl stop minecraft
sudo -u minecraft /bin/bash -c \
  'cd /opt/minecraft/restore-test/server && exec /opt/minecraft/java -Xms1G -Xmx2G -jar server.jar nogui'

From a second terminal on your computer, create an SSH tunnel:

ssh -N -L 25566:127.0.0.1:25566 ADMIN_USER@VPS_IP

Add your custom SSH port if needed. In Minecraft, join localhost:25566. Confirm the expected world, your player data, and the change made before the backup.

In the restored server’s Minecraft console, enter stop. Close the tunnel, then start the live service and timer:

sudo systemctl start minecraft
sudo systemctl start minecraft-backup.timer

Record the archive name, restored release, result, and recovery time. An archive that opens is useful; a world that you can restore and join provides stronger proof.

Step 10. Update Minecraft and Roll Back Safely

Read the new release notes before updating. Check its Java requirement and coordinate the client update with players.

Use this order:

  1. Stop the backup timer and ensure no backup job is running.
  2. Stop Minecraft cleanly.
  3. Run the backup script while Minecraft is stopped. It will leave the service stopped.
  4. Record the completed pre-update archive name.
  5. Test the new release against a separate copy of that backup.
  6. Download the approved new JAR as server.jar.new and check it.
  7. Replace the live JAR while the service remains stopped.
  8. Update the version record and start Minecraft.
  9. Check logs, player access, world state, and saving.
  10. Start the backup timer again.

Do not let a scheduled backup race with an update or restore. If a backup job is active, let it finish before changing the live files.

Restore the Pre-Update State

If an update fails, stop the service and timer. Preserve the failed state before restoring:

sudo systemctl stop minecraft-backup.timer
sudo systemctl stop minecraft
cd /opt/minecraft
sudo mv server "server-before-rollback-$(date -u +%Y%m%dT%H%M%SZ)"
sudo tar -xzf /var/backups/minecraft/PRE_UPDATE_BACKUP.tar.gz -C /opt/minecraft
sudo chown -R minecraft:minecraft /opt/minecraft/server

Replace PRE_UPDATE_BACKUP.tar.gz with the recorded archive. Confirm that /opt/minecraft/java still points to a runtime supported by the restored release. Restore its previous setting if you changed it during the update.

Then start the service, check the world, and restart the timer:

sudo systemctl start minecraft
sudo journalctl -u minecraft -n 60 --no-pager
sudo systemctl start minecraft-backup.timer

Rollback returns the world to the backup time. Players lose changes made after that point. Replacing only the JAR does not reverse changes a newer release made to world data.

Fix Common Minecraft Linux Server Errors

Start with the service log:

sudo journalctl -u minecraft -n 100 --no-pager
Symptom First checks Next action
UnsupportedClassVersionError Server release and /opt/minecraft/java -version Install the required runtime and correct the launcher path
EULA message repeats eula.txt and service working directory Check agreement status and file location
Unable to access JAR JAR path and permissions Correct the filename or ownership
Invalid or corrupt JAR Download and archive check Download again from the official source
Service fails at CHDIR Working directory and parent permissions Correct directory access
Failed to bind to port Listening processes and configured address Stop duplicate instances or correct the bind address
Connection refused Process, listening socket, address, and reject rules Check the listener before changing network rules
Connection times out Provider firewall, UFW, routing, and NAT mapping Test the network path from another host
Player is not allowed Account name and allowlist Add the intended account through an operator or console
Client/server version mismatch Both Minecraft releases Use matching releases
Process disappears or reports Killed Kernel log and available memory Check for memory exhaustion before increasing the heap
Disk is full World growth, logs, and backups Free space without deleting the only recovery copy

For memory-related shutdowns, inspect:

sudo journalctl -k -n 100 --no-pager
free -h
df -h

Do not turn off authentication or the entire firewall to make a connection test pass. Fix the failed layer.

Check Performance Before Buying More Resources

Minecraft performance problems can come from the network, the server, or the player’s computer.

Problem Typical sign Useful check
Network delay Delayed actions while server processing remains healthy Player routes, latency, and packet loss
Slow server ticks World actions fall behind for several players Tick timing, CPU load, active chunks, and entities
Client frame-rate limits One player sees poor rendering performance Client settings and local hardware

Minecraft normally targets 20 ticks per second. That leaves about 50 milliseconds for each tick at that rate. Repeated processing above that budget can make the world fall behind.

Use the profiling tools available in your selected release. Do not copy a Paper-only command into a Vanilla server and assume it exists there.

Check view distance and simulation distance before increasing heap size. Change one setting, repeat the same workload, and compare the result. More memory helps only when memory is part of the limit.

A VPS near the main player group can reduce network delay, but location cannot fix an overloaded CPU. Choose resources and location as separate decisions.

Minecraft Java Server on Linux VPS FAQs

Which Java version does my Minecraft server need?

Use the requirement for your exact Minecraft release. Minecraft 26.1 moved to Java 25. Older servers and modpacks can need another runtime. Check the release notes before downloading the JAR, and confirm which executable your service runs.

Does Minecraft keep running after I close SSH?

Yes, when systemd manages it as shown here. A directly launched process in a normal SSH terminal may stop when the session closes. Also enable the service if you want Minecraft to start after a VPS reboot.

Do I need port forwarding on a VPS?

A VPS with a directly assigned public address normally needs firewall rules, not home-router port forwarding. A NAT-based VPS needs its provider’s port mapping. Check the address and network model included with your plan.

Why can I reach port 25565 but still not join?

A reachable TCP port only proves that a service accepts a connection. Check the Minecraft release, Java Edition client, allowlist, account authentication, and server log. A different process can also be listening on the expected port.

Can I run Minecraft on a VPS with 4 GB of RAM?

A 4 GB VPS can be a starting point for a small private Vanilla workload. Leave space for Linux and Java memory outside the heap. Test your world and settings before setting a player limit. CPU performance can become the limit first.

Can Bedrock players join this Java server?

Not through the standard Vanilla setup shown here. Crossplay needs additional software such as Geyser and a supported deployment method. Check its current client support, authentication requirements, and network ports before offering crossplay.

Can I move a single-player world to the VPS?

Yes. Back up both worlds, stop the service, and copy a compatible Java world into the server directory. Set level-name to its folder name and correct ownership. Keep the original copy until you have checked player data, world loading, and saving.

Can I undo a Minecraft server update?

You can restore the pre-update world, configuration, and compatible software from a backup. Do not assume a world opened by a newer release can safely run on an older JAR. A rollback also removes changes made after the backup.

Choose Hosting for Your Minecraft Workload

A useful Minecraft setup starts with the release, world, players, and location. Choose a plan from those needs, then measure the server under normal play.

Our Linux VPS hosting page provides a starting point for comparing VPS options. For a workload that needs a hardware review, see our dedicated game servers.

Share your expected active players, Minecraft release, mods or plugins, player locations, and budget with our team. We can discuss the infrastructure options against those requirements.

Κύλιση στην κορυφή