Diskussion Docker und Laravel

Werner S

Mitglied
Guten Abend,

ich brauche von meinem aktuellen Projekt mal etwas Pause und wollte mich mal mit Docker beschäftigen.

Ich nutze aktuell Windows 11 mit Docker Desktop
Über den Windows Store habe ich Ubuntu drauf und WSL2 läuft auch Problemlos.

Ich habe zum Testen WordPress mit Docker installiert, soweit klappt auch alles.

Ich habe mir jetzt mal folgendes Tut angeschaut https://www.digitalocean.com/commun...aravel-with-docker-compose-on-ubuntu-20-04-de
Das klappt auch soweit, Container laufen. Was ich mich jetzt nur Frage, wird Laravel nicht auf Docker verschoben wenn man das so nennen kann?
Ich habe bei mir in der Linuxconsole die welcome.blade.php bearbeitet und http://127.0.0.1:8000/ aufgerufen. Die Änderungen wurden übernommen.
Ist das bei Docker allgemein so üblich das die Files für ein Projekt auf dem Hostsystem verleiben und nicht in den Container geladen werden?

Ich habe eigentlich gedacht, nachdem die Container erstellt wurden das ich Laravel aus dem Homeordner löschen kann da alle Files auf Docker übertragen wurden.

Habe ich da einen Falschen Eindruck von Docker oder habe ich es falsch angegangen?

Bei meinem Test mit WordPress war das nicht der Fall. Da waren alle File im Docker Container
 

dominik

Aktives Mitglied
Nein, du hast schon den richtigen Eindruck von Docker. Standardmäßig befinden sich alle notwendigen Dateien im Image und später im Container. Das ist vor allem bei Images wichtig, die "verteilt" werden sollen - also wenn sie in einer Registry anderen Entwicklern zur Verfügung gestellt werden sollen oder auf einem Server laufen. Da sollte alles Notwendige inkludiert sein.

Es gibt allerdings auch eine Möglichkeit, vom Container aus auf Dateien am Host zuzugreifen, und genau das wird im Tutorial gemacht:

docker-compose.yml:
volumes:
      - ./:/var/www

Hier wird das aktuelle Verzeichnis auf dem Host (./) an der Stelle /var/www in den Container eingehängt. Da /var/www der Web-Root des Servers ist, liefert der Server direkt die Dateien vom Host aus. Es handelt sich dabei um einen Bind Mount, die ich hier mal erklärt habe: https://dev-community.de/resources/docker-bind-mounts-eine-Übersicht.18/

Dieses "Hot Reloading" ist für die lokale Entwicklung praktisch. Sobald du das Image an andere Entwickler oder Systeme verteilen würdest, würdest du die Code-Dateien aber in das Image kopieren.
 
Zuletzt bearbeitet:

Werner S

Mitglied
Danke für die verständliche Erklärung.

Wann empfiehlt sich ein locales Arbeitsverzeichnis und wann nicht oder kann man das nicht so pauschal sagen?

Nehmen wir mal 2 Projekte. Eine Homepage auf Basis von WordPress wo eher selten was an den Dateien geändert wird sondern nur von 7 Usern Artikel verfasst. Das kann, wenn ich das richtig aufgenommen habe ohne weitere ins Image.

Das 2 Projekt basiert auf Laravel. An diesem Arbeiten 7 Programmierer, git ist im Einsatz.
An diesem Projekt wird täglich gearbeitet, jede Woche werden neue Features veröffentlicht. Sollte sowas auch ins Image oder lieber dauerhaft auf dem localen Arbeitsverzeichnis?

Wenn die Files im Image liegen, wie werden dann bei neuen Features oder Codeänderungen die Files auf das vorhandene Image übertragen? Im Bestfall ohne das der Container beendet werden muss weil zum Beispiel 30.000 User auf die Homepage, rund um die Uhr zugreifen?
 
Zuletzt bearbeitet:

dominik

Aktives Mitglied
Früher wurde Infrastruktur wie Fileserver oder Webserver noch manuell und ohne jeglicher Automatisierung von Systemadministratoren betrieben und den Entwicklern zur Verfügung gestellt. Die Administratoren konfigurierten den Server, und die Entwickler konnte ihren Code per FTP zum Server übertragen. Jedes mal, wenn eine Änderung am Server notwendig war, nahm einer der Administratoren eine Anpassung vor.

