Docker Entwicklungsumgebung unter Windows – Teil 2: Webserver mit Nginx

Die Grundlagen sollten wieder klar sein, machen wir uns an die Praxis. Der erste Schritt auf dem Weg zu unserer Docker Entwicklungsumgebung wird der Webserver – ohne den werden es die meisten PHP Entwickler schwer haben, ihrer Arbeit nachzugehen. Also geht es in diesem Artikel darum, einen Nginx Container mit allen Einstellungen zum Laufen zu kriegen um im Browser direkt eine Datei ansteuern zu können, die von diesem Webserver ausgeliefert wird.

Ein Docker Nginx Container

Von Nginx gibt es glücklicherweise bereits offizielle Docker Images in mehreren Varianten. Das erspart uns die Mühe, selbst umständlich in einem Image Nginx zu installieren.
Neben den verschiedenen Versionsnummern von Nginx gibt es hier vor allem zwei große Varianten:

  1. Eine Version auf Debian Jessie basierend
  2. Eine Version auf Alpine Linux basierend

Der große Unterschied zwischen den beiden ist genau das – die Größe. Alpine ist eine sehr kleine (dementsprechend aber auch nicht sehr umfangreiche) Linux Distribution. Möchten wir also die Größe unserer Docker Images gering halten um Platz zu sparen ist das eine gute Möglichkeit. Gibt es dann Probleme weil wir spezielle Software nutzen können wir immer noch auf die Jessie Variante wechseln.
Um das Alpine Image auszuwählen stellen uns die Entwickler Tags zur Verfügung, die mit -alpine enden.

 

Einen ersten simplen Webserver starten

Genug mit der Theorie, kommen wir zur Praxis. Zum Starten eines Nginx Servers benötigen wir nur einen einzigen Befehl:

Das sieht jetzt natürlich etwas kryptisch aus, daher brechen wir den Befehl mal schön in seine einzelnen Teile auf.

  • docker run – sagt einfach nur, dass wir gerne einen Container ausführen möchten, der auf einem Image basiert
  • -v /$(pwd):’/usr/share/nginx/html‘ – die -v Flag (für Volume) legt ein Volumen an, teilt also den Inhalt eines Ordners auf unserer Festplatte (der erste Teil des Parameters vor dem Doppelpunkt) mit einem Ordner innerhalb des Containers (der Pfad nach dem Container)
    • /$(pwd) – benutzt das Verzeichnis, in dem wir uns aktuell befinden dafür. $(pwd) ist einfach ein Konsolenbefehl zur Ausgabe des aktuellen Verzeichnisses. In Git Bash brauchen wir unter Windows außerdem den zusätzlichen Slash davor, damit es die Verzeichnisstruktur ordentlich übergibt.
    • ‚/usr/share/nginx/html‘ – dies ist der Standardpfad in einem Docker Image, aus dem Docker Dateien bereitstellt. Die einfachen Anführungszeichen sind wichtig, da Docker unter Windows ansonsten auch hier den Pfad automatisch verändert um in das Homeverzeichnis unseres Users zu zeigen.
  • -d – lässt den Container im detached mode laufen, das heißt er läuft im Hintergrund einfach weiter (um laufende Container zu sehen können wir den docker ps Befehl verwenden). Wird diese Flag ausgelassen würde der Container zwar starten, allerdings nach erfolgreichem Start sofort beendet werden.
  • -p 80:80 – leitet den Port 80 unseres Computers (also der Port, auf den unser Browser standardmäßig zugreift) auf den Port 80 innerhalb des Containers weiter (also den Port, auf den Nginx standardmäßig hört). Das stellt einfach sicher, dass wir von unserem Computer auch zum Beispiel mit Chrome auf den Container zugreifen können.
  • nginx:latest – Das ist nun der Name des Images, das wir mit dem docker run Befehl starten wollen. nginx ist hier der Name und latest das Tag. Die Alpine Version könnten wir beispielsweise mit nginx:alpine starten. Probier es ruhig mal aus!

 

 

Mit docker ps können wir uns überzeugen, dass unser Container läuft und die Ports auch richtig weitergeleitet wurden. Rufen wir nun in unserem Browser die URL http://localhost auf sollten wir einen 403 Forbidden Fehler sehen.
Zuerst mal – warum localhost? Wir erinnern uns, dass wir den Port 80 auf unserem Rechner in den Container geleitet haben. Ohne eine Portangabe versucht ein Browser bei einem http:// Request automatisch den Port 80, das heißt wir versuchen auf den Port 80 unseres Computers (localhost) zuzugreifen. Docker erkennt das und leitet diese Anfrage automatisch in den Container auf den Port 80 dort weiter.
Nginx nimmt diese Anfrage entgegen (da er standardmäßig auf diesen Port hört) und verarbeitet diese.

Da wir nun aber leider (vermutlich) keine verwertbaren Dateien in unserem Verzeichnis haben, meckert Nginx, dass der Direktzugriff auf einen Ordner nicht erlaubt ist.
Hier können wir ganz leicht Abhilfe schaffen indem wir eine HTML Datei namens index.htm mit dem Wort Test anlegen und in dem Verzeichnis abspeichern, dass wir mit dem -v Flag geteilt haben.
Et voila – nach einem Refresh im Browser sollten wir nun unser Test im Browser angezeigt bekommen. Und schon haben wir einen funktionierenden Webserver.

 

 

Docker Einstellungen in ein Dockerfile auslagern

Nun läuft unser Webserver zwar, sich den dafür benötigten Befehl zu merken ist aber gar nicht so einfach. Außerdem wäre es relativ kompliziert, damit in einem Team zu arbeiten und den Code an jemand anderen weiterzugeben. „Hey Toni, um das Projekt zu starten führe erstmal folgenden Befehl aus. Dann loggst du dich in den Container ein und installierst zwölf Abhängigkeiten, loggst dich aus und schon kanns losgehn!“.

