Installing a Minecraft server on Linux

A Paper install on Debian or Ubuntu, from picking the right Java version to keeping the server running under systemd.

Game servers6 min read

On this page
  1. Which Java version to install
  2. Installing
  3. Keeping it running
  4. Under systemd
  5. Under tmux
  6. Opening the port
  7. Testing the connection
  8. Back it up before you change anything
  9. Related

This walks through a working Paper server on a fresh Debian or Ubuntu machine: the right Java version, a dedicated user to run it as, the server itself, and a service that starts it on boot.

Everything below is run over SSH. If you have not connected to your server yet, start with Connecting to your server.

Which Java version to install

Each Minecraft version sets a minimum Java version. Installing something older means the server refuses to start.

Minecraft versionMinimum Java
1.16.5 and olderJava 8
1.17.xJava 16
1.18 to 1.20.4Java 17
1.20.5 and newerJava 21

Paper runs on a newer Java than its minimum, so for any current Paper build, installing Java 21 and moving on is the right answer. Fabric and Forge modpacks are fussier: use the Java version the pack itself states, because a pack built for Java 17 can fail on 21.

How to check you got it right. Start the server. If Java is too old it stops immediately and prints the version it needs, or throws UnsupportedClassVersionError with a class file version number. Neither is subtle. To see what you currently have:

Shell
java -version

Installing

  1. Update the system and install Java

    On Debian or Ubuntu:

    Shell
    sudo apt update
    sudo apt install -y openjdk-21-jre-headless
    java -version

    The headless JRE is all a server needs. You only want the JDK if you intend to compile plugins on the machine.

    If that package is not found, your release does not carry it. See what it does have:

    Shell
    apt-cache search '^openjdk-' | grep jre-headless

    If the version you need is missing, enable backports for your Debian release, or install a Temurin build from Adoptium, who publish packages and tarballs for every current Java release.

    On Alma, Rocky, or RHEL the equivalent is:

    Shell
    sudo dnf install -y java-21-openjdk-headless
  2. Create a user for the server

    Shell
    sudo adduser --disabled-password --gecos "" minecraft

    This creates the user minecraft with a home directory and a normal shell, but no password, so nobody can sign in as it directly. You reach it from your own account with sudo. On Alma, Rocky, or RHEL use sudo useradd -m minecraft instead.

    Switch to it:

    Shell
    sudo -iu minecraft
  3. Make a directory for the server

    As the minecraft user:

    Shell
    mkdir -p ~/server && cd ~/server

    Everything the server writes stays inside this folder: the world, the config, the logs, and the plugins.

  4. Download Paper

    Open papermc.io in a browser, choose your Minecraft version, and copy the download link for the latest build. Then, on the server:

    Shell
    wget -O paper.jar 'PASTE_THE_DOWNLOAD_URL_HERE'

    Save it as paper.jar rather than the versioned filename. The service file below then never has to change when you update, and you can keep the previous jar alongside it to roll back to.

  5. Accept the EULA

    Run the server once. It will stop straight away:

    Shell
    java -Xms2G -Xmx2G -jar paper.jar --nogui

    It writes eula.txt and exits with a message telling you to agree to Mojang's EULA. Read it, then set the flag:

    Shell
    sed -i 's/eula=false/eula=true/' eula.txt

    The -Xms and -Xmx values are the Java heap, set here to a plain starting point. Sizing them properly is covered in Optimising a Minecraft server.

  6. First real run

    Run the same command again:

    Shell
    java -Xms2G -Xmx2G -jar paper.jar --nogui

    It generates the world and the config files, which takes a minute or two, and finishes with a Done line and a console prompt. Type stop and press enter to shut it down cleanly. Never kill it with Ctrl-C part way through a save if you can avoid it.

    You now have server.properties, a world folder, a plugins folder, and logs/latest.log.

  7. Set the basics in server.properties

    Open server.properties in an editor. The ones worth setting before you go live:

    SettingWhat to do with it
    server-portLeave at 25565 unless you have a reason. Whatever you set here is the port you must open.
    online-modeLeave true. This is what verifies joining accounts against Mojang, and it is the single biggest anti-bot control you have. See Protecting a Minecraft server from attacks.
    max-playersSet it to what your machine and your heap can actually hold, not to an aspiration.
    motdThe line shown in the client's server list.
    view-distance and simulation-distanceThe two highest-impact performance settings. Covered in Optimising a Minecraft server.
    white-listSet true for a private server, and add names with /whitelist add.

    The server reads this file at startup, so restart after editing it.