Dabei zeigten sich einige Nachteile: Wenn diese Infrastruktur über Jahre modifiziert und angepasst wurde, war sie - weil niemand mehr genau wusste, was eigentlich alles konfiguriert und geändert wurde - nicht mehr reproduzierbar. Wenn man bei diesen alten Projekten einen neuen Server aufsetzen müsste, stünde viel Recherchearbeit bevor. Wenn es zudem zu Fehlern in der Anwendung oder auf dem Server kam, kannten die Entwickler nie den aktuellen Zustand des Systems: Wurde eine Konfiguration am Server geändert? Welcher Stand des Codes läuft gerade? Und wurde am Code zwischenzeitlich noch etwas geändert?

Docker löst das Problem der fehlenden Reproduzierbarkeit und des unklaren Zustands damit, dass Images unveränderbar ("immutable") sind. Bei unveränderbarer Infrastruktur weiß man immer, wie der Zustand ist, weil er sich nie geändert hat. Anstatt Änderungen an einem bestehenden Image oder an bestehender Infrastruktur vorzunehmen, baut man einfach ein vollständig neues Image. Codeänderungen werden also nie auf das vorhandene Image übertragen. Zudem ist im Dockerfile klar dokumentiert, welche Konfigurationen vorgenommen werden.

Das Konzept der "Immutable Infrastructure" hat sich in den vergangenen Jahren mehr als bewährt. Im Tao of HashiCorp ist Immutability sogar als Leitgrundsatz festgelegt:

Immutability is the inability to be changed. This is a concept that can apply at many levels. The most familiar implementation of immutability is version control systems; once code is committed, that commit is forever fixed. Version control systems, such as git, enjoy widespread use because they offer tremendous benefits. Code becomes versionable, allowing rollback and roll forwards. You can inspect and write code atomically. Using versions enables auditing and creates a clear history of how the current state was reached. When something breaks, the origin of the error can be determined using the version history.

The concept of immutability can be extended to many aspects of infrastructure — application source, application versions, and server state. We believe that using immutable infrastructure leads to more robust systems that are simpler to operate, debug, version and visualize.

Das bedeutet auch, dass es erstmal keine Rolle spielt, ob ein, zwei oder 30 Entwickler an einem Projekt arbeiten. Wenn die Entwickler Git verwenden, würde der normale Workflow so aussehen, dass jeder Entwickler den aktuellen Stand vom Code bei sich auscheckt und ein docker-compose up ausführt. Bei diesem Schritt werden entweder alle Quelldateien in das Image kopiert und anschließend wird der Container gestartet, oder der Quellcode wird wie bei deinem Tutorial als Bind Mount in den Container eingehängt. Für die lokale Entwicklung ist ein Bind Mount angenehmer, weil man ansonsten nach jeder Änderung das Image neu bauen und starten müsste - eben weil das Image unveränderbar ist.

Nachdem ein Entwickler seine Änderungen vorgenommen hat, würde er den Code dann pushen und einen Pull Request erstellen, der von einem der anderen Entwickler abgenommen werden muss. Wenn dann der Pull Request gemerged wird, würde typischerweise automatisch ein neues Image gebaut werden, diesmal aber mit dem "reinkopierten" Quellcode. Dieses Image würde dann durch das bestehende Image auf dem Live-Server ausgetauscht werden.

Dein genannter Bestfall, dass der Container nicht gestoppt werden muss, kann also standardmäßig nicht so einfach erfüllt werden. Man kann aber einfach einen Load Balancer davor schalten, dann den neuen Container starten, und erst dann den Alten stoppen.

Ja, theoretisch kann man auch einen Container auf dem Live-Server laufen lassen und auch dort einen Bind Mount verwenden, sodass man den Container nicht neu starten müsste. Damit würde man aber den Zustand des Containers ändern, weil sich der Code ändert, und man verliert den Vorteil der Reproduzierbarkeit und Unveränderbarkeit.
 

Werner S

Mitglied
Das kann ich nachvollziehen. Mein Server lief 6 Jahren und wurde vergessen. Viele der Änderungen kann ich heute gar nicht mehr nachvollziehen,Der Vorteil von Docker ergibt sich mir langsam.

Bevor ich dies aber Produktiv Einsetzen, möchte ich dies erst verstehen, auch wenn es bei mir etwas länger dauert. Mein Englisch ist mit dem Alter noch schlimmer geworden, daher bin ich für jede Deutsche, verständliche Erklärung dankbar.

Wenn ich das jetzt richtig verstanden habe, bei einem Update der Anwendung wird das Images gestoppt, und neue Images angelegt und die alten gelöscht.
Dabei gehen vermutlich auch alle Daten verloren wie Datenbank und Mails? Wie löst man dies ohne Verlust?
Was ist zb. wenn die Anwendung für jeden neuen User einen eigenen Ordner erstellt, zb. Nextcloud. Diese Daten wären dann bei Codeänderungen auch weg.

