How to Set Up a Minecraft Server on Ubuntu 24.04

Why a Minecraft Server Is the Best First Server Project

I have been running servers professionally for over twenty years. Linux, Windows, bare metal, virtualised, containerised, on-prem, cloud. And if someone asked me what the single best learning project is for someone who wants to understand server administration, I would tell them to set up a Minecraft server.

From the homelab: Setting up game servers is a brilliant way to learn Linux administration. You deal with services, firewalls, port forwarding, and resource management — the same skills you will use running production infrastructure. I have seen people start with a Minecraft server and end up managing enterprise systems.

Not because of the game. Because of what it teaches you. A Minecraft server hits every fundamental skill: Linux command line, Java runtime configuration, memory management, systemd service management, firewall rules, network port forwarding, and performance tuning. If you can stand up a Minecraft server on Ubuntu, configure it properly, keep it running through reboots, and let friends connect to it remotely, you have just done more real server administration than most people do in their first six months of studying for a certification.

This guide treats the Minecraft server as infrastructure, not as a gaming tutorial. I will cover the proper way to do this: dedicated user, systemd service, firewall configuration, and a production-grade server JAR. If you just want to double-click something and play, this is not that guide. If you want to learn how servers actually work, keep reading.

Terminal showing a Minecraft server starting on Ubuntu 24.04 with Java 21

Prerequisites

Before you start, make sure you have:

  • A machine running Ubuntu 24.04 LTS (server or desktop, either works)
  • sudo access on that machine
  • At least 4 GB of RAM (2 GB for the server, 2 GB for the OS). 8 GB is better if you want more than a handful of players.
  • A working internet connection for downloading packages and the server JAR
  • Minecraft Java Edition on whatever device you will use to connect (the server JAR is free, but the client is not)

You do not need a powerful CPU for a small Minecraft server. A quad-core processor handles 5-10 players comfortably. The bottleneck is almost always single-thread performance and RAM, not core count. Minecraft’s server is largely single-threaded for world ticking, which is why clock speed matters more than having 16 cores.

If you are new to Ubuntu and want to get comfortable with the command line first, read Linux commands that actually get you hired before continuing.

Step 1: Install Java 21

Minecraft 1.20.5 and later require Java 21. Earlier versions ran on Java 17 or even Java 8, but the current release needs 21. Install OpenJDK 21 from Ubuntu’s repositories:

sudo apt update
sudo apt install -y openjdk-21-jre-headless

The -headless variant skips the GUI libraries, which you do not need on a server. Verify the installation:

java -version

You should see output like:

openjdk version "21.0.x" 2024-xx-xx
OpenJDK Runtime Environment (build 21.0.x+xx-Ubuntu-1ubuntu1)
OpenJDK 64-Bit Server VM (build 21.0.x+xx-Ubuntu-1ubuntu1, mixed mode, sharing)

If you see a Java version, you are good. If the command is not found, the installation failed. Check sudo apt install -y openjdk-21-jre-headless again and watch for errors.

Step 2: Create a Dedicated User

Never run a game server as root or under your personal account. Create a dedicated system user with no login shell:

sudo useradd -r -m -d /opt/minecraft -s /bin/bash minecraft

This creates a user called minecraft with a home directory at /opt/minecraft. The server files will live here. This is standard practice for any service: isolate it under its own user so it cannot read or write files belonging to other services or your personal account.

Creating dedicated service accounts is something you will do in every infrastructure role. Whether it is a Minecraft server, a database, or a web application, the principle is identical: least privilege. Each service gets its own user, its own directory, and only the permissions it needs. Interviewers ask about this. Know why you do it, not just how.

Step 3: Download the Server JAR

You have two options here: vanilla (Mojang’s official server) or PaperMC. I strongly recommend PaperMC.

Option A: Vanilla server (from Mojang)

The official server JAR is free to download from minecraft.net/download/server. Download it to the minecraft user’s directory:

sudo -u minecraft mkdir -p /opt/minecraft/server
sudo -u minecraft wget -O /opt/minecraft/server/server.jar \
  https://piston-data.mojang.com/v1/objects/LATEST_HASH/server.jar

Replace the URL with the current download link from the Minecraft website. The hash in the URL changes with each release.

Option B: PaperMC (recommended)

PaperMC is a high-performance fork of the vanilla server. It is fully compatible with vanilla clients but runs significantly better: lower memory usage, better tick performance, async chunk loading, and plugin support. There is no reason not to use it.

sudo -u minecraft mkdir -p /opt/minecraft/server
sudo -u minecraft wget -O /opt/minecraft/server/server.jar \
  https://api.papermc.io/v2/projects/paper/versions/1.21.4/builds/LATEST/downloads/paper-1.21.4-LATEST.jar

Check papermc.io/downloads for the current version and build number, and update the URL accordingly.

