Files
minecraft-java-bedrock/DEPLOY-ORACLE.md
T

9.0 KiB

Deployment: Oracle Cloud (Ampere A1) auf minecraft.djnizz.at

Anleitung fuer den Umzug des lokal getesteten Stacks auf die bestehende OCI-Instanz. Alles per Hand, kein Automatismus.

Ausgangslage

Ziel-Host 130.61.230.183
DNS minecraft.djnizz.at → 130.61.230.183 (A-Record bei helloly, existiert bereits)
Shape Ampere A1, ARM64
SSH-Key C:\Users\nicol\Documents\oracle free private key.ppk
Paket deploy/minecraft-crossplay.tar.gz

Geprueft: DNS loest korrekt auf, die Ports 25565/TCP und 19132/UDP sind von aussen aktuell noch dicht — erwartbar, es laeuft ja noch nichts.

ARM ist kein Problem. itzg/minecraft-server ist multiarch und bringt linux/arm64 mit; Paper, Geyser und Floodgate sind reines Java.

Caddy wird nicht gebraucht. Minecraft spricht ein eigenes Protokoll ueber rohes TCP, Bedrock zusaetzlich UDP — beides kann ein HTTP-Reverse-Proxy nicht sinnvoll weiterreichen. Die Container-Ports werden direkt veroeffentlicht. 80/443 bleiben unberuehrt, es gibt keine Kollision.

1. SSH-Key nutzbar machen

Die .ppk ist PuTTY-Format, scp/ssh von Windows koennen damit nichts anfangen. Entweder mit pscp/WinSCP arbeiten oder einmalig konvertieren:

puttygen "$HOME\Documents\oracle free private key.ppk" -O private-openssh -o "$HOME\.ssh\oracle_mc.key"

Danach Rechte einschraenken, sonst verweigert OpenSSH den Key:

icacls "$HOME\.ssh\oracle_mc.key" /inheritance:r /grant:r "$($env:USERNAME):(R)"

Der Login-User haengt am Image: Ubuntu → ubuntu, Oracle Linux → opc.

2. Paket hochladen und entpacken

scp -i "$HOME\.ssh\oracle_mc.key" "deploy\minecraft-crossplay.tar.gz" ubuntu@130.61.230.183:~/
ssh -i "$HOME\.ssh\oracle_mc.key" ubuntu@130.61.230.183

Auf dem Server:

mkdir -p ~/docker && tar xzf ~/minecraft-crossplay.tar.gz -C ~/docker/ && cd ~/docker/minecraft-crossplay && ls -la

Docker liegt durch den Caddy-Stack schon vor. Kurz gegenpruefen:

docker version --format '{{.Server.Version}}' && docker compose version

3. Ports in OCI oeffnen (der eigentliche Knackpunkt)

Das ist in der Praxis die Ursache fuer die meisten „Server nicht erreichbar"- Faelle. In der OCI-Konsole:

Networking → Virtual Cloud Networks → → Security Lists → Default Security List → Add Ingress Rules