Keeping it running

Closing your SSH session kills anything you started in it. You need the server to survive that, and to come back after a reboot.

Under systemd

This is the option to take for anything you care about. Leave the minecraft user first:

Shell
exit

Create the unit file:

Shell
sudo nano /etc/systemd/system/minecraft.service
Config
[Unit]
Description=Minecraft server
After=network-online.target
Wants=network-online.target
 
[Service]
Type=simple
User=minecraft
Group=minecraft
WorkingDirectory=/home/minecraft/server
ExecStart=/usr/bin/java -Xms2G -Xmx2G -jar paper.jar --nogui
Restart=on-failure
RestartSec=10s
TimeoutStopSec=120
SuccessExitStatus=0 143
 
[Install]
WantedBy=multi-user.target

SuccessExitStatus=0 143 tells systemd that exiting on SIGTERM is a normal stop, not a crash, so Restart=on-failure does not fight you. TimeoutStopSec=120 gives the server time to save the world before systemd loses patience: the Minecraft server handles SIGTERM by saving and shutting down, and a large world does not do that instantly.

A stopYou stop itsudo systemctl stop minecraftsystemd sends SIGTERMThe server saves and shuts downA large world does not save instantly.TimeoutStopSec=120: time to saveIt exits on the SIGTERMSuccessExitStatus=0 143 counts that exit as anormal stop, so Restart=on-failure leaves itstopped.A crashIt crashesThe server exits on a failureRestart=on-failure starts it againsystemd waits, then starts the same command.RestartSec=10sThe server is backWithout anyone signing in to start it.
The same unit file meeting a stop and a crash. A stop ends in an exit systemd has been told is normal, so nothing restarts it; a crash ends in a failure, which is exactly what Restart=on-failure restarts. Illustration.

Enable and start it:

Shell
sudo systemctl daemon-reload
sudo systemctl enable --now minecraft
sudo systemctl status minecraft

Watch the log live:

Shell
sudo journalctl -u minecraft -f

Stop and start it with sudo systemctl stop minecraft and sudo systemctl start minecraft. Because the console is not attached to a terminal, you cannot type commands into it this way. Use RCON over an SSH tunnel, or an in-game admin plugin, or run under tmux instead.

Under tmux

Simpler, and it gives you the console back, but it does not restart the server after a crash or a reboot.

Shell
sudo apt install -y tmux
sudo -iu minecraft
cd ~/server
tmux new -s mc
java -Xms2G -Xmx2G -jar paper.jar --nogui

Detach with Ctrl-b then d, and the server keeps running. Come back to it with:

Shell
sudo -iu minecraft
tmux attach -t mc

Use tmux while you are setting things up, and move to systemd before players arrive.

systemdtmuxSurvives closing your SSHsessionRestarts the server after acrashBrings it back after arebootA console you can type intoUnder systemd: RCON over anSSH tunnel, or an in-gameadmin pluginUse itsystemd: anything you care abouttmux: while you are setting things up
What each way of running the server gives you. Both outlive your SSH session; only systemd survives a crash or a reboot, and only tmux hands you back a console to type into. Illustration.

Opening the port

The server is listening, but nothing can reach it until the port is open.

On a Clouduxe server, apply the Minecraft (Java) preset, which writes the TCP 25565 rule for you, or add the rule by hand if you changed server-port. See Game presets and Port rules.

If you also run a firewall on the machine itself, allow the port there too:

Shell
sudo ufw allow 25565/tcp

Testing the connection

In the Java client, open Multiplayer, press Add Server, and enter your server's IP address. You do not need to type the port if it is 25565.

If it does not connect, work through When players cannot connect, and check sudo journalctl -u minecraft -f at the same time so you can see whether the connection is reaching the server at all.

Back it up before you change anything

Copy the world before your first plugin, your first config change, and every update after that. Stop the server first, or you will copy a region file that was half-written when you started.

Shell
sudo systemctl stop minecraft
sudo -iu minecraft
tar czf ~/world-backup-$(date +%F).tar.gz -C ~/server world world_nether world_the_end

See Backups for keeping a copy somewhere other than the machine that is running the server, which is the only kind of backup that helps when the machine is the problem.

Need a server, or a hand with one?

Pick a plan to deploy a server, or open a ticket in the panel. Support runs 24/7/365.