So containerisieren Sie eine PHP-Anwendung sicher mit Docker
James Olaogun
2. August 2023
0 Min. LesezeitAnmerkung der Redaktion: 10. August 2023
Dieser Beitrag wurde aktualisiert und enthält jetzt eine aktuellere PHP-Version im Tutorial.
Nehmen wir an, Sie haben eine PHP-Anwendung entwickelt, möchten sie aber von der unterstützenden Infrastruktur trennen – und zwar so, dass sie leichtgewichtig, portabel und dennoch sicher bleibt. Andere Entwickler sollen damit arbeiten können, ohne ganze Umgebungen neu erstellen zu müssen. Kurz gesagt: Sie möchten Ihre Anwendung containerisieren – sie also zusammen mit ihren Abhängigkeiten in Containern verpacken, die sich problemlos in verschiedenen Umgebungen teilen lassen.
Die derzeit beliebteste Lösung für die Containerisierung ist Docker, eine Open-Source-Plattform, die erstmals 2013 vorgestellt wurde. Seitdem hat sich Docker zu einer weitverbreiteten Technologie in der Softwareentwicklung entwickelt, mit der Anwendungen isoliert, wiederverwendbare CI/CD-Komponenten erstellt und schnelle Bereitstellungen ermöglicht werden.
Dieses Tutorial zeigt Ihnen Schritt für Schritt, wie Sie eine PHP-Anwendung sicher containerisieren – oder genauer gesagt „dockerisieren“. Außerdem verwenden Sie Snyk, eine Sicherheitsplattform für Entwickler, die Sicherheitstools für moderne Anwendungen bereitstellt, um Schwachstellen zu erkennen und ihre Behebung zu automatisieren.
Voraussetzungen und Empfehlungen
Bevor Sie mit dem folgenden Tutorial beginnen, nehmen Sie sich einen Moment Zeit und vergewissern Sie sich, dass Sie über die folgenden Tools verfügen:
Docker ist auf Ihrem Rechner installiert. Damit führen Sie den PHP-Container aus und verwalten ihn.
Ein kostenloses Snyk-Konto. Die Sicherheitsscans von Snyk machen Schwachstellen in den Containern sichtbar und helfen Ihnen, sie zu beheben.
NPM oder Yarn, um die Snyk CLI zu installieren und auszuführen.
Eine einfache PHP-Anwendung. In diesem Tutorial verwenden wir ein neu erstelltes Laravel-Projekt.
Wenn Sie sicher sind, dass Sie diese Voraussetzungen erfüllen, beachten Sie vor dem Tutorial noch die folgenden Tipps. Diese Empfehlungen helfen Ihnen dabei, Ihre PHP-Anwendung nahtlos und sicher mit Docker zu containerisieren.
Verwenden Sie für Builds eine bestimmte Image-Version
Vergewissern Sie sich beim Erstellen Ihrer Anwendung immer, dass Sie eine bestimmte Version des Docker-Images verwenden. Anstatt beispielsweise PHP-FPM abzurufen, können Sie eine Image-Version angeben und PHP:8.0-fpm abrufen. Beachten Sie, dass das Basis-Image, das Sie verwenden, von den Versionsanforderungen Ihrer Anwendung abhängt.
So können Sie sicher sein, dass Ihre Anwendung auf einem bekannten, getesteten und stabilen Release basiert. Außerdem wissen Sie, dass die Image-Version in verschiedenen Umgebungen dieselbe zugrunde liegende Plattform und dieselben Abhängigkeiten verwenden kann, was die Reproduzierbarkeit und Konsistenz verbessern kann.
Verwenden Sie ADD nicht für Remote-Abhängigkeiten
Mit dem Befehl ADD lassen sich Dateien von beliebigen URLs herunterladen. Dadurch können Sicherheitslücken in Ihrer Docker-Anwendung entstehen. Daher empfehle ich, in Dockerfiles auf den Befehl `ADD` zum Einbinden von Remote-Abhängigkeiten zu verzichten.
Verwenden Sie stattdessen den Befehl COPY, um Dateien aus dem lokalen Dateisystem zu kopieren. Mit dem Befehl COPY stellen Sie sicher, dass nur die für die Anwendung erforderlichen Dateien in das Docker-Image aufgenommen werden. Auch dadurch wird das Risiko von Schwachstellen verringert.
Verwenden Sie eine docker-compose-YAML-Datei
Mit Docker Compose können Sie Ihre Docker-Container verwalten und orchestrieren. Dazu definieren Sie Ihre Docker-Anwendung in einer YAML-Datei und legen fest, wie sie erstellt und ausgeführt werden soll. Zu den Vorteilen von Docker Compose gehören:
Anwendungskomponenten trennen. Mit Docker Compose können Sie die Komponenten Ihrer Anwendung auf verschiedene Container aufteilen. Dadurch wird die Angriffsfläche jedes Containers begrenzt und das Risiko eines einzelnen Ausfallpunkts verringert.
Umgebungsvariablen verwenden. Mit Docker Compose können Sie Ihre Anwendung mithilfe von Umgebungsvariablen konfigurieren. So lassen sich sensible Informationen wie Datenbankpasswörter sicher verwalten.
Netzwerkverbindungen verwalten. Mit Docker Compose können Sie die Netzwerkverbindungen zwischen Ihren Containern verwalten. So stellen Sie sicher, dass Ihre Container nur über einen sicheren Kanal miteinander kommunizieren können.
Wenn Sie Docker Desktop für Windows, Mac oder Linux installiert haben, ist Docker Compose bereits enthalten.
Verwenden Sie PHP-FPM statt mod_php
PHP-FPM und mod_php sind beides Lösungen zum Ausführen von PHP-Anwendungen auf Webservern, unterscheiden sich jedoch in ihrer Funktionsweise. mod_php ist ein Apache-Modul, mit dem der Apache-Webserver PHP-Dateien verarbeiten kann. PHP-FPM ist dagegen ein PHP-Prozessmanager, der mit verschiedenen Webservern wie NGINX und Apache zusammenarbeitet.
PHP-FPM gilt allgemein als effizientere und besser skalierbare Möglichkeit, PHP-Anwendungen auszuführen – insbesondere in Umgebungen mit hohem Datenverkehr.
Verwenden Sie mehrstufige Builds
Mehrstufiges Erstellen ist eine Docker-Technik, mit der kleinere und sicherere Images erstellt werden. Wenn Sie in einem Dockerfile mehrere Phasen mit jeweils eigenen Anweisungen anlegen, müssen Sie nicht bei jeder Änderung das gesamte Image von Grund auf neu erstellen. Dadurch wird der Docker-Build-Prozess effizienter und schneller.
Testen Sie die Sicherheit Ihrer Docker-Anwendung regelmäßig
Regelmäßige Sicherheitstests sind entscheidend, um die Sicherheit Ihrer Anwendung zu gewährleisten und zu verbessern. Docker bietet zwar eine isolierte Umgebung für die Ausführung der Anwendung, garantiert aber nicht deren Sicherheit. Führen Sie regelmäßig Sicherheitsprüfungen durch, um potenzielle Schwachstellen zu erkennen und zu beheben, bevor Angreifer sie ausnutzen können.
Fünf Schritte, um Ihre PHP-Anwendung sicher mit Docker zu containerisieren
Kommen wir nun zum praktischen Teil! Im folgenden Tutorial erfahren Sie in fünf Schritten, wie Sie eine Laravel-PHP-Anwendung sicher mit Docker containerisieren. Dabei wenden Sie einige der gerade vorgestellten Tipps an.
1. Richten Sie das Dockerfile mit Apache ein
Erstellen Sie ein neues Laravel-Projekt, falls Sie noch keines haben, und wechseln Sie mit cd in das Verzeichnis des neuen Laravel-Projekts. Ändern Sie im folgenden Befehl beispielsweise {{laravel-application-directory}} in den Verzeichnisnamen Ihrer Laravel-Anwendung.
Erstellen Sie im Stammverzeichnis Ihrer Laravel-Anwendung eine neue Datei mit dem Namen Dockerfile:
Kopieren Sie den folgenden Code und fügen Sie ihn in das neu erstellte Dockerfile ein:
Wie oben erwähnt, eignet sich PHP-FPM besser für die Entwicklung einer skalierbaren Lösung. In diesem Tutorial verwenden wir jedoch mod_php, da die Anwendung klein ist.
Beachten Sie außerdem, dass im obigen Dockerfile mehrstufige Builds verwendet werden. In der ersten Phase wird das offizielle Composer-Image verwendet, um die Anwendungsabhängigkeiten zu installieren und den Autoloader zu erstellen. In der zweiten Phase kommt das offizielle PHP/Apache-Image zum Einsatz, um die Anwendung auszuführen. Achten Sie darauf, dass mit dem Befehl COPY die Composer-Build-Dateien aus dem lokalen Dateisystem kopiert werden – nicht mit dem Befehl ADD.
Erstellen Sie im Stammverzeichnis Ihrer Laravel-Anwendung eine neue Datei mit dem Namen docker-compose.yml:
Kopieren Sie den folgenden Code und fügen Sie ihn in die neu erstellte Datei docker-compose.yml ein:
Im vorherigen Code ist der Dienst snykdemoapp der Container für die PHP-Anwendung. Im Abschnitt „networks“ wird außerdem das app-network definiert, das Docker Compose für die Kommunikation verwendet.
2. Fügen Sie der docker-compose.yml einen MySQL-Datenbankcontainer hinzu
Fügen wir Ihrer Datei docker-compose.yml einen MySQL-Container hinzu. Dieser Container hostet die Datenbank Ihrer Laravel-Anwendung.
Erstellen Sie einen neuen Dienst für Ihren MySQL-Container, indem Sie den folgenden Code als neuen Dienst in die in Schritt eins erstellte Datei docker-compose.yml einfügen:
Im vorherigen Codeblock:
app_dbist der Name des Datenbankdienstes, der mit dem MySQL-5.7-Image erstellt wurde. Sie können den Namen beliebig ändern. Achten Sie jedoch darauf, ihn auch in anderen verknüpften Diensten anzupassen.{{database_name}}ist der von Ihnen gewünschte Datenbankname.{{database_user}}ist der von Ihnen gewünschte Datenbankbenutzer.{{dbuser_password}}ist das von Ihnen gewünschte Passwort für den Datenbankbenutzer.
Damit haben Sie Ihrer Docker-Konfiguration erfolgreich einen MySQL-Container hinzugefügt.
3. Fügen Sie der docker-compose.yml einen PHPMyAdmin-Container hinzu
Fügen wir nun neben Ihren Laravel- und MySQL-Containern einen PHPMyAdmin-Container für lokale Tests hinzu. PHPMyAdmin ist ein kostenloses Open-Source-Verwaltungstool für MySQL und MariaDB. Es bietet eine webbasierte Oberfläche, über die Sie Ihre Datenbanken verwalten können. Wir empfehlen, PHPMyAdmin nur in der Entwicklung und nicht in der Produktion zu verwenden.
Erstellen Sie einen neuen Dienst für Ihren PHPMyAdmin-Container, indem Sie den folgenden Codeausschnitt als neuen Dienst in die Datei docker-compose.yml einfügen.
Im vorherigen Codeblock ist phpmyadmin der Name des PHPMyAdmin-Dienstes, der mit dem Image phpmyadmin/phpmyadmin erstellt wurde. Im Abschnitt „environment“ wird die Variable PMA_HOST auf app_db gesetzt – den Namen des MySQL-Dienstes in derselben Datei docker-compose.yml.
Nun ist Ihr PHPMyAdmin-Container für die Zusammenarbeit mit Ihren Laravel- und MySQL-Containern eingerichtet. Beachten Sie, dass das PHPMyAdmin-Image nur für Entwicklungszwecke verwendet werden sollte. Der Einsatz in der Produktion stellt ein Sicherheitsrisiko für Ihre Anwendung dar.
4. Erstellen und starten Sie die Laravel-PHP-Anwendung mit Docker
Nachdem Sie das Dockerfile und die Datei docker-compose.yml eingerichtet haben, starten Sie den Docker-Dienst und vergewissern Sie sich, dass er läuft. Anschließend können Sie die Laravel-PHP-Anwendung mit den folgenden Befehlen erstellen und starten:
docker-compose build: Erstellt das Docker-Image.docker-compose up -d: Startet die Container.docker ps: Überprüft den Status des Containers.
Wenn alle obigen Befehle erfolgreich ausgeführt wurden, öffnen Sie Ihren Webbrowser und rufen Sie http://localhost:8000/ auf, um die Startseite Ihrer Laravel-Anwendung aufzurufen.

