Minecraft + playit
Minecraft server with playit.gg tunnel
|
|
| Host |
ShineoriServer |
| Category |
Game servers |
| Status |
🟢 running |
| Exposed? |
playit.gg tunnel (no open ports, home IP hidden) |
| Server |
Paper 1.21.5, 2 GB RAM, whitelist on |
Compose file: stacks/minecraft/
Why I run it
A private server for me and my friends, on my own hardware, with no monthly hosting bill. Friends join through a playit.gg address, so my home IP is never exposed and no router ports are open.
Architecture
flowchart LR
friends([Friends' Minecraft clients]) --> playit[playit.gg relay]
playit --> agent[playit agent<br/>ShineoriServer]
agent --> mc[Minecraft server<br/>Paper · :25565]
mc --> world[(./mc-data<br/>world + configs)]
| Piece |
Job |
| Minecraft server |
itzg/minecraft-server running Paper, a faster, vanilla-compatible server |
| playit agent |
Dials out to playit.gg, which relays players' game traffic back in, the same idea as the Cloudflare Tunnel but for raw game traffic |
./mc-data |
The world and all server settings |
Security decisions
| Decision |
Why |
| playit.gg instead of port forwarding |
No open router ports, and players never see my home IP |
ONLINE_MODE: TRUE |
Only real, authenticated Minecraft accounts can join |
| Whitelist on |
Only friends I've added can join, even if someone finds the address |
| Removed an old dynamic-DNS container |
It was set up to publish my home IP in DNS. It had been failing for a long time, but I removed it and its credential anyway (audit). |
Setup notes
docker compose up -d (accepting the EULA through EULA: "TRUE")
- Set up the playit agent and create a Minecraft (Java) tunnel to port 25565
- Add friends to the whitelist:
docker exec -it shineori-mc rcon-cli whitelist add <name>
- Moved from ShiNAS to ShineoriServer so all the Minecraft pieces live on one machine with more RAM
Troubleshooting log
| Date |
Problem |
Root cause |
Fix |
| 2026-10 |
A DNS record for an old setup pointed straight at my home IP |
Leftover from when friends joined through a port forward |
Deleted it, checked against Cloudflare's authoritative nameservers, and removed the dynamic-DNS container (details) |
What I'd harden next
- [ ] Update the compose file's header comments, which still describe the old port-forward and dynamic-DNS setup
- [ ] Pin the server image instead of
:latest
- [ ] Back up
./mc-data (the world is the part that would hurt to lose)
What I learned
- Tunnels for non-web traffic: game traffic is raw TCP, so it needs a different tool than the Cloudflare Tunnel
- Layered access control: authentication (online mode) plus authorization (whitelist)
- Old setups leave traces: a DNS record and an unused container both kept pointing at my home IP until an audit caught them