Das lässt sich mit einem Dockerfile besser machen. Wir erinnern uns – ein Dockerfile ist eine Art Scriptdatei, die aussagt, wie ein Image während des Startens eines Containers verändert werden soll. Für unseren einfachen Webservercontainer müssen wir noch gar nicht viel verändern (höchstens das Volume und die Ports), doch das wird sich im nächsten Abschnitt noch ändern. Schließlich soll unser Nginx auch konfigurierbar werden, andernfalls wird es schwer, PHP zu aktivieren.

Legen wir nun also in unserem Verzeichnis eine Datei namens Dockerfile mit folgendem Inhalt an:

Auch dieses kryptische etwas brechen wir natürlich in seine Bestandteile auf.

  • FROM nginx:latest – der FROM Befehl legt fest, auf welchem Image unser neues Image basieren soll – in diesem Fall genau wie vorher einfach das Nginx Image
  • MAINTAINER Frank Tiersch „mail@ftiersch.de“ – der MAINTAINER ist die Person, die sich um dieses Image kümmert
  • CMD [„nginx“, „-g“, „daemon off;“] – CMD ist einfach der Befehl (Command), der standardmäßig beim Ausführen eines Containers mit diesem Image gestartet werden soll. Hier starten wir Nginx mit einer kleinen Besonderheit, und zwar setzen wir den Einstellungswert daemon auf off. Das hat einfach den Hintergrund, dass andernfalls Nginx im Hintergrund läuft. Ohne einen Vordergrundtask beendet sich ein Docker Container allerdings nach dem Starten sofort wieder und unser Server läuft nicht weiter.

 

 

Nun können wir aus diesem Dockerfile jederzeit ein eigenes Image erzeugen. Dafür führen wir einfach einmal folgenden Befehl aus:

  • docker build – sorgt dafür, dass ein Image aus einem Dockerfile erzeugt wird
  • -t ftiersch/nginx – ist ein Name innerhalb eines Namespaces, den wir dem Dockerfile geben können, um es später einfacher wiederzufinden. Hier können wir auch einen Tag vergeben, z.B. ftiersch/nginx:0.1.0 um später weitere Versionen eindeutig zu unterscheiden
  • . – Der Punkt ist wichtig, denn er teilt Docker mit wo er das Dockerfile findet – in diesem Fall einfach im aktuellen Verzeichnis

Und schon können wir den selben Container wie vorher mit folgendem Befehl starten:

Laden wir unsere Seite im Browser neu sollten wir sehen, dass sich nichts verändert hat.

Warum dann der Aufwand? Nun, dazu kommen wir im nächsten Abschnitt, den nun verpassen wir unserem Docker Nginx noch eine eigene Konfiguration!

 

Docker Nginx Konfiguration verändern

Um unsere Nginx Konfiguration zu verändern haben wir eine ganz einfache Möglichkeit: Wir speichern die Konfigurationsdatei im selben Verzeichnis ab und kopieren diese beim Erzeugen des Images einfach in den Container an dieselbe Stelle wo die normale Nginx Konfiguration liegt.

Legen wir also nun eine Datei mit dem Namen default.conf an und befüllen sie mit folgendem Inhalt:

Das ist eine ganz normale Standardkonfiguration für Nginx, starten wir diesen Server ändert sich also quasi nichts zu vorher.

Nun öffnen wir unser Dockerfile und passen es ein klein wenig an:

Der ADD Befehl nimmt einfach eine Datei von unserem Computer und fügt sie in den Container ein. Eine bisher vorhandene Datei wird dabei einfach überschrieben. Dies geschieht noch bevor der nginx Befehl ausgeführt wird, dadurch ist die Konfiguration direkt live.

Wir erzeugen also nun unser Image erneut mit dem docker build Befehl von oben und können den Container wieder mit demselben docker run Befehl wie zuvor starten. Ein Refresh des Browsers zeigt keine Veränderung wodurch wir wissen, dass alles immer noch funktioniert – mit dem wichtigen Unterschied, dass wir nun die Nginx Konfiguration bearbeiten können. Das wird im nächsten Artikel der Serie wichtig, wo wir uns um PHP kümmern.

 

Downloads

Wie versprochen, hier noch der Download für die hier verwendeten Datein: nginx.zip herunterladen

3 Kommentare zu “Docker Entwicklungsumgebung unter Windows – Teil 2: Webserver mit Nginx

  1. Hallo Frank,

    danke für dein Tutorial. Ich hab’s mal ausprobiert und komme spontan nicht über folgende Fehlermeldung hinweg:

    C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error response from daemon: Mount denied:
    The source path „/C:\\tmp\\nginx“
    is not a valid Windows path.
    See ‚C:\Program Files\Docker\Docker\Resources\bin\docker.exe run –help‘.

    Hast du Rat? 🙂

    Danke & VG

    • Hi Gunnar,

      das Problem mit dem $(pwd) hab ich leider in letzter Zeit auch, dass er das nicht mehr so akzeptiert. Da musst du wohl jetzt einfach doch den ganzen Pfad angeben. Also beispielsweise:

      -v //d/Projekt/code:’/usr/share/nginx/html‘

      Das sollte zumindest den Fehler mal lösen 🙂 Muss mal recherchieren, warum das nicht mehr geht.

      Viele Grüße
      Frank

      • Hallo Frank ,

        das $(pwd) muss unter der PowerShell ${pwd} heißen und benötigt keinen vorangestellten ‚/‘ wie man in der Fehlerausgabe schön sehen kann.

Schreibe einen Kommentar

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

*