Sie können auch http://localhost:8080/ aufrufen, um die PHPAdmin-Oberfläche zu öffnen. Verwenden Sie für die Anmeldung einfach MYSQL_USER und MYSQL_PASSWORD, die Sie in Ihrer Datei docker-compose.yml festgelegt haben.

5. Testen und schützen Sie Ihre PHP-Anwendung mit Snyk
Sobald Sie Ihre Docker-Anwendung erfolgreich erstellt haben und sowohl die Anwendung als auch PHPMyAdmin über Ihren Browser aufrufen können, testen Sie im nächsten Schritt die Sicherheit der Docker-Anwendung. In diesem Tutorial verwenden wir Snyk, um die Docker-Anwendung zu testen und sicherzustellen, dass sie umfassend geschützt ist.
Melden Sie sich an oder erstellen Sie ein neues Snyk-Konto mit einem der auf der Seite aufgeführten SSO-Anbieter Ihrer Wahl. Installieren Sie die Snyk CLI und authentifizieren Sie Ihren Laptop, wie im Abschnitt zu den Voraussetzungen dieses Artikels beschrieben.

Nachdem Sie Snyk erfolgreich eingerichtet haben, können Sie mit der Snyk CLI die Sicherheit Ihrer Docker-Anwendung bewerten. Führen Sie den folgenden Befehl im Stammverzeichnis Ihrer Laravel-Anwendung aus:
Im vorherigen Befehl ist {{your-image}} der Name des Images, das Sie testen möchten. Mit dem Befehl `docker ps` können Sie eine Liste der Docker-Images in Ihrer Anwendung abrufen.
Wenn Sie den vorherigen Befehl für das Basis-Image PHP 8.2 mit dem Namen snykdemoapp ausführen, erhalten Sie in diesem Tutorial folgendes Ergebnis:

