A complete guide to making a Minecraft server on a Raspberry Pi
2023 update: this is for the Java Edition of Minecraft, but you can now run Bedrock servers like this too! See this repository — it functions much the same way as the below.
My first tutorial! How exciting. I kind of doubt that anyone will read this. Nonetheless, it would’ve been helpful to have, so here I go:
What you’ll need
- a Raspberry Pi 4 (4GB+ of RAM, probably)
- Power supply
- MicroSD card
- an Ethernet connection (preferably)
- a case, if you’d like one
- I think that’s it…?
I used a Raspberry Pi 4 with 8GB of RAM to be safe — but when running htop
I haven’t ever seen usage go above 2GB, even when I’m connected and playing on the server. I have yet to stress-test it, or even really use it, though, so it’s better to be safe and get more RAM. But I suspect that 4GB is just fine (2GB might be a little iffy, but if that’s all you have and don’t plan on hosting too many people, go for it).
Also, an Ethernet connection is almost definitely a good idea — that’s probably something you won’t want to skimp on. I don’t know, maybe if you have some super-fast connection and you’ve got awesome WiFi with no interference, that might be fine, but I’m definitely sticking with a wired connection given our paltry upload speeds (and for ping purposes, too).
As for the MicroSD card: I had no idea what I’d need, so I totally overshot and got one that’s 128GB. It’s been great, but I’ve also since realized that because of the way the Pi’s filesystem works, bootable backups will be massive (unless I’m missing something, which I probably am?). I’ve used, like, nothing of that storage, so you definitely don’t need one so huge. Even 16GB would probably be barely-utilized. I’m not sure about the necessity of fast read-and-write speeds, so I defaulted to getting a relatively fast one — for example, Micro Center’s MicroSD cards are ridiculously cheap but also (on paper, at least) very slow, so I avoided them. They could definitely work — I just have no idea.
Getting started
Ok, so first you’ll have to flash the Pi’s software. And right off the bat we have a lesson I learned: use a 64-bit OS! I was very confused as to why I couldn’t set my server to use more than 2GB of RAM without it failing, but turns out there’s a whole Wikipedia page about it. I used the beta 64-bit Raspberry Pi OS, which you can download by clicking here (download will start immediately). Also, you’ll need the Raspberry Pi Imager app: download a copy here, or if you use Homebrew, install it with brew install --cask raspberry-pi-imager
. Once the OS is downloaded, you don’t have to unzip it — just launch the RPi Imager and click “choose OS” and scroll down to select “custom OS.” Select the .zip
file, select your MicroSD card (insert it if you haven’t already), and then write the image.
When all of that is done, the application will automatically eject the MicroSD card. Just remove it and plug it back in to remount it — we’ll need to edit something. Because the Pi 4 has MicroHDMI ports, and I couldn’t find the adapter to normal HDMI, I had to figure out a different way to enable SSH footnote: for those of you who don’t know, ssh
is a way to remotely connect to another computer — it stands for “secure shell.”… turns out it’s quite simple. All you have to do is create an empty file called ssh
on the MicroSD card — to do this, launch Terminal (I’m on a Mac… sorry Windows people; I have like no idea how your stuff works…) and type cd
— that’s cd with a space after it. Then, just drag your MicroSD card’s icon from your Desktop onto the Terminal window — it’ll fill in the path. You should have something like this:
cd Volumes/path/to/your/drive
in which the /path/to/your/drive
part will obviously be different. Then hit return, and you should be in the MicroSD card’s directory. Now, the command to create the empty file called ssh
:
touch ssh
You should be all good to go now! Eject the MicroSD card, put it in the Pi, connect your Ethernet, and plug in the power supply! SSH should be automatically enabled.
Ok, but now we have to actually connect. That’s also pretty straightforward! I used Fing to find my Pi’s IP address — using the desktop app is likely easiest, since the iPhone app can no longer identify devices by MAC address as well. Find the Raspberry Pi, click on it, and get its IP address. Then, SSH into it:
ssh pi@192.168.0.x
in which x
will be replaced by your Pi’s specific number. Some routers use different numbering schemes, but I think most are 192.168
etc. The pi
refers to the username, which is by default pi.
If you’ve got the IP address right, it will ask you for a password — the default is raspberry
. Once you’re in, you’ll want to change that right away (it will tell you how onscreen). After you’ve done that, you can adjust other localisation settings by running
sudo raspi-config
Docker things
Alright, so you’re all logged in and everything now! Congrats. Time for the actual server stuff: we’ll be using the absolutely awesome docker-minecraft-server by itzg. Docker is a platform for creating containerized apps/environments/stuff, so you can do multiple things on one computer without worrying about one thing messing the other things up. Clearly I’m not super proficient with it. But here, you can read more. Anyway, we’ll need to install Docker to start. Run these two commands:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
and Docker will install! Then add yourself to the user group so you don’t have to run everything with sudo
, then restart the Pi to make that go into effect:
sudo usermod -aG docker pi
sudo reboot
You’ll have to wait a minute, then ssh
again, like before (ssh pi@[your IP]
). Next, we need to install docker-compose
, which makes it much easier to restart your server and stuff — instead of having to type in all your configuration every time you start it, docker-compose
will use a YAML file, which is so much easier to read and just generally way better. More commands (I used this guide):
sudo apt-get install -y libffi-dev libssl-dev
sudo apt-get install -y python3 python3-pip
sudo apt-get remove python-configparser
sudo pip3 -v install docker-compose
Server time
Ah, finally, time for the actual server. Ok, so to begin, let’s make a directory (folder) for our server, so we can keep everything in one place:
mkdir minecraft-server
cd minecraft-server
mkdir
is “make directory,” and cd
is “change directory.” Next, make (and edit) a file called docker-compose.yml
— that’s the one with all the configuration stuff:
nano docker-compose.yml
You’ll now be in nano
, a command-line text editor. You can copy and paste the following into nano
:
minecraft-server:
image: itzg/minecraft-server:multiarch-latest
ports:
- "25565:25565" # Probably don't change this
environment:
EULA: "TRUE" # Agrees to Mojang EULA (necessary to start server)
INIT_MEMORY: "1G" # Initial memory
MAX_MEMORY: "6G" # Set this to a little less than your RAM
DEBUG_MEMORY: "TRUE" # Shows extra memory stats in logs
OVERRIDE_SERVER_PROPERTIES: "TRUE"
MAX_TICK_TIME: "-1" # Disables the watchdog server restarter
ENABLE_AUTOPAUSE: "TRUE" # Pauses server process when no one's on
SERVER_NAME: "Raspberry Pi Server" # Self-explanatory
OPS: "player1,player2" # Administrators by username
MAX_PLAYERS: "5" # Self-explanatory
MOTD: "Message of the day (subtitle) goes here" # Set this
WHITELIST: "player1,player2,etc" # Whitelist players here
SPAWN_PROTECTION: "0" # radius in chunks around spawn to protect from non-OPs
OVERRIDE_SERVER_PROPERTIES: "true"
OVERRIDE_WHITELIST: "true"
OVERRIDE_OPS: "true"
# The above 3 set it to override old parameters upon restart
volumes:
- ./data:/data # This stores your world between restarts
tty: true
stdin_open: true
restart: always
container_name: mc # You can change this if you'd like
privileged: true
Go ahead and change the parameters to suit your own preferences/needs. When you’re all done, do control-X to exit, then follow the onscreen instructions to save (type y
then hit enter
to save as docker-compose.yml
). Now… time to start the server!
docker-compose up -d
The -d
part is for --detached
, which lets it run in the background. But to view the logs, which is probably a good idea, do
docker logs mc -f
mc
is the name we gave the Docker container, and -f
tells it to follow the logs as they keep coming. Once everything’s downloaded and up and running, you can open up Minecraft on your computer, add a new server, type in your Pi’s IP address, and you should be able to log in (as long as you’ve whitelisted yourself, if you left the whitelist enabled)! Super exciting.
Connecting over the Internet
So far, you’re able to connect over your local network. But that’s probably not why you’re making this — you’d like to play with people over the whole Internet, otherwise there isn’t much of a point to doing this over just using your computer.
There are two ways you can do this: either by using Tailscale or by opening your server to the Internet using port forwarding. It’s more secure to use Tailscale, as opening a device to the whole Internet is inherently a security risk. However, if you use Tailscale, that does mean that each person with whom you’d like to play needs to install the Tailscale app and set up its VPN. You can also open your server to the whole Internet by using port forwarding. From what I’ve read, the Minecraft servers seem secure and this shouldn’t be a huge problem, but there is a risk that an exploit is discovered in the server application.
Using Tailscale (more secure)
Create a Tailscale account and follow their guide for setting everything up. Make sure to install and set up Tailscale on both your server (Pi) and client device (whatever you’d like to play Minecraft on). Then you should be able to connect to your Minecraft server by typing the Tailscale IP address (which you can find in the admin console) into Minecraft.
Using DuckDNS + port forwarding (more open)
There are a few steps to opening the server to the internet — first, sign up for an account at DuckDNS. They’re a free dynamic IP service — so basically, unless you’re a business and you pay your ISP for a static IP address, your outward-facing IP will change from time to time, which would break the server address your friends typed in. You’d have to constantly check your public IP and tell them to type it in. DuckDNS automates that — you put a script on your Pi that runs every 5 minutes or so and tells them your IP address, and then their website points a subdomain (that you choose) to your IP. Add a subdomain with a name you like, and then follow their installation instructions back on your Pi (in the Terminal window). Make sure you select “pi” as the operating system, and you can use nano
instead of vi
— it’s a little less complicated and easier to understand. Come back here when you’re done.
Ok, you’re back? Good job. Now all we have to do is port forwarding.
Note: be very considerate when taking the following steps. You’re opening a device to the internet, which is inherently a security risk, since after configuring port forwarding, anyone on the Internet can send traffic to that device.
Log into your router’s GUI (probably 192.168.0.1), and find the section about port forwarding (for us it’s under “advanced setup”). Do what it asks for — routers are weird and all very different, but for us, that meant entering the IP address of the Pi, leaving the LAN starting port blank, selecting TCP (only) as the protocol, and setting 25565 to be the only WAN port (I also left “source IP state” as “all IP addresses”). Port 25565 is the default port for Minecraft servers. If you’d like to be able to ssh
from somewhere else, you could also open port 22, which is (you guessed it) the default SSH one. However, this is probably a bad idea for security reasons, and if you’d like to do this, I’d recommend setting up Tailscale or another VPN instead.
Joining the world
So presumably you’ve made it — congrats(!)
To join the world on your local network, you’ll need to use the Pi’s local IP address as your server address. To play elsewhere, use the DuckDNS domain. (If you have a VPN on, you can connect using the DuckDNS domain even on your local network, but just do the local IP address because it provides lower (better) ping.) Basically, just add both, and one will be disconnected depending on whether you’re at home or elsewhere. You can just give other people the DuckDNS domain, though, unless they’re at your place. Also — if you’re finicky like me and would rather use a subdomain of a domain that you own, you can just add a CNAME record that points to you.duckdns.org
(replacing you
, of course). If you have no idea what that means, don’t worry at all.
🎉 You did it!
Congratulations! (If you ran into issues, feel free to leave a comment and I’ll do my best to help.)
This is where I would say ‘happy crafting’ or something, but that’s exceedingly cringy, so nope… just congratulations.
Comments no longer work :( Unfortunately, Heroku got rid of their free tier, so this no longer works. Click here to read the disclaimer I had here before / if you'd like to know a bit about how I made it work. ¶ Once upon a time… To be specific: I didn't want to pay to host them, so I installed Commento on Heroku and set up Cloudflare to get SSL to work (Heroku charges for SSL certificates). However, while the connection between your computer and Cloudflare is secure, the connection between Cloudflare and Heroku isn't. Theoretically I think someone could sneak something into the URL, or something. Again, I'm a random person who has like 4 friends, so none of this should ever be an issue. Clicking the button below will load the external Commento script.
try loading anywaay