Intermediate 30 min — Run a high-performance Paper Minecraft server in a lightweight Proxmox container with Aikar's JVM flags.
From the Proxmox shell (or SSH into your host), create a new container. Adjust the storage and ID as needed:
pct create 210 local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst \
--hostname minecraft \
--cores 2 \
--memory 4096 \
--swap 1024 \
--rootfs local-lvm:20 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--unprivileged 1 \
--start 1
This creates a container with 2 CPU cores, 4GB RAM, and 20GB disk. Minecraft benefits from multiple cores (GC runs on separate threads), and 4GB gives the JVM enough heap for a smooth experience with 10-20 players.
Enter the container and install Eclipse Temurin 21 from the Adoptium apt repository:
pct enter 210
apt update && apt upgrade -y
apt install -y wget apt-transport-https gpg
Add the Adoptium GPG key and repository:
wget -qO - https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor -o /etc/apt/keyrings/adoptium.gpg
echo "deb [signed-by=/etc/apt/keyrings/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main" | tee /etc/apt/sources.list.d/adoptium.list
apt update
apt install -y temurin-21-jdk
Verify the installation:
java -version
# Expected: openjdk version "21.x.x" ... Temurin
Paper is a high-performance fork of Spigot that includes significant optimizations and bug fixes. Download the latest Paper 1.21.4 build using the PaperMC API:
mkdir -p /opt/minecraft && cd /opt/minecraft
# Get the latest build number for 1.21.4
PAPER_BUILD=$(wget -qO - https://api.papermc.io/v2/projects/paper/versions/1.21.4/builds | \
grep -o '"build":[0-9]*' | tail -1 | cut -d: -f2)
# Download the jar
wget -O paper.jar \
"https://api.papermc.io/v2/projects/paper/versions/1.21.4/builds/${PAPER_BUILD}/downloads/paper-1.21.4-${PAPER_BUILD}.jar"
echo "Downloaded Paper 1.21.4 build ${PAPER_BUILD}"
Run the server once to generate the configuration files:
cd /opt/minecraft
java -jar paper.jar --nogui
The server will stop immediately and ask you to accept the Minecraft EULA. Open the generated eula.txt and set it to true:
sed -i 's/eula=false/eula=true/' /opt/minecraft/eula.txt
By changing this to true, you agree to the Minecraft End User License Agreement.
The first run generated server.properties. Edit it with the key settings:
cat > /opt/minecraft/server.properties << 'EOF'
# Minecraft Server Properties
server-port=25565
max-players=20
motd=A Paper Minecraft Server
view-distance=10
simulation-distance=8
online-mode=true
difficulty=normal
gamemode=survival
level-name=world
spawn-protection=0
max-tick-time=60000
enable-command-block=true
enforce-whitelist=false
white-list=false
EOF
Key settings:
view-distance=10 — number of chunks sent to the client. Lower values reduce RAM and CPU usagesimulation-distance=8 — how far from the player entities and redstone are ticked. Keep this at or below view-distanceonline-mode=true — verifies player accounts with Mojang. Set to false only if running behind a proxy like Velocitymax-players — adjust based on your RAM. With 4GB heap, 20 players is comfortableAikar's flags are the community-standard JVM tuning for Minecraft servers. They optimize the G1 garbage collector to reduce lag spikes:
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 \
-Dusing.aikars.flags=https://mcflags.emc.gs \
-Daikars.new.flags=true \
-jar paper.jar --nogui
Important: -Xms and -Xmx should be the same value. This pre-allocates the full heap and avoids resize pauses. With a 4GB container, use -Xms4G -Xmx4G (leave ~512MB for the OS if your container has 4.5GB+, but 4G/4G works in a 4GB container since the OS overhead in LXC is minimal).
Create a systemd unit so the server starts on boot and restarts on crash:
cat > /etc/systemd/system/minecraft.service << 'EOF'
[Unit]
Description=Paper Minecraft Server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/minecraft
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 \
-Dusing.aikars.flags=https://mcflags.emc.gs \
-Daikars.new.flags=true \
-jar paper.jar --nogui
ExecStop=/bin/kill -SIGINT $MAINPID
Restart=on-failure
RestartSec=10
StandardInput=null
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable minecraft
systemctl start minecraft
systemctl status minecraft
Watch the logs to confirm the server starts successfully:
journalctl -u minecraft -f
You should see output like Done (12.345s)! For help, type "help" once the server is ready. Open Minecraft Java Edition 1.21.4, go to Multiplayer > Add Server, and enter your container's IP address. The default port is 25565 so you don't need to specify it.
If you're using Proxmox's built-in firewall or ufw, allow port 25565:
# On the Proxmox host (if using host firewall)
iptables -A INPUT -p tcp --dport 25565 -j ACCEPT
# Or if using ufw inside the container
ufw allow 25565/tcp
If your server is behind a NAT router, forward port 25565 TCP to the container's IP address.
Your world files live in /opt/minecraft/world/ (with world_nether/ and world_the_end/ for other dimensions). Back these up regularly. A simple cron job:
mkdir -p /opt/minecraft/backups
crontab -e
# Add this line to back up every 6 hours:
0 */6 * * * tar czf /opt/minecraft/backups/world-$(date +\%Y\%m\%d-\%H\%M).tar.gz /opt/minecraft/world/ /opt/minecraft/world_nether/ /opt/minecraft/world_the_end/
Consider stopping the server briefly before backup to avoid corrupted chunks, or use Paper's built-in save-off/save-all commands via RCON.
Desert Forge Backup handles world file backups automatically with AES-256 encryption and zero egress fees.
Set up Backupjava -version to verify. If you see Java 17 or lower, make sure Temurin 21 is installed and check update-alternatives --config java to select the correct version.You need to agree to the EULA. Verify /opt/minecraft/eula.txt contains eula=true (no spaces around the equals sign).ping 8.8.8.8), and confirm the server is listening (ss -tlnp | grep 25565). Make sure your Minecraft client version matches the server version (1.21.4)./tps in-game or from console. If TPS is below 20, lower view-distance and simulation-distance in server.properties. Check /timings for detailed performance reports. Paper also has tuning options in config/paper-global.yml and config/paper-world-defaults.yml.pct set 210 --memory 6144) and update -Xms/-Xmx in the systemd unit.journalctl -u minecraft -e for errors. Plugin incompatibility is common after version upgrades. Remove plugins from /opt/minecraft/plugins/ one at a time to isolate the issue.Desert Forge Game Hosting gives you a Minecraft server with one click — from $2/week, no Linux required.
Get a server