PaperMC also supports plugins via the Bukkit/Spigot API, so you can add things like world protection, permissions management, and anti-cheat later without changing the base server. For a homelab server this is overkill, but if you are running a server for a community, plugins become essential.

Step 4: Accept the EULA and Configure the Server

Run the server once to generate the configuration files:

sudo -u minecraft bash -c 'cd /opt/minecraft/server && java -Xmx2G -Xms1G -jar server.jar --nogui'

It will fail on first run with a message about the EULA. This is expected. Accept it:

sudo -u minecraft sed -i 's/eula=false/eula=true/' /opt/minecraft/server/eula.txt

Now configure server.properties. This file controls everything about your server. Here are the settings worth changing from their defaults:

sudo -u minecraft tee /opt/minecraft/server/server.properties > /dev/null <<'EOF'
# Server basics
server-port=25565
motd=A Minecraft Server
max-players=10
difficulty=normal
gamemode=survival
level-name=world

# Security
white-list=true
enforce-whitelist=true
online-mode=true
enable-command-block=false

# Performance
view-distance=10
simulation-distance=8
max-tick-time=60000
network-compression-threshold=256

# Misc
enable-rcon=false
spawn-protection=16
EOF

Key settings explained:

  • white-list=true - Only players you explicitly approve can join. Non-negotiable for any server exposed to the internet.
  • online-mode=true - Verifies player accounts with Mojang. Turning this off lets pirated copies connect. Leave it on.
  • view-distance=10 - How many chunks around each player the server keeps loaded. Lower values reduce CPU and RAM usage dramatically. Default is 10, reduce to 6-8 if performance is tight.
  • simulation-distance=8 - How many chunks around each player are actively simulated (mobs, redstone, etc.). Can be lower than view-distance.
  • enable-rcon=false - Remote console access. Leave this off unless you specifically need it and have secured it properly.

Step 5: Allocate RAM Properly

The -Xmx and -Xms Java flags control memory allocation. This is where most people either under-allocate (server lags) or over-allocate (OS starves).

  • -Xms - Minimum heap size (Java starts with this much)
  • -Xmx - Maximum heap size (Java will not exceed this)

Guidelines:

  • 1-5 players: 2-3 GB (-Xmx3G -Xms2G)
  • 5-10 players: 4-6 GB (-Xmx6G -Xms4G)
  • 10-20 players: 6-8 GB (-Xmx8G -Xms6G)

Always leave at least 1-2 GB free for the operating system. If your machine has 8 GB total, do not set -Xmx above 6 GB. Java's garbage collector also needs headroom above the heap, so allocating literally all available RAM to -Xmx will cause out-of-memory kills.

Do not set -Xms and -Xmx to the same value unless you know exactly why you are doing it. Some guides recommend this to "avoid garbage collection pauses," but it forces Java to reserve all that memory at startup whether it needs it or not. On a shared machine, that is wasteful. Let Java grow into its allocation.

Step 6: Create a systemd Service

Running the server in a terminal session is not acceptable. If you close the terminal, log out, or the SSH connection drops, the server dies. Create a systemd service so the server starts on boot, restarts on failure, and can be managed with standard tools.

sudo tee /etc/systemd/system/minecraft.service > /dev/null <<'EOF'
[Unit]
Description=Minecraft Server
After=network.target
Wants=network-online.target

[Service]
User=minecraft
Group=minecraft
WorkingDirectory=/opt/minecraft/server

ExecStart=/usr/bin/java -Xmx4G -Xms2G -jar server.jar --nogui
ExecStop=/bin/kill -SIGINT $MAINPID
TimeoutStopSec=30

Restart=on-failure
RestartSec=10

StandardInput=null
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

Enable and start it:

sudo systemctl daemon-reload
sudo systemctl enable minecraft.service
sudo systemctl start minecraft.service

Check it is running:

sudo systemctl status minecraft.service

You should see Active: active (running). To watch the server log in real time:

sudo journalctl -u minecraft.service -f

Press Ctrl+C to stop following the log. For a deeper dive into systemd service management, read mastering systemctl.

The ExecStop line sends SIGINT, which tells the Minecraft server to save worlds and shut down gracefully. The TimeoutStopSec=30 gives it 30 seconds to finish saving before systemd forces a kill. If you have a large world, you might need to increase this.

Step 7: Configure the Firewall

If UFW (Uncomplicated Firewall) is enabled on your server, you need to allow Minecraft's port:

sudo ufw allow 25565/tcp comment 'Minecraft Server'
sudo ufw status

You should see port 25565 listed as ALLOW. If UFW is not active (Status: inactive), you should seriously consider enabling it. A server exposed to the internet with no firewall is asking for trouble:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh comment 'SSH'
sudo ufw allow 25565/tcp comment 'Minecraft Server'
sudo ufw enable

