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

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:
- Stop the server:
sudo systemctl stop minecraft.service - Back up the world:
sudo cp -r /opt/minecraft/server/world /opt/minecraft/backups/world-$(date +%Y%m%d) - Download the new server JAR (replace the old
server.jar) - Start the server:
sudo systemctl start minecraft.service - 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:
- Reduce
view-distanceinserver.properties(from 10 to 6-8) - Reduce
simulation-distance(from 8 to 4-6) - In PaperMC: increase
mob-spawn-rangedelay and reduce entity activation ranges - 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.
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=truefor any server that faces the internet - Allocate RAM deliberately with
-Xmxand-Xmsflags, 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:
- Minecraft Server in Docker -- Run your Minecraft server in a container for easy management and portability.
- Minecraft Server on Raspberry Pi -- Run a Minecraft server on a Raspberry Pi for a low-power family server.
- Minecraft Server on Windows -- Get a Minecraft server running on a spare Windows PC in minutes.
- Install Docker on Ubuntu 24.04 -- Get Docker installed and running on Ubuntu 24.04 LTS.
- Linux Fundamentals -- Core Linux skills every self-hoster needs.
- How to Build Your First Homelab in 2026 -- Start your self-hosting journey with a practical homelab build.

ReadTheManual is run, written and curated by Eric Lonsdale.
Eric has over 20 years of professional experience in IT infrastructure, cloud architecture, and cybersecurity, but started with PCs long before that.
He built his first machine from parts bought off tables at the local college campus, hoping they worked. He learned on BBC Micros and Atari units in the early 90s, and has built almost every PC he’s used between 1995 and now.
From helpdesk to infrastructure architect, Eric has worked across enterprise datacentres, Azure environments, and security operations. He’s managed teams, trained engineers, and spent two decades solving the problems this site teaches you to solve.
ReadTheManual exists because Eric believes the best way to learn IT is to build things, break things, and actually read the manual. Every guide on this site runs on infrastructure he owns and maintains.
Enjoyed this guide?
New articles on Linux, homelab, cloud, and automation every 2 days. No spam, unsubscribe anytime.

