Technology & Life

Summary
Setting up a Minecraft server on CentOS Stream
Published
Reading time
5 min
Tags
, , ,

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.

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

Open the default Minecraft port:

sudo firewall-cmd --permanent --add-port=25565/tcp
sudo firewall-cmd --reload

To verify:

sudo firewall-cmd --list-all

Install OpenJDK 21 from the CentOS repositories:

sudo dnf install java-21-openjdk-headless

Verify installation:

java -version

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

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.

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.

Accept EULA:

sudo -u minecraft echo 'eula=true' | sudo -u minecraft tee /opt/minecraft/eula.txt

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.

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

# Reload systemd
sudo systemctl daemon-reload

# Enable auto-start at boot
sudo systemctl enable minecraft

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

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

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/*

Back to top ↑