If you are connecting from outside your local network, you also need to set up port forwarding on your router. Forward external port 25565 TCP to your server's internal IP address on port 25565. The exact steps depend on your router model. If your ISP uses CGNAT (common with mobile broadband and some fibre providers in the UK), port forwarding will not work and you will need a VPN tunnel or a service like Tailscale to allow external connections.

Step 8: Connect and Test

Open Minecraft Java Edition, go to Multiplayer, and add a new server:

  • From the same machine: localhost
  • From another device on your network: Your server's local IP (e.g., 192.168.1.50)
  • From outside your network: Your public IP or domain name (after port forwarding)

The default port is 25565, so you do not need to specify it in the address. If you changed the port in server.properties, append it with a colon: 192.168.1.50:25566.

Managing Players: Whitelist and Ops

With white-list=true in your server properties, no one can join until you add them. Manage the whitelist from the server console (via journalctl or by attaching to the process):

# Add a player to the whitelist
sudo -u minecraft bash -c 'echo "whitelist add PlayerName" >> /opt/minecraft/server/stdin'

The easier approach is to edit the files directly. The whitelist is stored in /opt/minecraft/server/whitelist.json. To give a player operator (admin) privileges, edit /opt/minecraft/server/ops.json or use the op PlayerName command in the server console.

If you need to send commands to the running server, you can use mcrcon (a Minecraft RCON client) or simply stop the service, make changes to the JSON files, and restart. For a small homelab server, file editing is simpler and less error-prone than setting up RCON.

Updating the Server

When a new Minecraft version releases:

  1. Stop the server: sudo systemctl stop minecraft.service
  2. Back up the world: sudo cp -r /opt/minecraft/server/world /opt/minecraft/backups/world-$(date +%Y%m%d)
  3. Download the new server JAR (replace the old server.jar)
  4. Start the server: sudo systemctl start minecraft.service
  5. Check the logs for errors: sudo journalctl -u minecraft.service -n 50

Always back up before updating. Minecraft version updates occasionally change the world format, and there is no downgrade path. If the new version corrupts your world or a plugin is not compatible yet, you want to be able to roll back. This is true of every service you will ever manage, not just Minecraft.

Performance Tuning

If you are running PaperMC, you get access to additional configuration files that vanilla does not have:

  • paper-global.yml - Global performance settings (async chunk loading, entity limits)
  • paper-world-defaults.yml - Per-world defaults for mob spawning, tick rates, and entity behaviour

For a small server (under 10 players), the defaults are fine. If you start seeing TPS (ticks per second) drop below 20, the most effective changes are:

  1. Reduce view-distance in server.properties (from 10 to 6-8)
  2. Reduce simulation-distance (from 8 to 4-6)
  3. In PaperMC: increase mob-spawn-range delay and reduce entity activation ranges
  4. Pre-generate the world using a plugin like Chunky (avoids lag spikes when players explore new areas)

Monitor TPS in-game with /tps (PaperMC) or by watching the server log for "Can't keep up!" warnings.

Next Steps

Once your server is running, here are some paths to explore:

  • Run Minecraft in Docker - Containerise the server for easier updates, backups, and the ability to run multiple instances on different ports.
  • Minecraft on a Raspberry Pi - A dedicated low-power server that does not need your main machine running 24/7.
  • Install Docker on Ubuntu 24.04 - Once you are comfortable with systemd services and firewall rules, Docker is the natural next step.
  • Set up Tailscale - Let friends connect to your server without exposing port 25565 to the internet.

Everything you just did maps directly to real infrastructure work. You installed a runtime (Java), configured a service (server.properties), managed it with systemd, opened firewall ports, and planned for updates and backups. Swap "Minecraft server" for "Tomcat application server" or "Elasticsearch cluster" and the workflow is identical. If you are working towards a career in infrastructure, DevOps, or platform engineering, this project gives you genuine hands-on experience with the tools you will use every day.

Watch out: Java version matters. Newer Minecraft versions need Java 17+, but some Linux repos still default to Java 11. If you get cryptic startup errors, check java -version first.

Key Takeaways

  • A Minecraft server teaches Linux administration, Java configuration, systemd, firewall management, and performance tuning in a single project
  • Always run game servers under a dedicated user account, never as root or your personal user
  • Use PaperMC instead of the vanilla server JAR for better performance and plugin support at no cost
  • Run the server as a systemd service so it survives reboots, SSH disconnects, and crashes
  • Enable the whitelist and keep online-mode=true for any server that faces the internet
  • Allocate RAM deliberately with -Xmx and -Xms flags, and always leave headroom for the operating system
  • Back up the world directory before every update because there is no downgrade path for Minecraft worlds

Related Guides

If you found this useful, these guides continue the journey:

The RTM Essential Stack - Gear I Actually Use

Enjoyed this guide?

New articles on Linux, homelab, cloud, and automation every 2 days. No spam, unsubscribe anytime.

Scroll to Top