# 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: ```powershell 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: ```powershell 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 ```powershell scp -i "$HOME\.ssh\oracle_mc.key" "deploy\minecraft-crossplay.tar.gz" ubuntu@130.61.230.183:~/ ``` ```powershell ssh -i "$HOME\.ssh\oracle_mc.key" ubuntu@130.61.230.183 ``` Auf dem Server: ```bash 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: ```bash 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: ```bash systemctl is-active firewalld; sudo iptables -S INPUT | head ``` **Oracle Linux (firewalld):** ```bash sudo firewall-cmd --permanent --add-port=25565/tcp --add-port=19132/udp && sudo firewall-cmd --reload ``` **Ubuntu (iptables + netfilter-persistent):** ```bash 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 ```bash 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: ```bash 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: ```bash sudo systemctl is-enabled docker ``` Konsole und Backup laufen wie lokal (siehe [README.md](README.md)): ```bash docker compose exec minecraft rcon-cli ``` ```bash 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: ```bash 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: ```bash 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: ```bash 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: ```bash 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: ```bash 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.