Wäre für so eine Anwendung, die Wöchentlich ein neues Updates bekommt (Code erweitert, Datenbank erweitert, durch die Anwendung, täglich neu angelegte Ordner) Docker das richtige?
 

dominik

Aktives Mitglied
Am besten funktionieren Container tatsächlich bei zustandslosen ("stateless") Anwendungen, eben weil Daten durch das ständige Starten und Stoppen von Containern verloren gehen. Wenn man Daten vom Lebenszyklus eines Containers unabhängig machen möchte, gibt es dafür zwei Wege:

1. Volumes: Auch hierzu habe ich eine Erklärung geschrieben. Ein Volume wird in ein bestimmtes Verzeichnis im Container eingehängt, und alle Dateien werden in diesem Volume und nicht im Container gespeichert. Das Volume selbst ist ein von Docker verwaltetes Verzeichnis auf dem Hostsystem. Damit überleben die Daten eines Volumes auch Container-Neustarts.

2. Infrastruktur außerhalb von Docker: Der fast noch einfachere und gängigere Weg ist aber - zumindest in großen Produktivsystemen - das Betreiben dieser Infrastruktur außerhalb von Docker. So würde man beispielsweise die Datenbank, dedizierte File-Storages oder ähnliches nicht in einem Container, sondern auf klassischem Wege betrieben. Nur der zustandslose Code läuft im Container.

Bei uns in der Firma ist es auch so, dass die Datenbank auf eigenen Servern läuft (mehrere Instanzen bilden da ein Cluster), und die ganzen Services laufen in Containern, die durch zahlreiche Codeänderungen ständig gestartet, gestoppt, gelöscht und ersetzt werden. Große Mengen an Dateien kann man dann auch einfach bei einem Cloud-Dienstleister ablegen und auch darauf von den Containern aus zugreifen.
 

Werner S

Mitglied
Bei großen Projekten wo immer viel Bewegung drinne ist eine Mischung aus beiden?
Eine Anwendung wo sich Minütlich die DB und Wöchentlich die Files ändern, NGINX und Mailserver dann lieber in den Container und die Files der Anwendung (zb. Laravel und die DB) Extern.

Eine WordPress Installation wo sich eigentlich nach Einrichtung bis auf Artikel nichts ändern kann komplett in Docker?

Kur gesagt: Es kommt immer auf die Anwendung an, nicht immer ist Docker die bessere Wahl?

Ich finde deine Artikel leicht verständlich, kommen bezüglich Docker noch einige?
 

dominik

Aktives Mitglied
Ja, es kommt immer auf die Anwendung drauf an, bzw. auf die notwendige Infrastruktur.

Für die eigentliche Anwendung, also den Quellcode, macht Docker so gut wie immer Sinn. Für die lokale Entwicklung macht auch eine Datenbank in einem Container Sinn - sodass ein docker-compose up die gesamte Infrastruktur lokal in Docker hochfährt. Das sind alles Fälle, in denen die Anwendung tendenziell zustandslos ist bzw. die Daten keine lange Lebensdauer haben müssen.

Auf Produktionssystemen hat es sich hingegen wie gesagt durchgesetzt, die Datenbank nicht in einem Container laufen zu lassen. Letztendlich muss man immer selbst abwägen, welches Setup für die eigene Situation sinnvoll ist - als Daumenregel kann man sagen: Je zustandsloser die Anwendung, desto mehr bietet sie sich für die Containerisierung an.

Für weitere Artikel habe ich persönlich aktuell kaum Ideen, ich kann aber gerne ein bestimmtes Thema erklären, falls da Bedarf herrscht.
 

Werner S

Mitglied
Ich hätte da ein paar Ideen aufgrund der Tatsache das vieles nur in Englisch verfügbar ist.
Beschreibung/Aufbau der kompletten Dockerfile und docker-compose.yml
Stoppen, Löschen, Starten bei Updates einer Anwendung
Cluster, Backup, Load Balancer

Aufgrund meines Englisch habe ich 3 Tage gebraucht für Laravel 9, PHP8.1 und Nginx. Das es unterschiede bei den Befehlen gibt was nginx und nginx:alpine gibt hat mir viel Zeit gekostet.
 
Zuletzt bearbeitet:

dominik

Aktives Mitglied
Zu Dockerfiles habe ich zwei Artikel geschrieben:
Zudem kann ich noch das Buch "Docker: Das Praxisbuch für Entwickler und DevOps-teams" empfehlen, mit dem man einen guten Eindruck von Docker bekommt: https://www.rheinwerk-verlag.de/docker-das-praxisbuch-fuer-entwickler-und-devops-teams/? Mit dem habe ich selbst auch angefangen. Ansonsten konkrete Themenwünsche gerne äußern 🙂
 
Oben Unten