
Wie man Laravel dockerisiert und deployed
Lukas MauserDieses Dockerfile packt deine Laravel App mit FrankenPHP, einem modernen PHP-Server, der deine App ausführt und HTTP aus einem einzelnen Prozess auf einem einzelnen Port ausliefert. Genau das willst du in einem Container.
Falls du nur zum Kopieren und Einfügen hier bist, hier ist das fertige Dockerfile, das ein Image für deine Laravel App erstellt:
FROM dunglas/frankenphp:1-php8.3-alpine
# Composer aus dem offiziellen Image holen
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
# Die PHP-Extensions installieren, die Laravel üblicherweise braucht
RUN install-php-extensions pcntl pdo_pgsql pdo_mysql gd zip intl opcache
WORKDIR /app
# Erst die Dependencies installieren, damit dieser Layer gecacht bleibt, wenn sich nur der Quellcode ändert
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist
# Den Rest der App kopieren und den optimierten Autoloader bauen
COPY . .
RUN composer dump-autoload --optimize
# Über unser eigenes Caddyfile ausliefern
COPY Caddyfile /etc/caddy/Caddyfile
EXPOSE 8080
CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"]
FrankenPHP baut auf dem Caddy Webserver auf, liest also ein kleines Caddyfile. Leg das neben dein Dockerfile:
{
frankenphp
auto_https off
}
:8080 {
root * /app/public
encode gzip
php_server
}
Und hier ist die .dockerignore Datei:
vendor
node_modules
.git
.env
storage/logs/*
Um das Image zu bauen und auszuführen, nutze diese Befehle:
docker build -t laravel-app .
docker run -p 8080:8080 laravel-app
Nicht nur zum Kopieren und Einfügen hier? Dann lass uns durchgehen, was im Dockerfile passiert!
Das Setup
Für dieses Tutorial gehe ich davon aus, dass du ein funktionierendes Laravel Projekt hast. Der klassische Weg, Laravel in Production zu betreiben, ist nginx vor PHP-FPM, was zwei Prozesse, einen Process-Manager und einiges an Config bedeutet. In einem Container sind das mehr bewegliche Teile, als du willst.
FrankenPHP ersetzt das alles. Es ist ein einzelnes Binary, das PHP und einen Webserver einbettet, sodass ein Prozess deine App auf einem Port ausliefert. Das passt perfekt dazu, wie eine Plattform einen Container betreibt, und es ist schnell, weil die Runtime zwischen den Requests warm bleibt.
Das Dockerfile
- Basis-Image:
- Nutzt
dunglas/frankenphp:1-php8.3-alpine, das PHP 8.3, den FrankenPHP-Server und den praktischeninstall-php-extensionsHelper bündelt.
- Composer und Extensions:
- Kopiert das Composer-Binary aus dem offiziellen Composer-Image, damit wir es nicht von Hand installieren.
- Installiert gängige Laravel-Extensions. Pass die Liste an deine App an, lass zum Beispiel
pdo_mysqlweg, wenn du nur Postgres nutzt.
- Dependency-Installation:
- Kopiert erst nur
composer.jsonundcomposer.lockund führt danncomposer installohne Dev-Dependencies aus. Weil das vor dem restlichen Code passiert, kann Docker es cachen und das Neuinstallieren der Packages überspringen, wenn du nur Application-Code änderst.
- Application-Code:
- Kopiert das Projekt und führt
composer dump-autoload --optimizeaus, um eine schnelle Class-Map für Production zu erzeugen.
- Ausliefern:
- Kopiert unser
Caddyfile, das den Web-Root auf LaravelspublicOrdner zeigt undphp_serveraktiviert.auto_https offist gesetzt, weil deine Hosting-Plattform TLS für dich terminiert, sodass FrankenPHP einfach nur plain HTTP auf Port 8080 sprechen muss.
Eine Sache zum Merken: Laravel liest seine Konfiguration zur Laufzeit aus Environment-Variablen, also setz APP_KEY, deine Datenbank-Credentials und den Rest als Environment-Variablen auf deinem Host, statt eine .env Datei ins Image zu backen.
Deployment
Du kannst diesen Docker Container bei jedem Cloud-Anbieter deployen, der Docker unterstützt. Du könntest zum Beispiel Plattformen wie Heroku, DigitalOcean oder AWS ECS nutzen. Da ich Mitgründer von Sliplane bin, zeig ich dir, wie du es dort deployst.
Nach der Anmeldung kannst du einen neuen Service erstellen, indem du dein GitHub Repository auswählst. Behalt dann die Standardeinstellungen bei, füg deine Environment-Variablen wie APP_KEY und die Datenbank-Verbindung hinzu und klick auf Deploy.

Nach dem Deployment ist deine Laravel App unter einer Subdomain von sliplane.app verfügbar, normalerweise ist das einfach dein Service-Name.
Du kannst auch die Logs deiner App sehen, Metriken wie CPU- und Speichernutzung einsehen, persistenten Speicher für Uploads hinzufügen und vieles mehr. Wann immer du in dein Repository pushst, deployed Sliplane deine App automatisch.
Wenn du Sliplane ausprobieren möchtest, sind die ersten 2 Tage kostenlos! Probier es aus und lass mich wissen, was du davon hältst :)
Nächste Schritte
Sobald die App läuft, willst du wahrscheinlich php artisan migrate beim Deploy ausführen und deine Config mit php artisan optimize cachen. Beides passt gut in ein kleines Startup-Script. Brauchst du dabei eine Hand oder beim Anbinden einer Managed-Datenbank? Melde dich gerne!
Bis dann,
Lukas