A Guide To Selfhosting A Minecraft Server
My nephew wanted to host a Minecraft server for him and his friend. He asked me for some help since I have hosted a lot of game servers myself.
So I wrote a short guide on how I set up my minecraft servers and how I would recommend him to do so himself.
Preparations
SSH Keys
If you don’t already have a SSH key pair, you should generate one. You should put your public key on your server and use your private key to connect to the server. The private key should, as the name suggests, stay private. You should never post this key online, upload it in a git repo, etc.
To generate the keypair you should run these commands:
ssh-keygen
# Keep everything default
# this generates 2 files
# - <keyname> --> This is your private key
# - <keyname>.pub --> This is your public key
On linux, put the public key file in /home/<username>/.ssh/authorized_keys. (This may be different for different flavors of linux)
Playit.gg account
If you do not want to port forward on your home router, you can use a proxy service like playit.gg. So I you plan on not port forwarding, you should make an account.
Linux
I have found some linux cheatsheets to help with the linux experience. If needed, you can checkout any of these for help.
- geeksforgeeks - linux commands cheat sheet
- https://linux-commands.labex.io/
- https://cheatography.com/davechild/cheat-sheets/linux-command-line/
To start you should run the update and upgrade commands and make a minecraft folder:
# Update and upgrade the server
sudo apt update
sudo apt upgrade
# Make a minecraft folder in the home folder and move into it
mkdir minecraft
cd minecraft
Minecraft server hosting
You can host the server native or in a Docker container. I prefer the native one, because I find it easier, but the docker containers certainly are also a good option.
Native hosting
Java
Install Java JDK (Ubuntu Forum)
# Search the package you want to install
sudo apt search openjdk
# ... # openjdk-21-jdk-headless/noble-updates,noble-security 21.0.9+10-1~24.04 amd64 # OpenJDK Development Kit (JDK) (headless) # ...
# Download the package
sudo apt install openjdk-21-jdk-headless
Minecraft server
The vanilla minecraft server that Mojang provides will work, but isn’t as optimized as some other minecraft servers. If you want to install plugins the vanilla server isn’t what you are looking for.
I prefer the PaperMC server as it is more optimized and supports bukkit plugins. Go to the downloads page and copy the download link. Use this link to wget the server software to the server using this command:
# Make sure to use the -O <filename> to change the filename of the download file to whatever you want it to be
wget -O paper-1-21-11.jar 'https://fill-data.papermc.io/v1/objects/cf374f2af9d71dfcc75343f37b722a7abcb091c574131b95e3b13c6fc2cb8fae/paper-1.21.11-69.jar'
Accept the EULA, otherwise the server won’t start.
echo "eula=true" > eula.txt
Start the server with some parameters:
# - Xmx4G -> Max memory used by the server process
# - Xms1G -> memory used by the server process
# - jar <server-file-naam> -> use the filename you entered when you wget the serverfile
# - nogui -> no graphical user interface, only command line
java -Xmx4G -Xms1G -jar minecraft-server-1-21-11.jar nogui
Now your server is started.
Screen
If you are connected to your server with SSH and start the server in your terminal session you will find that whenever you logout or lose connection to your server, the minecraft server process is stopped. We obviously don’t want this, we want the minecraft server to be online 24/7.
There are a few different ways to accomplish this, but I prefer screen. Screen is a connmand line utility, a terminal multiplexer. This allows you to have multiple virtual terminal sessions running, even though you log out of your current SSH session, these will stay active.
# Start a screen session with the name minecraft
screen -S minecraft
# After this you'll just see a normal terminal. You might have to change the directory to your minecraft folder
# To detacht from the screen session press: Ctrl-A, Ctrl-D
# You'll be put back in your normal SSH session
# To list all active screen session run:
screen -ls
# To re-attacht to a screen session run:
screen -r minecraft
# Extra info about the screen command
screen --help
Hosting with docker
To host your minecraft server with Docker, you first should make sure you have Docker installed. To keep it simple for myself, I will not be explaining how to install Docker, this is explained very well on their website: Docker docs
For the docker image I like to use itzg/minecraft-server. Their documentation is quite good so for environment variables and parameters, you should go to their website.
I would recommend using a docker compose file instead of just running a docker run command so you always start your server with the exact same parameters. You can use this generator to generate your docker compose file for your minecraft server.
Here is an example of a compose file I generated with the generator:
# Generated by setupmc.com on 2026-07-16T07:50:44.637Z
services:
mc:
image: itzg/minecraft-server:latest
tty: true
stdin_open: true
ports:
- "25565:25565"
environment:
EULA: "TRUE"
MEMORY: "2048M"
MOTD: "A Minecraft server for Podepod"
USE_AIKAR_FLAGS: "true"
TZ: "Europe/Brussels"
DIFFICULTY: "3"
SIMULATION_DISTANCE: "16"
VIEW_DISTANCE: "16"
SEED: "Podepod"
SPAWN_PROTECTION: "0"
OPS: |-
Podepod
ENABLE_WHITELIST: "true"
WHITELIST: |-
Podepod
Podepod1
Podepod2
PAUSE_WHEN_EMPTY_SECONDS: "0"
SERVER_NAME: "Podepod"
SNOOPER_ENABLED: "false"
volumes:
- "./data:/data"
After saving that file in your minecraft folder as docker-compose.yml you should just be able to run this command:
# Start the docker container. After this you can use Ctrl-D to detach
docker compose up
# Start the docker container detached
docker compose up -d
Making the server public
A public Minecraft server means the whole internet has access to the server. Even though you might go through a proxy tunnel or only opened the one port on your firewall with port forwarding, you should consider the risk of this.
Make sure the online-mode and whitelist are enabled to avoid griefing:
- If you turn off
online-modeeverybody can join with a selected username, even without a mojang/microsoft account. So if my username isPodepodand I am a admin on the server, another person could join the server under the same username. This will kick me off the server and the other person is now admin on my minecraft server untill I log back in which will kick them again. When in offline mode, the whitelist is also useless if everybody can see who is online. They can just join as that username. See https://madelinemiller.dev/blog/minecraft-offline-mode/ - If you disable the whitelist, the server does not check the usernames of the players that join your server.
There are two ways to make your server public:
Port forwarding
Port forwarding opens a port on your networks firewall and points it to the networkport of a device on your internal network. For this, you should have access your networks firewall.
Proxy / tunneling
Sign in to your PlayIt.gg account and go to Setup > New Account Wizard. Follow these steps and your copy the url they give you. You can now use this URL to connect to your minecraft server from anywhere with an internet connection.
DNS
If you own a domain name, you can set up DNS for your minecraft server aswel. For this you need an A record to point to the public IP of your minecraft server (if you don’t use a proxy. When using a proxy, use a CNAME record to point to your proxy endpoint instead of the A record) and a SRV record for the minecraft service. The SRV record should look like this:
| Name | _minecraft._tcp.minecraft.podepod.be |
|---|---|
| Type | SRV |
| Priority | 0 |
| Weight | 5 |
| Port | 25565 |
| Target | minecraft.podepod.be |
| The SRV record name is made up of a few parts: |
| Service | _minecraft |
|---|---|
| Protocol | _tcp |
| Name | minecraft.podepod.be |
After this you should be able to join the server by entering the domainname: minecraft.podepod.be
A few other good guides for this:
- https://setupmc.com/guides/minecraft-domain-without-port-srv-record/
- https://minecraft.wiki/w/Tutorial:Setting_up_a_Java_Edition_server#Domain_name
Customize the server
To change stuff like the name of the server, the Message Of The Day for your server or the server icon, … you will need to change the server settings in the server.properties file in your minecraft folder.
Here is an example of this file I used for one of my servers:
#Minecraft server properties
#Fri Dec 05 19:35:55 UTC 2025
accepts-transfers=false
allow-flight=false
broadcast-console-to-ops=true
broadcast-rcon-to-ops=true
bug-report-link=
debug=false
difficulty=hard
enable-code-of-conduct=false
enable-jmx-monitoring=false
enable-query=false
enable-rcon=false
enable-status=true
enforce-secure-profile=true
enforce-whitelist=true
entity-broadcast-range-percentage=100
force-gamemode=false
function-permission-level=2
gamemode=survival
generate-structures=true
generator-settings={}
hardcore=false
hide-online-players=false
initial-disabled-packs=
initial-enabled-packs=vanilla
level-name=world
level-seed=Podepod
level-type=minecraft\:normal
log-ips=true
management-server-enabled=false
management-server-host=localhost
management-server-port=0
management-server-secret=-/-
management-server-tls-enabled=true
management-server-tls-keystore=
management-server-tls-keystore-password=
max-chained-neighbor-updates=1000000
max-players=20
max-tick-time=60000
max-world-size=29999984
motd=Podepod Minecraft Server
network-compression-threshold=256
online-mode=true
op-permission-level=4
pause-when-empty-seconds=60
player-idle-timeout=0
prevent-proxy-connections=false
query.port=25565
rate-limit=0
rcon.password=
rcon.port=25575
region-file-compression=deflate
require-resource-pack=false
resource-pack=
resource-pack-id=
resource-pack-prompt=
resource-pack-sha1=
server-ip=
server-port=25565
simulation-distance=12
spawn-protection=0
status-heartbeat-interval=0
sync-chunk-writes=true
text-filtering-config=
text-filtering-version=0
use-native-transport=true
view-distance=16
white-list=true
Other customization can also be done through plugins or mods, but I won’t go into that here.
Start and backup script
To start and backup my server I have two scripts. I do not run the backup automatically, but this could be done with a cronjob.
Start script
The start script is as simple as running the command itself. But I find it easier to run a script than to have to go through my terminal history to find which parameters I used.
File location: /home/<username>/minecraft/start.sh
#!/bin/bash
# └─> Bash Shebang
echo "Starting Minecraft Server"
java -Xmx4G -Xms2G -jar minecraft-server-1-21-11.jar nogui
Backup script
To run the backup, you should always stop the minecraft server, take the backup and restart the minecraft server. If you don’t do this, your backup might have wrong data and result in a server that won’t start.
File location: /home/<username>/minecraft/backup.sh
#!/bin/bash
# └─> Bash Shebang
echo "Starting Backup"
# Define the source and backup folders
source_dir="`/home/<username>/minecraft"
backup_dir="`/home/<username>/minecraft-backups"
# Define the backup file name (it includes the date and time to avoid duplicates)
timestamp=$(date +%Y-%m-%d-%H-%M-%S)
backup_file="backup_minecraft_$timestamp.tar.gz"
# Make the backup
tar -czf "$backup_dir/$backup_file" "$source_dir"
echo "Backup complete, removing old backup(s)"
# Remove backups older then 7 days
find "$backup_dir/*" -type f -mtime +7 -delete
echo "Done."
Running the scripts
Because of the bash shebangs, you should be able to run the scripts by just running the filenames as commands:
# in the minecraft folder
./start.sh
# or
./backup.sh
If you get an error saying command not found, it means that you do not (yet) have the rights to execute the scripts. You can check this with ls. And look for the x at the front. In the output here, the backup file does have execute permissions, the start file does not.
-rwxr-xr-x 1 podepod podepod 144 Nov 17 12:13 backup.sh*
-rw-r--r-- 1 podepod podepod 228 Nov 3 10:56 start.sh
To change the file permissions we use chmod:
# Add the execute permission for the user
chmod u+x start.sh
ls
# output:
# -rwxr-xr-x 1 podepod podepod 144 Nov 17 12:13 backup.sh*
# -rwxr-xr-x 1 podepod podepod 228 Nov 3 10:56 start.sh*
Some interesting links vaguely related to this:
- https://devhints.io/bash - Very interesting website, not only the bash section. Check out there other cheatsheets!
- https://quickref.me/bash.html
- https://github.com/RehanSaeed/Bash-Cheat-Sheet - Cheat sheet for linux commands
Server optimization
Whenever you are running your minecraft server on a host server with less resources, you should try to optimize the minecraft server. Some stuff to keep in mind:
- Changing the Render- / viewing distance and / or simulation distance - This way the server has to load less chunks for each player
- Using Paper MC (or other optimized) server jar - These versions of minecraft servers are more optimized than the default vanilla server software. Most of them also support plugins, which makes sure you get some extra functionality but the player can keep using the vanilla client.
- Pregenerating chunks - Most of the lag on small servers is caused by new chunks being loaded. To prevent this, you can preload the chunks in your world. By doing this the world folder will get bigger then when you play on the server normally, but the server will not have to load new chunks when a player moves through them when exploring. I use the Chunky plugin for this but you can also do this manually, although this takes a lot of time.
- “anti lag” plugins in most cases cause more lag then the same server without them, especially on a small scale minecraft server like the ones you most likely host for your friends.
Also have a look at these guides / articles:
- https://github.com/YouHaveTrouble/minecraft-optimization
- https://apexminecrafthosting.com/guides/minecraft/control-panel/server-optimization/