PHP 8.2 ist die neueste Version mit Long-Term-Support. Obwohl im Basis-Image dieses Containers 69 Sicherheitsprobleme gefunden wurden, haben sie alle einen niedrigen Schweregrad.
Wenn Sie in Ihren Produktionsanwendungen auf ältere PHP-Versionen wie PHP 7.4 setzen, finden Sie schwerwiegendere und dringendere Sicherheitslücken, die behoben werden müssen. In diesem Fall ist Snyk besonders hilfreich, da Ihnen alternative Image-Typen mit weniger Schwachstellen angezeigt werden.
Der Befehl snyk container test liefert nur ein einmaliges Ergebnis. Besser ist es, den Befehl container monitor für einen Container-Scan auszuführen.
Mit dem Befehl container monitor werden die Testergebnisse Ihres Container-Images an Snyk gesendet. So kann Snyk die Informationen in Ihrem Dashboard anzeigen und Sie über mögliche zukünftige Schwachstellen in Ihrem Image benachrichtigen.
Wenn Sie container monitor für das Basis-Image PHP 7.4 mit dem Namen snykdemoapp ausführen.

So beheben Sie erkannte Schwachstellen in Ihrer PHP-Anwendung
Nachdem Sie Ihren PHP-Container getestet haben, finden Sie hier einige Tipps, die Sie beim Beheben erkannter Schwachstellen beachten sollten.
Erstellen Sie das Image neu, um die neuesten Sicherheitsupdates aus dem Upstream-Docker-Basisimage zu erhalten. So stellen Sie sicher, dass alle Sicherheitsupdates in Ihre Anwendung übernommen werden. Führen Sie nach dem Neuerstellen den Sicherheitsscan erneut aus, um Schwachstellen zu identifizieren und zu beheben, die durch die neuesten Sicherheitsupdates des Basisimages entstehen könnten.
Prüfen Sie die von Snyk bereitgestellte Schwachstellenbewertung. Diese Liste kann nützliche Informationen zu potenziellen Sicherheitsproblemen in den Abhängigkeiten Ihrer Anwendung liefern.
Denken Sie daran, dass Schwachstellen aus verschiedenen Quellen stammen können. Dazu gehören die PHP-Laufzeitumgebung sowie die im Basisimage installierten Tools und Bibliotheken. Es ist wichtig, alle Komponenten des Anwendungs-Stacks regelmäßig zu aktualisieren und zu überwachen, damit Sicherheitslücken zeitnah erkannt und behoben werden.
Fazit
Mit einigen Best Practices können Sie eine Anwendung mit weniger Schwachstellen entwickeln. Wenn Sie das Schritt-für-Schritt-Tutorial durchgearbeitet haben, sollten Sie in der Lage sein, eine Dockerisierte PHP-Anwendung sicher zu entwickeln und dabei die Sicherheitsplattform von Snyk zum Erkennen und Beheben von Schwachstellen zu nutzen.
Den gesamten Code für die Dockerisierte Laravel-Anwendung aus diesem Tutorial finden Sie auf GitHub.
Container-Sicherheit mit Fokus auf Entwickler
Snyk findet und behebt automatisch Schwachstellen in Container-Images und Kubernetes-Workloads.



