Unsere Minecraft Welt gibt es nun als isometrische Karte à la Google Maps. Der Weg dahin führt über eine Open-Source Software namens Overviewer. Das ist ein Kommandozeilentool auf Basis von Python. Was hat das alles mit Docker und einem Synology NAS zu tun, fragst Du dich? Hier folgt eine erklärende Anleitung um diese Karten selber zu generieren.

Isometrische Minecraft-Karte mit Overviewer generiert
Die über Nacht mit Overviewer gerenderte Minecraft-Karte.

Overviewer läuft nicht auf dem Mac

Mein Problem ist, dass Overviewer nicht so einfach auf dem Mac läuft. Schon gar nicht, wenn man Karten mit der neusten Minecraft-Version 1.13.2 verarbeiten möchte. Die ersten Versuche, Overviewer für MacOS zu kompilieren, endeten mit einem zugemüllten MacOS-System.

Emulation durch VirtualBox

Mit wenigen Befehlen lässt sich Overviewer für 1.13.2 unter Ubuntu builden und starten. Natürlich will  ich kein Ubuntu nativ auf meinem Mac parallel zu MacOS installieren. Das würde viel zu lange dauern.

Also habe ich mir VirtualBox installiert, das ubuntu.iso Image runtergeladen, mich angemeldet, Overviewer kompiliert, usw.

In- und Output festlegen

Das System bestehend aus Ubuntu und Overviewer kann man als eine Funktion mit zwei Eingabe- und einem Ausgabewert verstehen:

  1. Lesen: Die Minecraft Map
  2. Lesen: Die Overviewer-Konfigurationsdatei „config.py“
  3. Schreiben: Das Exportverzeichnis für die isometrische Karte

Mit VirtualBox und der Ubuntu-Installation ist das schwierig umzusetzen. Besonders wenn man das System später auf einem Synology DS218+ (günstig kaufen) nachts automatisch laufen lassen möchte. Zudem zieht die die Emulation mit VirtualBox auch Leistung.

Docker ist die Lösung

Docker ist einfach. Zuerst installiert man die Docker-App für sein jeweiliges Betriebssystem. In einem Dockerfile definiert man, was gemacht werden soll. Am Beispiel von meinem Anwendungsfall mit Overviewer sah es dann so aus:

FROM ubuntu:18.04
RUN apt-get update
RUN apt-get update && apt-get install -y \
build-essential \
python-pil \
python-dev \
python-numpy \
git \
wget \
&& rm -rf /var/lib/apt/lists/*
RUN mkdir /tmp/overviewer
WORKDIR /tmp/overviewer
RUN git clone https://github.com/gmcnew/Minecraft-Overviewer.git .
RUN git checkout minecraft113
RUN python2 setup.py build
RUN wget https://launcher.mojang.com/mc/game/1.13.1/client/8de235e5ec3a7fce168056ea395d21cbdec18d7c/client.jar
RUN mkdir /tmp/world
RUN mkdir /tmp/export
RUN mkdir /tmp/config
RUN useradd -ms /bin/bash bob
USER bob
ENTRYPOINT ["/bin/bash", "-c","/tmp/overviewer/overviewer.py --config=/tmp/config/config.py"]
  1. FROM bedeutet: Starte mit einem frischen Ubuntu 18.04 Image.
  2. RUN apt-get: Die Pakete werden geladen und installiert.
  3. Der Befehl RUN mkdir und WORKDIR wird ein neues Verzeichnis erzeugt und das Arbeitsverzeichnis für die nächsten Befehle festgelegt.
  4. Die Zeilen mit RUN git clone und checkout holt sich den aktuellen Stand des minecraft113 branches von GitHub.
  5. RUN python setup.py build führt die Kompilierung aus.
  6. Nun holt RUN wget  die aktuellen Texturen von Mojang.
  7. RUN mkdir legt die Verzeichnisse an, mit denen nachher gearbeitet wird.
  8. Damit overviewer nicht rumweint, weil es zu viele Rechte hat, wechseln wir mir mit USER von root auf bob.
  9. Der ENTRYPOINT Befehl wird erst dann ausgeführt, sobald das Image gestartet wird. Das bitte nicht mit dem Build verwechseln.

Das Image wird gebaut und mit dem Tag „overviewer113“ versehen. Auf dem Weg findet man es nachher einfacher wieder.

docker build -t overviewer113 .

Die Schönheit von Containern: Geschwindigkeit

Die einzelnen Zeilen im Dockerfile werden in Containern persistiert und gecached. Das ist eine tolle Eigenschaft die sich folgendermaßen auswirkt: Beim ersten Mal dauert das erste Bauen etwa 8 Minuten. Das ist  schon ein beachtlicher Unterschied zur Lösung mit der VirtualBox.

Wenn allerdings neue Zeilen im Dockerfile hinzufüge, dann dauert der Build-Vorgang wenige Sekunden. Die bereits gebauten Zeilen werden als zustandslose Container gespeichert und können jederzeit blitzschnell abgerufen werden. Das fertige Image kann man sogar auf hub.docker.com kostenfrei hochladen.

Rohre rein und Rohre raus

Das Image kann man auf der Shell ausführen. Das sieht mit Volumes mit den Mount-Points dann so aus:

docker run \
--rm \
-v /Users/marc/Documents/mcserver/:/tmp/world/:ro \
-v /Users/marc/Documents/config/:/tmp/config/:ro \
-v /Users/marc/Documents/export/:/tmp/export/:rw \
-it marctv/minecraft-overviewer

So werden die folgenden lokalen Order auf die Ordner im Image und werden dynamisch wie ein SymLink behandelt:

  • mcserver
  • config
  • export

Was macht Docker nun also anders als eine VM?

Docker spart den Overhead der virtuellen Machine ein.
Docker spart den Overhead der virtuellen Machine ein.

Docker ist keine Virtual Machine

Mit Docker spart man sich also neben der Zeit auch die virtuelle Machine die Leistung frisst. Docker arbeitet direkt auf der Hardware und ist über den Docker Daemon davon getrennt. Hierdurch hat man die Vorteile der Performance zusammen mit der Sicherheit, einfach in Sekunden wieder alles einzureißen und neu aufzubauen.

Man spart sich den Overhead eines kompletten Betriebsystem mit Virtualisierungsebenen und gewinnt dank Containerisierung Geschwindigkeit beim Entwickeln und Bauen.

Docker auf unter dem DSM von Synology

Docker auf dem Synology NAS

Overviewer schreibt auf meinem neuen Synology DS218+ NAS (kaufen) innerhalb von 12 Stunden über Docker 24 GB (!) isometrisches Kartenmaterial auf die Platte. Dank der Intel CPU kann dort im Gegensatz zu meinem alten Synology 216j NAS Docker als Paket installieren. Dort kann man mein fertiges Docker-Image unter dieser URL runterladen: https://hub.docker.com/r/marctv/minecraft-overviewer

Konfiguration von Overviewer über die Oberfläche von DSM

Konfiguration von Overviewer über DSM

Wir konfigurieren den Overviewer-Container über die Docker Oberfläche in DSM. In der Docker App in DSM  wählt man unter „Image“ das marctv/overviewer133:latest Image aus und drückt auf „Launch“ Dort vergibt man den Container-Namen „overviewer“ und setzt die CPU Priority auf „low“. Sonst schießt man mit dem Overviewer gerne mal den Minecraft-Server auf dem NAS ab.

Wichtig ist die „Advanced Configuration“. Dort gibt man unter „Volume“ drei Verzeichnisse an:

Lokale VerzeichnisseVerzeichnis im Container
Ordner mit dem Server. Darin ist ein Verzeichnis namens „world“ das eine Datei namens level.dat enthält./tmp/server/
Hier config.py drin. Ein Beispiel liegt in GitHub/tmp/config/
Ein für Docker schreibbares Verzeichnis für den Export/tmp/export/

Die Dokumentation Overviewer findet man auf overviewer.org. Hier steht, wie man die config.py aufbaut.

Die Karte Nachts per Scheduler Task rendern

Wenn der konfigurierte Container funktioniert, dann kann man das Starten in ein Script auslagern, dass wir über den DSM Task Scheduler starten können. Hier der Inhalt meines Scriptes namens generate-mc-map.sh, dass in meinem Home-Verzeichnis /var/services/homes/marc liegt.

rsync -ahW --no-compress /volume1/mounts/mcserver/ /volume1/docker/world/
docker start overviewer -a
rsync -ahW --no-compress /volume1/docker/export/ ssh-user@marc.tv:/www/htdocs/web/mc/iso/
  1. Die erste Zeile synchronisiert das lokale Verzeichnis der MC Karte auf dem NAS mit einem Verzeichnis, in dem Docker Leserechte hat.
  2. Die zweite Zeile startet den Cocker container, den wir vorher mit den entsprechenden Verzeichnissen konfiguriert haben.
  3. Die dritte und letzte Zeile synchronisiert das Export-Verzeichnis der errechneten Minecraft Karte auf dem NAS mit einem Verzeichnis auf meinem Webserver. Mein NAS nutzt dafür die Public Key Authentication.

Der erste Durchlauf kann unter Umständen über 24 Stunden dauern. Nach dem ersten Durchlauf müssen nur noch die Unterschiede der Karte berechnet werden. Das geht dann deutlich schneller.

genPOI Beispiel

Wenn man die Marker auf der Karte generieren möchte, dann muss man die Environment Variable „overviewerParam“ auf „–genpoi“ gesetzt werden.

# sync SSD to HD
rsync -ahW --no-compress --delete --exclude '@eaDir' /volume2/SSD/mcserver/ /volume2/SSD/mcserver-static/
# run Overviewer and render map
docker start overviewer -a
docker start overviewer-genpoi -a
# sync markers to web
rsync -ahW --no-compress --stats --delete --exclude '@eaDir' /volume1/docker/export/ ssh-user@marc.tv:/www/htdocs/web/mc/iso/

Der Dunning-Kruger-Effekt

Ich beanspruche nicht, dass ich Docker vollständig verstanden habe. Deswegen habe ich meinen Ex-Ex-Ex-Arbeitskollegen und Freund Ron gefragt, ob ich völlig daneben liege. Die Antwort war: „Sieht ganz ok aus..

Trotzdem kann ich sicherlich noch einige Kleinigkeiten optimieren. Zum Beispiel sollte man Dateien von git und den Mojang-Servern lieber von außen mit COPY hinzufügen.

Beteilige dich an der Unterhaltung

48 Kommentare

  1. So, nachdem nun auch das automatische rendern mittels Task scheduler funktioniert, möchte ich mich noch einmal bei Marc für den mega Support bedanken. Nicht nur, wie viel Geduld Du mit mir hattest, sondern auch wie schnell Du mir bei meinen Problemen geholfen hast. Dafür möchte ich einfach nochmal DANKE sagen!!

  2. Hello Marc,
    I found this post to be very helpful with the setting up of Overviewer via a Docker container which is a lot more versatile than running it on a virtual machine (which you have stated quite clearly).

  3. Hallo,

    habe es heute auch mal probiert, einzurichten. Leider bekomme ich immer folgende Meldungen. Woran könnte es denn liegen?:

    This is the error that occurred:
    Traceback (most recent call last):
    File „/tmp/overviewer/overviewer.py“, line 637, in
    ret = main()
    File „/tmp/overviewer/overviewer.py“, line 155, in main
    g.genPOI.main()
    File „/tmp/overviewer/overviewer_core/aux_files/genPOI.py“, line 467, in main
    mw_parser.parse(options.config)
    File „/tmp/overviewer/overviewer_core/configParser.py“, line 75, in parse
    raise MissingConfigException(„The settings file you specified (%r) does not exist, or is not a file“ % settings_file)
    MissingConfigException: The settings file you specified (‚/tmp/config/config.py‘) does not exist, or is not a file

    Grüße

    1. Hi,

      Steht dort:

      The settings file you specified (%r) does not exist, or is not a file“ % settings_file)

      Pfad zum Settings Datei gesetzt? Nochmal Anleitung genau lesen bitte.

  4. Danke für die Info. Es war soweit alles eingerichtet.
    Ich habe den lokalen Pfad nun auf einen anderen geändert. Dann gabe es noch ein Rechte Problem, da ich beseitigen konnte.
    Nun läuft es anscheint.
    Danke vielmals.

    Grüße

  5. Hi Ihr lieben.

    Wenn ich den Observer starten will, hält er gleich wieder an.
    Im Protokoll finde ich dann:

    2019-05-26 18:35:11 E Partial traceback:
    File „/tmp/config/config.py“, line 126, in
    jsObserver = JSObserver(outputdir, 30)
    File „/tmp/overviewer/overviewer_core/observer.py“, line 265, in __init__
    self.logfile = open(os.path.join(outputdir, „progress.json“), „w+“, 0)
    IOError: [Errno 13] Permission denied: ‚/tmp/export/progress.json‘

    Ich kann doch in dem Container (tmp…) keine Schreibrechte verteilen, oder?
    Was kann ich hier tun, bzw was hab ich falsch gemacht?

    Danke,
    Gruß

    1. Nochmal die Anleitung lesen. Und bei dem mounten der Verzeichnisse genauer befolgen.

  6. Puuh, nun gut. Permissions der Ordner scheinen zu funktionieren.
    Nun bricht er trotzdem ab.

    Der Teil des „Volumes“-Tabs im Overviewer-Docker-Image sollte auch stimmen:

    mcserver/world/ -> /tmp/world/ (nur lesen)
    docker/config_test/ -> /tmp/config/ (nur lesen)
    docker/export_test/ -> /tmp/export/

    Den ersten rsync befehl habe ich erfolgreich angepasst und ausgeführt.
    Nun habe ich in /docker/ einen Ordner „world“ mitsamt Inhalt des mcserver-Ordners.

    Im Protokoll steht dann nach dem fehlgeschlagenen Start:
    „ValidationException: No level.dat file in ‚/tmp/world‘. Are you sure you have the right path?“
    (ob ich „tmp/world/“ oder „tmp/world/world/“ in der config.py stehen habe, ist egal)

    Was übersehe ich hier noch? Welchen Zusammenhang übersehe ich?
    (Ich habe die Anleitung nun dreimal hintereinander gelesen.)

    Vielen Dank für einen Ratschlag.

    1. Liegt denn die level.dat in genau dem Ordner? Denn der Overviewer findet leider nichts.

    2. Hierzu müsste ich wissen, welche Pfade denn mit /tmp/… überhaupt gemeint sind. „Mount-Ordner“ habe ich wohl noch nicht ganz kapiert. Ist das ein gemeinsam genutzter „echter“ Ordner auf der Diskstation? Oder ist /tmp/… ein Pfad innerhalb des Containers? (In den ich nicht reinkomme)

    3. In dem lokalen Ordner mcserver/world/. Hat docker denn dort Leserechte?

  7. Danke für das Bereitstellen des Containers, v. A. über den Docker-Hub! Ich habe es mit der Anleitung zwar zum Start des Containers gebracht, aber da ich eine vorhandene Config verwendet habe, ging das Generieren nicht. Hier der Tipp an andere, damit die nicht das gleiche Problem haben: Die Zeile

    texturepath = „/tmp/overviewer/client.jar“

    muss in die Config! :-)

  8. Hallo Marc,
    besten Dank für die Docker-Container und die Anleitung.
    Mit Overview habe ich noch ein kleines Permission-Problem.
    Habe alles wie beschrieben befolgt. Bekomme aber die Fehlermeldung, dass er im /tmp/export keine Schreibrechte hat.
    Habe dann manuell auf der NAS den Ordner komplett geöffnet chmod 777. Dann geht es. Overview legt dann Datei und Ordner mit der user-id:gid = 1000:1000 an. Alle anderen Dateien unter Docker gehören admin:user. Kann das jemand reproduzieren? Ich sehe bisher keinen Weg, das anderweitig zu beheben.

  9. Hey,

    erstmal großes Lob! Die Anleitung ist super. Einzig wäre noch zu erwähnen, dass man dem „System“ Lese/Schreibrechte für den Export-Pfad erteilen sollte. (So zumindest der Fall bei mir gewesen).
    Leider habe ich bei einer Ähnlichen Kartengröße wie bei dir und dem selben Prasen nach Spielerpositionen immer Meldungen wie folgende:
    „Found 0 markers in thread 10 so far at 250 chunks.“
    Das geht dann über 4-5 Stunden bis alles durchsucht wurde und dann die Kartenänderung in 20min abgeschlossen wird.
    Hast du mir dafür einen Tipp wie ich das abstellen kann? Irgendwie bin ich zu doof einen eigenen Container zu erstellen und um dann den Entrypoint zu verstellen, vllt gibt es ja aber auch eine andere bessere oder einfachere Möglichkeit.
    Vielen Danke schon mal
    Grüße Stefan

    1. 4-5 Stunden? Wow. Also da läuft was schief. Das geht bei recht schnell. Ggf. mehr Threads in der Config bereitstellen? Aber ja, das könnte ich mal als Option anbieten im Container und dann by default abstellen.

    2. Hey,
      wenn ich das ganze am PC starte hab ich das Problem und auch die Nachrichten nie. Im Log ist der „Thread 10“ auch nur ein Beispiel, das geht weit hoch in den 2-stelligen Bereich.
      Die Option „–skip-scan“ hab ich immer gern genutzt. Da ich abgesehen von dem Player alle Marker manuell setze. (Daher das Interesse an einem anderen Entrypoint)
      Außerdem wird der Docker-Container immer mit der Meldung „unerwartet beendet“ geschlossen, obwohl er komplett und sauber durchläuft. Wie schließt der bei dir?

    3. Sorry vergessen:
      der Container läuft auf CPU-Prio Mittel und bei RAM-Grenze auf Automatisch (von max. 12GB)
      …und die Zeit kommt nur von den Markern, egal ob ich manuelle POI’s oder den Player setzen lasse. (alles einzeln getestet)

    4. Er schließt ebenfalls „unsauber“. Dafür habe ich leider keine Lösung. Das war auch mal anders. ich denke das liegt an dem Overviewer.

      Ich habe den Container angepasst und die Overviewer Parameter als Environment variable optional gemacht.

  10. Hallo zusammen! Als erstes mal ein großes Lob. Ich habe den Server auf meiner DS918 mit einigen Plugins zu meiner vollsten zufriedenheit zum Laufen bekommen. Dand der sehr guten und ausführlichen Anleitung war das auch für ein älteres Semester wie mich kein großes Problem ;)
    Natürlich ist man nie zufrieden und eine schöne Map vom eigenen Server ist doch etwas tolles. Leider scheitere ich an der Stelle, wo man die Verzeichnisse des Dockers mounten muss.
    Also: Ich habe eine DS819. Die hat intern den Namen „Volume1“. In diesem Volume1 befindet sich der freigegebene Ordner „mcserver“ für die Serverdaten von Minecraft.
    Desweiteren gibt es noch einen Ordner „Docker“ der ist aber leer.
    Mich irritiert bei dem Bild „Edit-overviewer-recent“ in dieser Anleitung schonmal als erstes die obere Zeile: File/folder= docker/mcserver. Mein mcserver-Verzeichnis befindet sich aber nicht im dockerverzeichnis, sondern im Hauptverzeichnis von Volume1. Oder verstehe ich da etwas ganz falsch? (Wahrscheinlich ja) :)
    Könnte mir jemand, bei dem dasläuft bitte mal genau (wenn es geht Schritt für Schritt) erklären, was ich da anwählen muss, damit die Pfade richtig gesetzt sind?

    1. Hi,
      ich habe die Doku und den Screenshot als auch das Image erweitert. Der Pfad muss auf das Verzeichnis des Minecraft-Servers zeigen. In dem Verzeichnis muss ein Verzeichnis namens „world“ liegen, dass die Karte enthält. Egal wo es liegt. Bei mir liegt es ganz woanders weil ich ein statisches Abbild für ein vorheriges Backup in die Dropbox mache und dann daraus die Karte generiere für mc.marc.tv

Schreib einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website zeigt Benutzerbilder über gravatar.com an.

Wie bekomme ich einen verifizierten Account? - Login