Zwei Regeln, beide stateful (Haken bei „Stateless" NICHT setzen):

Source CIDR IP Protocol Destination Port Range
0.0.0.0/0 TCP 25565
0.0.0.0/0 UDP 19132

Haengt an der VNIC deiner Instanz eine Network Security Group, muessen die beiden Regeln dort hinein statt in die Security List — sonst greifen sie nicht.

Die UDP-Regel wird gerne vergessen. Ohne sie funktioniert Java einwandfrei und Bedrock gar nicht.

4. Firewall auf der Instanz

Von Docker veroeffentlichte Ports gehen per DNAT an der INPUT-Kette vorbei, deshalb laeuft das meist ohne Zutun. Erst testen (Schritt 6), und nur wenn es scheitert, hier nachziehen.

Welche Firewall aktiv ist:

systemctl is-active firewalld; sudo iptables -S INPUT | head

Oracle Linux (firewalld):

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

Ubuntu (iptables + netfilter-persistent):

sudo iptables -I INPUT 5 -p tcp --dport 25565 -j ACCEPT && sudo iptables -I INPUT 6 -p udp --dport 19132 -j ACCEPT && sudo netfilter-persistent save

5. Konfiguration anpassen

In ~/docker/minecraft-crossplay/.env:

  • MC_MEMORY — im Paket auf 8G gesetzt. Die Instanz hat 24 GB, davon gehen Caddy und der uebrige Kram ab; 8 GB sind fuer eine private Runde reichlich.
  • MC_OPS — dein Java-Name, sonst hast du auf dem Server keine Rechte.
  • MC_MOTD — steht auf djnizz.at - Java & Bedrock.
  • RCON_PASSWORD — im Paket bereits neu erzeugt, nicht identisch mit lokal.

6. Starten und pruefen

cd ~/docker/minecraft-crossplay && docker compose up -d && docker compose logs -f

Fertig, sobald Started Geyser on UDP port 19132 und Done (…)! For help, type "help" erscheinen. Erster Start dauert einige Minuten (Paper, Plugins, Welt).

Danach von deinem Windows-Rechner aus — das ist der ehrliche Test, weil er den kompletten Weg inklusive Security List prueft:

python "scripts/check-crossplay.py" minecraft.djnizz.at

Beide Abschnitte muessen OK melden. Kommt bei Java ein Timeout, fehlt die TCP-Regel; kommt er nur bei Bedrock, fehlt die UDP-Regel.

7. Verbinden

  • Java Edition: minecraft.djnizz.at (Port 25565 ist Standard, muss nicht mitgegeben werden)
  • Bedrock Edition: Adresse minecraft.djnizz.at, Port 19132
  • Konsolen (PS/Xbox/Switch) koennen keine freie Adresse eintragen — dort fuehrt der Weg ueber BedrockConnect oder eine DNS-Umleitung im Heimnetz.

Zum SRV-Record

Ein SRV-Record (_minecraft._tcp.minecraft.djnizz.at) lohnt nur, wenn Java auf einem anderen Port als 25565 laufen soll — dann koennen Java-Spieler die Portangabe weglassen. Bedrock wertet keine SRV-Records aus, dort muss der Port immer 19132 sein oder manuell eingetippt werden. Bei der jetzigen Konfiguration brauchst du also keinen.

8. Betrieb

Wichtig — reservierte IP: Ist die Public IP der Instanz ephemeral, aendert sie sich beim Stoppen/Starten der VM und der A-Record bei helloly zeigt ins Leere. In der OCI-Konsole unter Instance → Attached VNICs → IPv4 Addresses auf Reserved umstellen, falls noch nicht geschehen.

Autostart nach Reboot deckt restart: unless-stopped ab, solange der Docker-Dienst selbst aktiviert ist:

sudo systemctl is-enabled docker

Konsole und Backup laufen wie lokal (siehe README.md):

docker compose exec minecraft rcon-cli
docker compose exec minecraft rcon-cli save-all && docker run --rm -v mc-crossplay_mc-data:/data -v "$PWD":/backup alpine tar czf /backup/mc-backup-$(date +%F).tar.gz -C /data .

Ein Cronjob dafuer ist auf einem oeffentlich erreichbaren Server keine schlechte Idee.

9. Oeffentlicher Server: Whitelist

Sobald die Ports offen sind, findet dich jeder Scanner. Die Whitelist ist im Stack bereits verkabelt und wird ueber die .env gesteuert:

MC_WHITELIST_ENABLED=true
MC_WHITELIST=Nizz_05

MC_WHITELIST nimmt nur Java-Profilnamen - itzg loest sie beim Start ueber PlayerDB/Mojang in UUIDs auf. Ein Xbox-Gamertag scheitert an diesem Lookup und landet still nicht in der Liste. Trag hier also nie einen Bedrock-Namen ein.

Bedrock-Spieler auf die Whitelist

Erster Versuch ueber den Gamertag - Floodgate strippt einen fuehrenden Punkt selbst:

docker compose exec minecraft rcon-cli "fwhitelist add Nizz05"

Das schlaegt oft fehl, weil Floodgate den Gamertag ueber die oeffentliche GeyserMC-API in eine XUID aufloest und die nur Accounts kennt, die dort schon mal abgefragt wurden. Achtung: ueber RCON kommt in beiden Faellen keine Ausgabe zurueck - Floodgate schickt seine Antworten ueber ein eigenes Message-System, das den RCON-Aufrufer nicht erreicht. Leerer Output heisst also nicht „hat geklappt". Maszgeblich ist immer:

docker compose exec minecraft rcon-cli "whitelist list"

Der zuverlaessige Weg fuehrt ueber die Floodgate-UUID. Der Spieler verbindet sich einmal bei abgeschalteter Whitelist (whitelist off), danach steht er im User-Cache:

docker compose exec minecraft cat /data/usercache.json

Die UUID hat die Form 00000000-0000-0000-XXXX-XXXXXXXXXXXX: die oberen 64 Bit sind null (daran erkennt Floodgate seine eigenen IDs), die hinteren 16 Hex-Stellen sind die Xbox-XUID. Damit:

docker compose exec minecraft rcon-cli "fwhitelist add 00000000-0000-0000-XXXX-XXXXXXXXXXXX"

In whitelist list taucht der Eintrag danach als unknown auf, nicht unter dem Gamertag - Floodgate traegt beim Hinzufuegen per UUID fest "unknown" als Namen ein. Rein kosmetisch, geprueft wird gegen die UUID.

EXISTING_WHITELIST_FILE: MERGE in der docker-compose.yml sorgt dafuer, dass diese Eintraege einen Neustart ueberleben. Ohne das wuerde die whitelist.json bei jedem Start auf den Inhalt von MC_WHITELIST zusammengestrichen - und die Bedrock-Spieler waeren wieder draussen.

Reihenfolge beachten: erst eintragen, dann scharf schalten. Operatoren umgehen die Whitelist zwar, aber darauf sollte man sich nicht verlassen.

10. Troubleshooting

Von aussen keine Verbindung, lokal auf dem Server aber schon — dann liegt es an OCI. Auf dem Server gegenpruefen:

docker compose exec minecraft rcon-cli list

Antwortet das, laeuft der Server und es fehlt die Security-List-Regel oder die Instanz-Firewall blockt.

Bedrock timeoutet, Java geht — die UDP-Regel fehlt. Sicher der haeufigste Fall.

IP hat sich geaendert — A-Record bei helloly nachziehen und die Public IP auf reserved umstellen.

Container startet in Schleife, Log sagt „requires Java 25 or above" — das Image-Tag wurde auf eine aeltere JVM zurueckgesetzt. Es muss stable-java25 oder neuer bleiben.