Wie man Laravel dockerisiert und deployed

Wie man Laravel dockerisiert und deployed

Lukas Mauser - Co-Founder von sliplane.ioLukas Mauser
5 min

Dieses 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:

Dockerfile
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

  1. Basis-Image:
  • Nutzt dunglas/frankenphp:1-php8.3-alpine, das PHP 8.3, den FrankenPHP-Server und den praktischen install-php-extensions Helper bündelt.
  1. 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_mysql weg, wenn du nur Postgres nutzt.
  1. Dependency-Installation:
  • Kopiert erst nur composer.json und composer.lock und führt dann composer install ohne 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.
  1. Application-Code:
  • Kopiert das Projekt und führt composer dump-autoload --optimize aus, um eine schnelle Class-Map für Production zu erzeugen.
  1. Ausliefern:
  • Kopiert unser Caddyfile, das den Web-Root auf Laravels public Ordner zeigt und php_server aktiviert. auto_https off ist 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.

Sliplane Dashboard

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 :)

Deploy Laravel in 2 Minuten 🚀

Push dein Repo zu GitHub und lass Sliplane deine Laravel App für dich bauen und deployen. Die ersten 2 Tage sind kostenlos.

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

Willkommen auf deiner Cloud-Plattform

Sliplane macht es einfach, deine Apps in der Cloud zu deployen und zu skalieren. Starte mit einem Container oder deinem Lieblings-Framework und wachse von da aus. Probier es jetzt aus!