How to Host Minecraft Server for Friends on VPS
Run Paper Minecraft for Java Edition on Ubuntu 24.04. See why 1 GB no dey work, use Java 25, systemd, ufw port 25565, and safe backups.
Wetin you dey build
Minecraft Java Edition server wey go stay up: Paper for Ubuntu 24.04, dey run as dedicated minecraft user under systemd with Restart=on-failure, whitelist on, port 25565 open for ufw and your provider network firewall if dem enable one, plus backups wey you take in a way wey no go corrupt the world wey dem suppose protect. The server itself na one jar and one java command. Everything wey separate server wey your friends fit play for one year from server wey go die the first weekend dey around that command, and na wetin this guide cover.
Two honest warnings before you spend money. First, Minecraft dey chop plenty memory and e mostly use one CPU thread: 1 GB VPS no go run playable server, and one fast core better pass four slow ones. Second, na Java Edition be this. Bedrock players, consoles, phones, and the Windows Bedrock app no fit join Java server. Bedrock need different server software for UDP 19132, or the Geyser plugin, but we no go cover that here.
You need fresh Ubuntu 24.04 KVM VPS with root or sudo, plus about thirty minutes.
Sizing: wetin friends server really need
RAM na the number wey matter, and the honest figures dey lower than wetin modpack forums suggest:
- 2 GB fit run vanilla for 2–5 players with modest view distance. E dey playable, but no spare capacity.
- 4 GB na the comfortable size for friends server: around ten concurrent players on Paper with some plugins, plus enough memory for the OS.
- 8 GB and up na modpack and 20-plus-player territory. For this level, you suppose also care about single-core CPU speed, because the main game loop dey run for one thread.
The world go still grow for disk as players dey explore. A survival world wey players don travel well fit reach several gigabytes, so leave spare capacity for the world and its backups.
Vanilla or Paper? Paper na drop-in replacement for the official jar: e use the same worlds and clients, and e no need client-side mods. E rewrite the slowest server paths, including chunk loading, entity ticking, and hoppers, and e add plugin API. The only reason to run vanilla na if you need bit-exact vanilla mechanics for technical redstone farms wey Paper optimisations fit change. For everybody else, Paper fit support more players per gigabyte. Everything below work for both.
Step 1: install Java 25
Minecraft 26.1 and every release since require Java 25; na only Java 21 cover the older 1.20 to 1.21.11 line. Ubuntu 24.04 dey ship Java 25 through im updates and security repos. Install the full JRE, no be the -headless build: Paper Java install guide warn say make you avoid headless variants because dem no get some dependencies wey Paper need.
sudo apt update && sudo apt install -y openjdk-25-jre
java -versionCorrect result: the first line go read openjdk version "25.0.x". If e read 21, 17 or 11, another JRE dey installed and na im dey win; fix am with sudo update-alternatives --config java and choose the entry wey contain java-25.
If you skip this check, na this one be the Minecraft server error wey people search pass later. With Java 21, the server jar go die immediately with:
Error: LinkageError occurred while loading main class net.minecraft.bundler.Main
java.lang.UnsupportedClassVersionError: net/minecraft/bundler/Main has been
compiled by a more recent version of the Java Runtime (class file version 69.0),
this version of the Java Runtime only recognizes class file versions up to 65.0The numbers show the mismatch: class file version 69.0 na Java 25, 65.0 na Java 21, and 61.0 na Java 17. Any pair wey you see, the fix remain the same: install the newer JRE and run update-alternatives again.
Step 2: dedicated user, never root
The server dey execute plugin code and parse network input from anybody wey fit reach the port. If anything go wrong, compromise wey dey run as root go control your VPS; the one wey dey run as minecraft go control one game world.
sudo adduser --system --group --home /opt/minecraft minecraft--system dey create account wey no get password and no fit log in through SSH, with /opt/minecraft as the home and working directory. From this point, every command wey dey touch the server go run as this user.
Step 3: download server jar from official source
Na only two places suppose ever give you server jar: official server download page for minecraft.net for vanilla, and downloads page for papermc.io for Paper. Third-party “download hubs” wey dey repackage server jars na long-running malware channel. Server jar na arbitrary code wey you dey about to run 24/7 for server wey internet fit reach.
Copy download link for the current build from official page. The URL dey change with every version and build, so if we hardcode one here, e go become outdated. Then:
cd /opt/minecraft
sudo -u minecraft wget -O server.jar 'PASTE-THE-COPIED-URL-HERE'Correct result: na a server.jar of roughly 60 MB wey minecraft own, and ls -lh /opt/minecraft/server.jar don confirm am.
Step 4: first run, the EULA, and op-ing yourself
Run the server interactively once before you touch systemd, because only live console fit do two important jobs for the first run.
cd /opt/minecraft
sudo -u minecraft java -Xms1G -Xmx1G -jar server.jar noguiE go stop within seconds. Paper go spend some extra moments apply patches first, then the log go end with the line wey everybody dey see:
[ServerMain/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.This no be error; na license gate. The run write eula.txt beside the jar. Read the linked EULA if you never read am, then change the flag:
sudo -u minecraft sed -i 's/eula=false/eula=true/' /opt/minecraft/eula.txtRun the same java command again. This time e go generate the world, wey fit take one or two minutes for first boot, then e go settle for:
[Server thread/INFO]: Done (9.204s)! For help, type "help"You don get live console now. Use am for the second job: type op YourMinecraftName (your exact in-game username), and the server go write you into ops.json. So later, when no console dey attached, you fit run every admin command from inside the game. Then type stop to save and exit cleanly.
Step 5: server.properties, and why online-mode dey stay true
The first run still write server.properties. Most defaults dey okay; na these lines you suppose decide intentionally:
online-mode=true
white-list=true
enforce-whitelist=true
view-distance=8
max-players=10
motd=A private server for people I actually knowonline-mode=true make the server verify every username wey dey join against Mojang's session servers, to prove say the player own the account. If you set am to false, the "cracked server" toggle, the server go believe any client about who dem be: anybody fit join with any name, including your own, and because ops and whitelists dey use name, person wey impersonate you fit enter with your operator permissions. The only valid reason to set am false na when server dey behind authenticating proxy like Velocity, wey verify players by itself. For normal server, e stay true, no argument.
view-distance na the biggest performance control for the file. CPU and RAM cost dey increase roughly with the square of the value. 8 na sensible VPS default; 10 na the vanilla default and e dey use noticeably more resources.
white-list=true plus enforce-whitelist=true close the server to strangers. The security section below explain why this one no be optional. Add players with /whitelist add TheirName in-game as an op.
Step 6: memory flags, wetin make -Xms and -Xmx suppose match
The JVM dey allocate heap between -Xms (starting size) and -Xmx (ceiling). For dedicated game server, set both to the same value: heap go reach the ceiling anyway, and to dey grow am in steps just dey add garbage-collector churn during play. For 4 GB VPS, the correct pair na:
/usr/bin/java -Xms3G -Xmx3G -jar server.jar nogui-Xmx no be the total memory wey the process dey use. JVM dey add off-heap overhead, thread stacks, JIT caches, and direct buffers, wey fit reach roughly half gigabyte or more. Ubuntu sef need space. The working rule be say: -Xmx no suppose pass VPS RAM minus 1 GB. If you overshoot, one of two failures fit happen. If allocation fail from the beginning, server go refuse to start with:
Error: Could not reserve enough space for object heapThat one clear and immediate. The more dangerous one fit start well, then stop after some hours when heap full under load and kernel OOM killer pick the biggest process for the machine, wey be the JVM. Nothing go show for server log; the evidence dey inside sudo dmesg | grep -i oom, with line like Out of memory: Killed process 1234 (java). If your service dey restart "randomly", check there first, then reduce -Xmx.
For Paper, the project documentation get Aikar's flags, na tuned G1GC set (-XX:+UseG1GC -XX:MaxGCPauseMillis=200 and about twelve other flags) wey dey reduce garbage-collection pauses for bigger heaps. Generate the complete line from Paper documentation; for 2–4 GB heap, the improvement small, but the flags no dey cause problem.
Step 7: systemd unit wey get Restart=on-failure
Server wey you start by hand go die together with your SSH session, and e go remain down after reboot. Write /etc/systemd/system/minecraft.service:
[Unit]
Description=Minecraft server (Paper)
After=network-online.target
Wants=network-online.target
[Service]
User=minecraft
Group=minecraft
WorkingDirectory=/opt/minecraft
ExecStart=/usr/bin/java -Xms3G -Xmx3G -jar server.jar nogui
Restart=on-failure
RestartSec=10
TimeoutStopSec=120
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now minecraft
systemctl status minecraft
journalctl -u minecraft -fCorrect result: status go show active (running), and journal, wey now dey carry the server console output, go end for Done line again.
Two deliberate choices dey for that unit. Restart=on-failure go bring the server back after crash, but e no go do am after clean stop, so maintenance still fit happen. And TimeoutStopSec=120 important pass as e fit look: systemctl stop dey send SIGTERM, the Minecraft server dey catch am and save every world before e exit, and that save fit take time for big world. Systemd default timeout fit send SIGKILL to the JVM while e still dey save, and na exactly this one dey corrupt region files. Give am two minutes.
If the service dey flap and journal show:
[Server thread/WARN]: **** FAILED TO BIND TO PORT!
[Server thread/WARN]: The exception was: io.netty.channel.unix.Errors$NativeIoException: bind(..) failed: Address already in use
[Server thread/WARN]: Perhaps a server is already running on that port?then something already dey hold 25565, almost always na your earlier foreground run wey still dey alive for another SSH session. Find am with sudo ss -tlnp | grep 25565 and stop that copy; never run two servers for one port.
Step 8: open 25565 for both firewalls
Minecraft Java na use TCP 25565 only (UDP na just optional query protocol, and e dey off by default). For the VPS:
sudo ufw allow OpenSSH
sudo ufw allow 25565/tcp
sudo ufw enableNa firewall one be that. Plenty VPS providers still get another network-level firewall for the control panel, and na this second one people dey often forget. For SSD Nodes, na Advanced Firewall Groups add-on be this. E be paid extra wey you assign during checkout or from the dashboard. If your server get one, open TCP 25565 there too. If either firewall no get the rule, the symptom no clear at all: client go hang for "Connecting to the server..." and fail with Connection timed out: no further information. E no go show refusal, server error, or anything for the journal, because the packets never reach the server. Verify from a machine outside the VPS with nc -vz your.server.ip 25565. succeeded mean say every firewall for the path dey open. If connection hang, usually one firewall still dey drop the packets. But host wey too busy to accept connections fit also time out, so confirm say server dey listen with ss on the box.
As you dey inside ufw, remember say the same box dey run SSH on public IP, and brute-force log noise fit start within hours. set up Fail2ban for SSH on Ubuntu 24.04 before you forget.
Now connect: Multiplayer, Direct Connection, then enter the server IP. Because you op'd yourself for step 4, in-game commands go work immediately, /whitelist add FriendName for each player, /gamemode creative if na the plan.
Step 9: whitelist, because internet dey find port 25565
To leave Minecraft server open to internet no be theoretical risk: mass scanners dey sweep the whole IPv4 space continuously for port 25565, hobbyist griefing projects don map hundreds of thousands open servers this way, and server wey no get whitelist go receive visitors wey nobody invite within days, sometimes hours. The whitelist from step 5 na the fix: online-mode=true dey prove identity, while the whitelist restrict entry to identities wey you choose. This pair na the complete security model, and e enough for server wey your friends dey use.
For console access without the game, scripted backups, or cron job, enable RCON inside server.properties (enable-rcon=true, use strong rcon.password, port 25575) and build the small mcrcon client from its GitHub source directly on the VPS; Ubuntu repos no get am. Do not open 25575 for any firewall: RCON dey send password as cleartext, so e must remain loopback-only.
Step 10: backup wey no go spoil everything
The main rule be say: never copy world directory while server dey write to am. Region files dey change continuously while people dey play; a tar wey race with a write fit create archive wey get half-written chunks. When you later restore am, na that one time wey backup suppose work, log go full with chunk-loading errors and terrain go get holes. Two methods fit prevent this.
Stop-copy-start na the simple method, but e go cost one minute of downtime:
sudo systemctl stop minecraft
sudo mkdir -p /opt/backups
sudo tar czf /opt/backups/world-$(date +%F-%H%M).tgz \
-C /opt/minecraft world
sudo systemctl start minecraft(Since 26.1, Paper dey keep all three dimensions inside world/dimensions/, just like vanilla, so world na the whole world. Paper server wey still dey run 1.21.11 or older go split dem into world, world_nether, and world_the_end; for that case, add those two to the tar.)
Save-off dey back up live server: through RCON, issue save-off (stop the autosaver), then save-all flush (force everything go disk and wait), take the tar, then save-on. Na this version you suppose put for cron at 5 a.m.
Either way, backup wey dey for the same VPS with the server no be real backup. scp or rclone the archives comot from the box, and keep more than one copy. Since you no go dey watch console when something spoil, set external check for the port: Uptime Kuma for another box wey dey run TCP check against 25565 go tell you say server don go down before your players notice.
Plugins and upgrades
For Paper, plugin na jar wey you drop inside /opt/minecraft/plugins/, then restart the server. Na so the installation complete. Get plugins only from their official project pages (Hangar, Modrinth, SpigotMC), for the same reason as the server jar: each one na arbitrary code wey dey run as the minecraft user.
To upgrade the server, stop am, back am up, replace server.jar with the build for the new Minecraft version, then start am. Pay attention to two things. World upgrades na one-way process. World wey newer version don open no go open for older version again. Na another reason to keep backups. Plugins too often need days or weeks before dem support new Minecraft release, so check compatibility before you rush follow release for the first day. If you move from 1.21.11 to 26.1 or later, you also need Java 25 (step 1), and Paper go move Nether and End folders into world/dimensions/.
If you prefer manage everything as container, with version pinning, EULA acceptance, and memory flags as environment variables, the widely used itzg/minecraft-server image go run the same Paper server under Docker Compose for your VPS with the same firewall and backup discipline.
FAQ
How much RAM Minecraft server need?
2 GB fit run vanilla for 2–5 players; 4 GB comfortable for friends server wey get around ten players for Paper with small number of plugins; modpacks and 20-plus players need 8 GB or more. No matter the VPS size, set -Xmx to at most total RAM minus 1 GB, because JVM dey use memory outside the heap, and if you set am too high e fit end for Error: Could not reserve enough space for object heap or silent OOM kill.
Why my friends no fit connect to my Minecraft server?
If client hang and end for Connection timed out: no further information, e usually mean firewall problem: ufw for the VPS, plus your provider network firewall if one dey enabled for control panel. TCP 25565 must dey open for every firewall wey traffic pass through. Confirm say server dey listen with sudo ss -tlnp | grep 25565 for the machine, then test from outside with nc -vz your.server.ip 25565.
I suppose set online-mode=false for server.properties?
No. With online-mode=false, server go skip Mojang authentication completely. Anybody fit join with any username, including op name, and inherit that person permissions. Skins and stable UUIDs go also stop working properly. The only valid use na behind authenticating proxy like Velocity wey verify players by itself. For normal server, leave am as true.
Paper better pass vanilla Minecraft server?
For almost everybody, yes. Paper na drop-in jar wey loads vanilla worlds, accepts unmodified clients, ticks entities and loads chunks much more efficiently, and adds plugin ecosystem. The exception na technical-redstone communities wey need vanilla behaviour wey match exactly, because some Paper optimisations dey change am. For small VPS, Paper efficiency dey give you extra RAM almost free.
How I fit back up Minecraft world without corrupting am?
Never archive world directory while server dey write to am. If copy race with region-file write, e fit produce corrupted chunks wey you no go discover until restore time. Either stop server, tar the world directories, then start am again, or keep server live with save-off, save-all flush, tar, save-on over RCON. Then move the archive comot from the VPS.