Eine Erweiterung für die Verwendung von Laravel in einer Umgebung mit mehreren Domänen
Dieses Paket ermöglicht die Arbeit einer einzelnen Laravel-Installation mit mehreren HTTP-Domänen.
Es gibt viele Fälle, in denen verschiedene Kunden dieselbe Anwendung in Bezug auf den Code verwenden, nicht jedoch in Bezug auf Datenbank, Speicherung und Konfiguration.
Dieses Paket bietet eine sehr einfache Möglichkeit, für jeden dieser Kunden eine bestimmte Umgebungsdatei, einen bestimmten Speicherpfad und eine bestimmte Datenbank abzurufen.
Laravel | Multidomain |
---|---|
11.x | 11.x |
10.x | 10.x |
9.x | 5.x |
8.x | 4.x |
7.x | 3.x |
6.x | 2.x |
5.8.x | 1.4.x |
5.7.x | 1.3.x |
5.6.x | 1.2.x |
5.5.x | 1.1.x |
Veröffentlichungen v1.1.x:
Bisher sind die Versionen v1.1.6+, v1.2.x, v1.3.x, v1.4.x, v2.x und v3.x funktional gleichwertig. Die Releases wurden getrennt, um Integrationstests mit der entsprechenden Version des Laravel-Frameworks durchzuführen.
Mit der Veröffentlichung von Laravel 8 sind jedoch die Versionen v1.1.14, v1.2.8, v1.3.8 und v1.4.8 die letzten Versionen, die neue Funktionen für die entsprechenden Laravel 5.x-Versionen enthalten (die Bugfix-Unterstützung ist für diese Versionen weiterhin aktiv). . 13.02.2021 UPDATE : Einige letzte Funktionen für Versionen ab Version 1.1 sind noch in Arbeit :)
v1.0 erfordert Laravel 5.1, 5.2, 5.3 und 5.4 (wird im Vergleich zu Laravel 5.4 nicht mehr gewartet und nicht getestet, die Verwendung des Pakets ist jedoch dieselbe wie für 1.1)
20.02.2023 UPDATE : Ab Laravel 10.x folgen die Paketversionen der gleichen Nummerierung.
Fügen Sie „gecche/laravel-multidomain“ als Anforderung zu „composer.json“ hinzu:
{
"require" : {
"gecche/laravel-multidomain" : "11.*"
}
}
Aktualisieren Sie Ihre Pakete mit Composer Update oder installieren Sie sie mit Composer Install.
Sie können das Paket auch mit composer require gecche/laravel-multidomain
hinzufügen und später die gewünschte Version angeben.
Dieses Paket muss die Erkennung der HTTP-Domäne in einem minimalen Satz von Laravel-Kernfunktionen gleich zu Beginn des Bootstrap-Prozesses überschreiben, um die spezifische Umgebungsdatei abzurufen. Daher benötigt dieses Paket ein paar weitere Konfigurationsschritte als die meisten Laravel-Pakete.
Installationsschritte:
bootstrap/app.php
ändern. //use Illuminate F oundation A pplication
use Gecche Multidomain Foundation Application
QueueServiceProvider
mit dem erweiterten in der Datei config/app.php
wie folgt: ' providers ' => Illuminate Support ServiceProvider:: defaultProviders ()-> merge ([
// Package Service Providers . . .
])-> replace ([
Illuminate Queue QueueServiceProvider::class => Gecche Multidomain Queue QueueServiceProvider::class,
])-> merge ([
// Added Service Providers ( Do not remove this line ) . . .
])-> toArray (),
Bitte beachten Sie, dass, wenn Sie die Datei config/app.php
aus anderen Gründen geändert haben, wahrscheinlich bereits der oben genannte providers
Eintrag in dieser Datei vorhanden ist und die einzige wichtige Zeile diejenige ist, die den QueueServiceProvider
ersetzt.
php artisan vendor:publish
(Dieses Paket nutzt die Erkennungsfunktion.)
Wenn Sie die oben genannten Schritte ausführen, erkennt Ihre Anwendung die HTTP-Domäne, in der sie ausgeführt wird, sowohl für HTTP- als auch für CLI-Anfragen, einschließlich Warteschlangenunterstützung.
HINWEIS: In Laravel 11 ist die Installation einfacher als zuvor: Wenn Sie eine frühere Version von Laravel verwenden, überprüfen Sie bitte die Installationsschritte in der Dokumentation.
Das Paket ist dank Community-Beiträgen mit Horizon kompatibel. Wenn Sie dieses Paket zusammen mit Horizon verwenden müssen, müssen Sie zwei weitere Installationsschritte ausführen:
Installieren Sie Laravel Horizon wie gewohnt
Ersetzen Sie den Laravel Horizon-Import ganz oben in der Datei app/Providers/HorizonServiceProvider.php.
//use Laravel H orizon H orizonApplicationServiceProvider ;
use Gecche Multidomain Horizon HorizonApplicationServiceProvider ;
Dieses Paket fügt drei Befehle zum Verwalten Ihrer Anwendungs-HTTP-Domänen hinzu:
domain.add
artisan-Befehl Der Hauptbefehl ist der Befehl domain:add
, der als Argument den Namen der HTTP-Domäne verwendet, die der Anwendung hinzugefügt werden soll. Nehmen wir an, wir haben zwei Domänen, site1.com
und site2.com
, die denselben Code teilen.
Wir machen einfach:
php artisan domain:add site1.com
Und
php artisan domain:add site2.com
Diese Befehle erstellen zwei neue Umgebungsdateien, .env.site1.com
und .env.site2.com
, in die Sie die spezifische Konfiguration für jede Site einfügen können (z. B. Datenbankkonfiguration, Cache-Konfiguration und andere Konfigurationen, wie sie normalerweise in einer Umgebung zu finden sind). Datei).
Der Befehl fügt außerdem einen Eintrag im domains
in der Datei config/domains.php
hinzu.
Darüber hinaus werden zwei neue Ordner erstellt, storage/site1_com/
und storage/site2_com/
. Sie haben die gleiche Ordnerstruktur wie der Hauptspeicher.
Anpassungen an dieser storage
müssen mit Werten in der Datei config/domain.php
übereinstimmen.
domain.remove
artisan-Befehl Der Befehl domain:remove
entfernt die angegebene HTTP-Domäne aus der Anwendung, indem er ihre Umgebungsdatei löscht. Z.B:
php artisan domain:remove site2.com
Durch das Hinzufügen der force
-Option wird der Domänenspeicherordner gelöscht.
Der Befehl entfernt auch den entsprechenden Eintrag aus dem domains
in der Datei config/domains.php
.
domain.update_env
artisan-Befehl Der Befehl domain:update_env
übergibt ein JSON-codiertes Datenarray, um eine oder alle Umgebungsdateien zu aktualisieren. Diese Werte werden am Ende der entsprechenden .env hinzugefügt.
Aktualisieren Sie eine einzelne Domänenumgebungsdatei, indem Sie das domain
hinzufügen.
Wenn das domain
fehlt, aktualisiert der Befehl alle Umgebungsdateien, einschließlich der Standard .env
Datei.
Die Liste der zu aktualisierenden Domänen wird in der Konfigurationsdatei domain.php
verwaltet.
Z.B:
php artisan domain:update_env --domain_values='{"TOM_DRIVER":"TOMMY"}'
fügt die Zeile TOM_DRIVER=TOMMY
zu allen Domänenumgebungsdateien hinzu.
domain.list
artisan-Befehl Der Befehl domain:list
listet die aktuell installierten Domänen mit ihrer .env-Datei und dem Speicherpfadverzeichnis auf.
Die Liste wird im domains
der Konfigurationsdatei config/domain.php
verwaltet.
Diese Liste wird bei jeder Ausführung der Befehle domain:add
und domain:remove
automatisch aktualisiert.
config:cache
artisan-BefehlDer config:cache artisan-Befehl kann mit diesem Paket auf die gleiche Weise wie jeder andere artisan-Befehl verwendet werden.
Beachten Sie, dass dieser Befehl eine Datei config.php für jede Domain generiert, unter der der Befehl ausgeführt wurde. Also der Befehl
php artisan config:cache --domain=site2.com
generiert die Datei
config-site2_com.php
Zur Laufzeit wird die aktuelle HTTP-Domäne im Laravel-Container verwaltet und kann über die von diesem Paket hinzugefügte Methode domain()
aufgerufen werden.
Eine domainList()
Methode ist verfügbar. Es gibt ein assoziatives Array zurück, das die Informationen zu den installierten Domänen enthält, ähnlich dem obigen Befehl domain.list
.
Z.B
[
site1.com => [
'storage_path' => <LARAVEL-STORAGE-PATH>/site1_com,
'env' => '.env.site1.com'
]
]
Für jede von der Anwendung empfangene HTTP-Anfrage wird die spezifische Umgebungsdatei geladen und der spezifische Speicherordner verwendet.
Wenn keine bestimmte Umgebungsdatei und/oder kein Speicherordner gefunden wird, wird die Standarddatei verwendet.
Die Erkennung der richtigen HTTP-Domäne erfolgt mithilfe der PHP-Variable $_SERVER['SERVER_NAME']
.
WICHTIGER HINWEIS: In einigen Ausführungsumgebungen wird $_SERVER['SERVER_NAME'] nicht instanziiert, daher funktioniert dieses Paket nicht ordnungsgemäß, bis Sie die Erkennung von HTTP-Domänen wie unten beschrieben anpassen.
Ab Version 1.1.15 kann die Erkennung von HTTP-Domänen angepasst werden, indem ein Closure
als domain_detection_function_web
Eintrag des neuen domainParams
Arguments des Application
-Konstruktors übergeben wird. Im folgenden Beispiel basiert die HTTP-Domänenerkennung auf $_SERVER['HTTP_HOST']
anstelle von $_SERVER['SERVER_NAME']
.
//use Illuminate F oundation A pplication ;
use Gecche Multidomain Foundation Application ;
use Illuminate Foundation Configuration Exceptions ;
use Illuminate Foundation Configuration Middleware ;
$ environmentPath = null ;
$ domainParams = [
' domain_detection_function_web ' => function () {
return Illuminate Support Arr:: get ( $ _SERVER , ' HTTP_HOST ' );
}
];
return Application:: configure (basePath: dirname ( __DIR__ ),
environmentPath: $ environmentPath ,
domainParams: $ domainParams )
-> withRouting (
web: __DIR__ . ' /../routes/web.php ' ,
commands: __DIR__ . ' /../routes/console.php ' ,
health: ' /up ' ,
)
-> withMiddleware ( function ( Middleware $ middleware ) {
//
})
-> withExceptions ( function ( Exceptions $ exceptions ) {
//
})-> create ();
Um zwischen Domänen zu unterscheiden, akzeptiert jeder Handwerkerbefehl eine neue Option: domain
. Z.B:
php artisan list --domain=site1.com
Der Befehl verwendet die entsprechenden Domäneneinstellungen.
Die Handwerkerbefehle queue:work
und queue:listen
wurden aktualisiert, um eine neue domain
zu akzeptieren.
php artisan queue:work --domain=site1.com
Wie üblich verwendet der obige Befehl die entsprechenden Domäneneinstellungen.
Denken Sie daran, dass Sie, wenn Sie beispielsweise den database
verwenden und zwei Domänen haben, die sich dieselbe Datenbank teilen, zwei unterschiedliche Warteschlangen verwenden sollten, wenn Sie die Jobs jeder Domäne separat verwalten möchten.
Sie könnten zum Beispiel:
QUEUE_DEFAULT=default1
für site1.com und QUEUE_DEFAULT=default2
für site2.comqueue.php
, indem Sie die Standardwarteschlange entsprechend ändern: 'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => env('QUEUE_DEFAULT','default'),
'retry_after' => 90,
],
php artisan queue:work --domain=site1.com --queue=default1
Und
php artisan queue:work --domain=site1.com --queue=default2
Dasselbe kann natürlich auch für jeden anderen Warteschlangentreiber durchgeführt werden, mit Ausnahme des sync
.
storage:link
Befehl Wenn Sie den Befehl storage:link
verwenden und für jede Domäne einen eigenen symbolischen Link wünschen, müssen Sie diese manuell erstellen, da ein solcher Befehl bisher immer einen Link mit dem Namen storage
erstellt und dieser Name im Befehl fest codiert ist. Die Erweiterung des Befehls storage:link
die die Auswahl des Namens ermöglicht, liegt außerhalb des Rahmens dieses Pakets (und ich hoffe, dass dies direkt in zukünftigen Versionen von Laravel erfolgen wird).
Eine Möglichkeit, mehrere Speicherlinks zu erhalten, könnte wie folgt aussehen. Nehmen wir an, wir haben zwei Domänen, nämlich site1.com
und site2.com
mit den zugehörigen Speicherordnern storage/site1_com
und storage/site2_com
.
ln -s storage/site1_com/app/public public/storage-site1_com
ln -s storage/site2_com/app/public public/storage-site2_com
.env.site1.com
und .env.site2.com
fügen wir einen Eintrag hinzu, z. B. für die erste Domain: APP_PUBLIC_STORAGE=-site1_com
filesystems.php
ändern wir Folgendes: 'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage'.env('APP_PUBLIC_STORAGE'),
'visibility' => 'public',
],
Wenn Sie das Paket außerdem in einer Single Page Application (SPA)-Einstellung verwenden, können Sie unterschiedliche öffentliche Ressourcen für jede Domain besser über .htaccess oder ähnliche Lösungen verwalten, wie Scaenicus in seiner .htaccess-Lösung dargelegt hat.
Ab Version 1.1.11 wurde dem Anwendungskonstruktor ein zweites Argument hinzugefügt, um den Ordner auszuwählen, in dem die Umgebungsdateien abgelegt werden sollen: Wenn Sie Dutzende von Domänen haben, ist es nicht sehr angenehm, Umgebungsdateien in der Root-App von Laravel zu haben Ordner.
Wenn Sie also einen anderen Ordner verwenden möchten, fügen Sie ihn einfach ganz oben in der Datei bootstrap/app.php
hinzu. Wenn Sie beispielsweise Umgebungsdateien zum Unterordner envs
hinzufügen möchten, gehen Sie einfach wie folgt vor:
//use Illuminate F oundation A pplication ;
use Gecche Multidomain Foundation Application ;
use Illuminate Foundation Configuration Exceptions ;
use Illuminate Foundation Configuration Middleware ;
$ environmentPath = dirname ( __DIR__ ) . DIRECTORY_SEPARATOR . ' envs ' ;
$ domainParams = [];
return Application:: configure (basePath: dirname ( __DIR__ ),
environmentPath: $ environmentPath ,
domainParams: $ domainParams )
-> withRouting (
web: __DIR__ . ' /../routes/web.php ' ,
commands: __DIR__ . ' /../routes/console.php ' ,
health: ' /up ' ,
)
-> withMiddleware ( function ( Middleware $ middleware ) {
//
})
-> withExceptions ( function ( Exceptions $ exceptions ) {
//
})-> create ();
Wenn Sie das zweite Argument nicht angeben, wird der Standardordner angenommen. Bitte beachten Sie, dass bei Angabe eines Ordners auch die Standard .env
Datei darin abgelegt werden muss
Wenn Sie versuchen, eine Webseite oder einen Shell-Befehl unter einer bestimmten Domäne auszuführen, z. B. sub1.site1.com
, und es keine spezifische Umgebungsdatei für diese Domäne gibt, z. B. die Datei .env.sub1.site1.com
nicht existiert, wird die Das Paket verwendet die erste verfügbare Umgebungsdatei, indem es den Domänennamen durch Punkte aufteilt. In diesem Beispiel sucht das Paket nach der ersten Umgebungsdatei unter den folgenden:
.env.site1.com
.env.com
.env
Die gleiche Logik gilt auch für den Speicherordner.
Wenn Sie in Ihrer Einstellung den Scheduler von Laravel verwenden, denken Sie daran, dass auch der Befehl schedule:run
mit der Domain-Option gestartet werden muss. Daher müssen Sie für jede Domäne einen Planer starten. Zunächst könnte man denken, dass eine Scheduler-Instanz die für jede Domäne gestarteten Befehle verarbeiten sollte, aber der Scheduler selbst wird in einer Laravel-Anwendung ausgeführt, sodass die „Umgebung“, unter der er ausgeführt wird, automatisch auf jeden geplanten Befehl angewendet wird und die --domain
-Option hat überhaupt keine Auswirkung.
Das Gleiche gilt für externe Tools wie Supervisor: Wenn Sie Supervisor für handwerkliche Befehle verwenden, z. B. den Befehl queue:work
, stellen Sie bitte sicher, dass Sie für jede Domäne, die Sie bearbeiten möchten, einen Befehl vorbereiten.
Aus den oben genannten Gründen gibt es einige Fälle, in denen das Paket nicht funktionieren kann: in den Einstellungen, in denen Sie nicht die Möglichkeit haben, beispielsweise die Supervisor-Konfiguration anstelle der crontab
Einträge für den Scheduler zu ändern. Auf ein solches Beispiel wurde hier hingewiesen, bei dem eine Docker-Instanz verwendet wurde.
Beachten Sie schließlich, dass einige Laravel-Befehle andere Artisan-Befehle von innen aufrufen, offensichtlich ohne die Option --domain
. Die obige Situation funktioniert nicht ordnungsgemäß, da der Unterbefehl mit der Standardumgebungsdatei funktioniert. Ein Beispiel ist der Befehl migrate
bei Verwendung der Option --seed
.