CentOS Minecraft Server
CentOS stream makes for a nice Minecraft server.
The guide below should be enough to setup the server from scratch on a fresh install of CentOS Stream. Overall I liked the setup, feels very intuitive and well structured. One thing I like about using CentOS is the built-in web console that makes it easy to manage the Minecraft server without SSHing in.
Initial Setup
System Requirements
- CentOS 9 Stream or 10 Stream
- Minimum 4GB RAM (4GB+ recommended)
- Java 21 (for Minecraft 1.20+)
Note: For commands run as the minecraft user, you can use either sudo -u minecraft <command> or can create a shell instead and work from there: sudo -u minecraft bash
Create a Dedicated User
Create a system user for running the Minecraft server:
sudo useradd -r -m -d /opt/minecraft -s /sbin/nologin minecraft
This creates a system user with home directory at /opt/minecraft , which is where non-default applications should go on CentOS.
May receive a message about directory already existing if a separate 4 GiB partition was created for /opt/minecraft.
Configure Firewall
Open the default Minecraft port:
sudo firewall-cmd --permanent --add-port=25565/tcp
sudo firewall-cmd --reload
To verify:
sudo firewall-cmd --list-all
Installing the Minecraft Server
Install Java
Install OpenJDK 21 from the CentOS repositories:
sudo dnf install java-21-openjdk-headless
Verify installation:
java -version
Set Permissions
Allow the new user to access the working directory:
sudo chown -R minecraft:minecraft /opt/minecraft
sudo chmod 750 /opt/minecraft
And add yourself to the new minecraft group for administrative access:
sudo usermod -aG minecraft your_username
newgrp minecraft # reload your group membership
Download Server JAR (1.21.9)
sudo -u minecraft curl -o /opt/minecraft/server.jar https://piston-data.mojang.com/v1/objects/11e54c2081420a4d49db3007e66c80a22579ff2a/server.jar
Note: Get latest URL from https://www.minecraft.net/en-us/download/server. Requires JavaScript.
Starting the Server
Start the server once to generate necessary files.
sudo -u minecraft java -Xmx1G -Xms1G -jar /opt/minecraft/server.jar nogui
Expect to see a lot of console output, then a message about accepting the EULA to continue.
Note: This step will create a valid server.properties to start from in case you don't have one already.
Initial Server Configuration
Accept EULA:
sudo -u minecraft echo 'eula=true' | sudo -u minecraft tee /opt/minecraft/eula.txt
Loading an Existing World
Copy your existing world to /opt/minecraft/world-name. Make sure "world-name" matches the value specified in server.properties, under the key level-name. Spaces are allowed. Do not quote the value.
Example: level-name=<world-name>
It doesn't matter if the world came from a PC or another server, the server will convert it and move the folders as necessary.
Set the correct permissions if needed:
sudo chown -R minecraft:minecraft "/opt/minecraft/world-name"
Configure /opt/minecraft/server.properties to set the seed, world name, etc. and any other config (e.g. ops.json), then continue on.
Automation with systemd
Create systemd Service
Create/edit the service file:
sudo vi /etc/systemd/system/minecraft.service
Paste:
[Unit]
Description=Minecraft Server
After=network.target
[Service]
Type=simple
User=minecraft
Group=minecraft
WorkingDirectory=/opt/minecraft
# Adjust memory settings as needed
ExecStart=/usr/bin/java -Xms4G -Xmx4G \
-XX:+UseG1GC -XX:+ParallelRefProcEnabled \
-XX:MaxGCPauseMillis=200 \
-XX:+UnlockExperimentalVMOptions \
-XX:+DisableExplicitGC -XX:+AlwaysPreTouch \
-XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 \
-XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 \
-XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 \
-XX:InitiatingHeapOccupancyPercent=15 \
-XX:G1MixedGCLiveThresholdPercent=90 \
-XX:G1RSetUpdatingPauseTimePercent=5 \
-XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem \
-XX:MaxTenuringThreshold=1 \
-jar server.jar nogui
ExecStop=/usr/bin/screen -p 0 -S minecraft -X eval 'stuff "stop"\015'
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
# Security hardening
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
ProtectHome=true
[Install]
WantedBy=multi-user.target
Enable and Start Service
# Reload systemd
sudo systemctl daemon-reload
# Enable auto-start at boot
sudo systemctl enable minecraft
Maintain the Service
# Check status
sudo systemctl status minecraft
# Start the server
sudo systemctl start minecraft
# Stop server
sudo systemctl stop minecraft
# Restart server
sudo systemctl restart minecraft
View Logs
# View logs
sudo journalctl -u minecraft -f
# View last 100 lines of logs
sudo journalctl -u minecraft -n 100
# Or directly
sudo -u minecraft tail -f /opt/minecraft/logs/latest.log
Clone VM
If you clone a CentOS VM as a template, skip the world copying and configuration steps, then be sure to configure the new MAC/hostname and regenerate after booting the clone:
# Regenerate machine-id
sudo rm -f /etc/machine-id /var/lib/dbus/machine-id && sudo systemd-machine-id-setup
# Regenerate SSH keys
sudo rm /etc/ssh/ssh_host_* && sudo ssh-keygen -A
Copy your existing world files over:
WORLDNAME=logs
tar cvf - "${WORLDNAME}/" | ssh cosmic@mc1.local "cd /opt/minecraft/import && tar xf -"
Permissions reset
Use the following to force the whole /opts/minecraft directory to a known permission state:
# Navigate to the directory
cd /opt/minecraft
# Set directory ownership (if needed)
sudo chown -R minecraft:minecraft .
# Directories: 755 (minecraft can write, others can read/traverse)
sudo find . -type d -exec chmod 755 {} \;
# All files: 644 by default (minecraft can write, others can read)
sudo find . -type f -exec chmod 644 {} \;
# Executable JAR: 655 (does NOT need execute permission, Java executes the JAR)
sudo chmod 655 server.jar
# Config files that server modifies: 664 (group can write too)
sudo chmod 664 banned-ips.json banned-players.json ops.json server.properties usercache.json whitelist.json
# World directory: 755 for directory, 644 for files (server writes here)
sudo chmod 755 my-mc-server
sudo find my-mc-server -type d -exec chmod 755 {} \;
sudo find my-mc-server -type f -exec chmod 644 {} \;
# Logs directory: 755, files 644
sudo chmod 755 logs
sudo chmod 644 logs/*