Ekstensi untuk menggunakan Laravel dalam pengaturan multi domain
Paket ini memungkinkan satu instalasi Laravel untuk bekerja dengan beberapa domain HTTP.
Ada banyak kasus di mana pelanggan yang berbeda menggunakan aplikasi yang sama dalam hal kode tetapi tidak dalam hal database, penyimpanan, dan konfigurasi.
Paket ini memberikan cara yang sangat sederhana untuk mendapatkan file env tertentu, jalur penyimpanan tertentu, dan database spesifik untuk setiap pelanggan tersebut.
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 |
Rilis v1.1.x:
Hingga saat ini, rilis v1.1.6+, v1.2.x, v1.3.x, v1.4.x, v2.x, dan v3.x secara fungsional setara. Rilis telah dipisahkan untuk menjalankan tes integrasi dengan versi kerangka Laravel yang sesuai.
Namun, dengan dirilisnya Laravel 8, rilis v1.1.14, v1.2.8, v1.3.8 dan v1.4.8 adalah rilis terakhir termasuk fitur baru untuk versi Laravel 5.x yang sesuai (dukungan perbaikan bug masih aktif untuk versi tersebut) . PEMBARUAN 13-02-2021 : beberapa fitur terakhir untuk rilis v1.1+ masih berlangsung :)
v1.0 memerlukan Laravel 5.1, 5.2, 5.3 dan 5.4 (tidak lagi dipertahankan dan tidak diuji dibandingkan laravel 5.4, namun penggunaan paketnya sama seperti untuk 1.1)
PEMBARUAN 20-02-2023 : Dari Laravel 10.x ke atas, versi paket mengikuti penomoran yang sama.
Tambahkan gecche/laravel-multidomain sebagai persyaratan ke composer.json:
{
"require" : {
"gecche/laravel-multidomain" : "11.*"
}
}
Perbarui paket Anda dengan pembaruan komposer atau instal dengan instalasi komposer.
Anda juga dapat menambahkan paket menggunakan composer require gecche/laravel-multidomain
dan kemudian menentukan versi yang Anda inginkan.
Paket ini perlu mengesampingkan deteksi domain HTTP dalam kumpulan minimal fungsi inti Laravel di awal proses bootstrap untuk mendapatkan file lingkungan tertentu. Jadi paket ini memerlukan beberapa langkah konfigurasi lebih banyak daripada kebanyakan paket Laravel.
Langkah-langkah instalasi:
bootstrap/app.php
. //use Illuminate F oundation A pplication
use Gecche Multidomain Foundation Application
QueueServiceProvider
dengan yang diperluas di file config/app.php
sebagai berikut: ' 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 (),
Harap dicatat bahwa jika Anda mengubah file config/app.php
karena alasan lain, mungkin sudah ada entri providers
di atas dalam file tersebut dan satu-satunya baris penting adalah baris yang menggantikan QueueServiceProvider
.
php artisan vendor:publish
(Paket ini memanfaatkan fitur penemuan.)
Dengan mengikuti langkah-langkah di atas, aplikasi Anda akan mengetahui domain HTTP yang sedang berjalan, baik untuk permintaan HTTP maupun CLI, termasuk dukungan antrean.
CATATAN: di Laravel 11 instalasinya lebih sederhana dari sebelumnya: jika Anda menggunakan Laravel versi sebelumnya, silakan periksa di dokumentasi langkah-langkah instalasinya.
Paket ini kompatibel dengan Horizon, berkat kontribusi komunitas. Jika Anda perlu menggunakan paket ini bersama dengan Horizon Anda harus mengikuti dua langkah instalasi lainnya:
Instal Laravel Horizon seperti biasa
Ganti impor Laravel Horizon di bagian paling atas file app/Providers/HorizonServiceProvider.php.
//use Laravel H orizon H orizonApplicationServiceProvider ;
use Gecche Multidomain Horizon HorizonApplicationServiceProvider ;
Paket ini menambahkan tiga perintah untuk mengelola domain HTTP aplikasi Anda:
domain.add
perintah artisan Perintah utamanya adalah perintah domain:add
yang mengambil argumen nama domain HTTP yang akan ditambahkan ke aplikasi. Misalkan kita memiliki dua domain, site1.com
dan site2.com
, yang berbagi kode yang sama.
Kami cukup melakukan:
php artisan domain:add site1.com
Dan
php artisan domain:add site2.com
Perintah ini membuat dua file lingkungan baru, .env.site1.com
dan .env.site2.com
, di mana Anda dapat meletakkan konfigurasi spesifik untuk setiap situs (misalnya konfigurasi database, konfigurasi cache, dan konfigurasi lainnya, seperti yang biasanya ditemukan di suatu lingkungan mengajukan).
Perintah ini juga menambahkan entri pada kunci domains
di file config/domains.php
.
Selain itu, dua folder baru dibuat, storage/site1_com/
dan storage/site2_com/
. Mereka memiliki struktur folder yang sama dengan penyimpanan utama.
Penyesuaian pada substruktur storage
ini harus disesuaikan dengan nilai di file config/domain.php
.
domain.remove
perintah artisan Perintah domain:remove
menghapus domain HTTP yang ditentukan dari aplikasi dengan menghapus file lingkungannya. Misalnya:
php artisan domain:remove site2.com
Menambahkan opsi force
akan menghapus folder penyimpanan domain.
Perintah ini juga menghapus entri yang sesuai dari kunci domains
di file config/domains.php
.
domain.update_env
Perintah domain:update_env
meneruskan array data yang dikodekan json untuk memperbarui satu atau semua file lingkungan. Nilai-nilai ini akan ditambahkan di akhir .env yang sesuai.
Perbarui satu file lingkungan domain dengan menambahkan argumen domain
.
Jika argumen domain
tidak ada, perintah akan memperbarui semua file lingkungan, termasuk file .env
standar.
Daftar domain yang akan diperbarui disimpan di file konfigurasi domain.php
.
Misalnya:
php artisan domain:update_env --domain_values='{"TOM_DRIVER":"TOMMY"}'
akan menambahkan baris TOM_DRIVER=TOMMY
ke semua file lingkungan domain.
domain.list
Perintah domain:list
mencantumkan domain yang saat ini diinstal, dengan file .env dan direktori jalur penyimpanannya.
Daftar ini disimpan dalam kunci domains
dari file konfigurasi config/domain.php
.
Daftar ini diperbarui secara otomatis setiap kali perintah domain:add
dan domain:remove
dijalankan.
config:cache
Perintah config:cache artisan dapat digunakan dengan paket ini dengan cara yang sama seperti perintah artisan lainnya.
Perhatikan bahwa perintah ini akan menghasilkan file config.php untuk setiap domain tempat perintah dijalankan. Yaitu perintahnya
php artisan config:cache --domain=site2.com
akan menghasilkan file
config-site2_com.php
Saat run-time, domain HTTP saat ini dipertahankan dalam container laravel dan dapat diakses dengan metode domain()
yang ditambahkan oleh paket ini.
Metode domainList()
tersedia. Ia mengembalikan array asosiatif yang berisi info domain yang diinstal, mirip dengan perintah domain.list
di atas.
Misalnya
[
site1.com => [
'storage_path' => <LARAVEL-STORAGE-PATH>/site1_com,
'env' => '.env.site1.com'
]
]
Untuk setiap permintaan HTTP yang diterima oleh aplikasi, file lingkungan spesifik dimuat dan folder penyimpanan spesifik digunakan.
Jika tidak ada file lingkungan dan/atau folder penyimpanan tertentu yang ditemukan, maka yang standar akan digunakan.
Deteksi domain HTTP yang tepat dilakukan dengan menggunakan variabel PHP $_SERVER['SERVER_NAME']
.
CATATAN PENTING: di beberapa lingkungan eksekusi $_SERVER['SERVER_NAME'] tidak dipakai, jadi paket ini tidak akan berfungsi dengan baik sampai Anda menyesuaikan deteksi domain HTTP seperti dijelaskan di bawah.
Mulai dari rilis 1.1.15, deteksi domain HTTP dapat dikustomisasi dengan meneruskan Closure
sebagai entri domain_detection_function_web
dari argumen domainParams
baru dari konstruktor Application
. Dalam contoh berikut, deteksi domain HTTP bergantung pada $_SERVER['HTTP_HOST']
dan bukan $_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 ();
Untuk membedakan domain, setiap perintah artisan menerima opsi baru: domain
. Misalnya:
php artisan list --domain=site1.com
Perintah tersebut akan menggunakan pengaturan domain yang sesuai.
Perintah artisan queue:work
dan queue:listen
telah diperbarui untuk menerima opsi domain
baru.
php artisan queue:work --domain=site1.com
Seperti biasa, perintah di atas akan menggunakan pengaturan domain yang sesuai.
Ingatlah bahwa jika, misalnya, Anda menggunakan driver database
dan Anda memiliki dua domain yang berbagi db yang sama, Anda harus menggunakan dua antrian berbeda jika Anda ingin mengelola pekerjaan setiap domain secara terpisah.
Misalnya, Anda dapat:
QUEUE_DEFAULT=default1
untuk site1.com dan QUEUE_DEFAULT=default2
untuk site2.comqueue.php
dengan mengubah antrian default: 'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => env('QUEUE_DEFAULT','default'),
'retry_after' => 90,
],
php artisan queue:work --domain=site1.com --queue=default1
Dan
php artisan queue:work --domain=site1.com --queue=default2
Jelasnya, hal yang sama dapat dilakukan untuk setiap driver antrean lainnya, selain driver sync
.
storage:link
Jika Anda menggunakan perintah storage:link
dan menginginkan tautan simbolis yang berbeda untuk setiap domain, Anda harus membuatnya secara manual karena hingga saat ini perintah tersebut selalu membuat tautan bernama storage
dan nama tersebut dikodekan dalam perintah. Memperluas perintah storage:link
yang memungkinkan untuk memilih nama berada di luar cakupan paket ini (dan saya berharap ini akan dilakukan secara langsung di versi Laravel yang akan datang).
Cara untuk mendapatkan banyak tautan penyimpanan adalah sebagai berikut. Misalkan kita memiliki dua domain, yaitu site1.com
dan site2.com
dengan folder penyimpanan terkait storage/site1_com
dan 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
dan .env.site2.com
kami menambahkan entri, misalnya, untuk domain pertama: APP_PUBLIC_STORAGE=-site1_com
filesystems.php
kita ubah sebagai berikut: 'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage'.env('APP_PUBLIC_STORAGE'),
'visibility' => 'public',
],
Selain itu, jika Anda menggunakan paket dalam pengaturan Aplikasi Halaman Tunggal (SPA), Anda dapat menangani sumber daya publik yang berbeda untuk setiap domain dengan lebih baik melalui .htaccess atau solusi serupa seperti yang ditunjukkan oleh Scaenicus dalam solusi .htaccess miliknya.
Mulai dari versi 1.1.11, argumen kedua telah ditambahkan ke konstruktor Aplikasi untuk memilih folder tempat meletakkan file lingkungan: jika Anda memiliki puluhan domain, tidak menyenangkan memiliki file lingkungan di root aplikasi Laravel map.
Jadi, jika Anda ingin menggunakan folder lain cukup tambahkan di bagian paling atas file bootstrap/app.php
. misalnya, jika Anda ingin menambahkan file lingkungan ke subfolder envs
, cukup lakukan:
//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 ();
Jika Anda tidak menentukan argumen kedua, folder standar akan diasumsikan. Harap dicatat bahwa jika Anda menentukan folder, file .env
standar juga harus ditempatkan di dalamnya
Jika Anda mencoba menjalankan halaman web atau perintah shell di bawah domain tertentu, misalnya sub1.site1.com
dan tidak ada file lingkungan khusus untuk domain tersebut, yaitu file .env.sub1.site1.com
tidak ada, maka paket akan menggunakan file lingkungan pertama yang tersedia dengan membagi nama domain dengan titik. Dalam contoh ini, paket mencari file lingkungan pertama di antara yang berikut:
.env.site1.com
.env.com
.env
Logika yang sama juga berlaku untuk folder penyimpanan.
Jika dalam pengaturan Anda menggunakan Penjadwal Laravel, ingatlah bahwa perintah schedule:run
juga harus diluncurkan dengan opsi domain. Oleh karena itu, Anda harus meluncurkan penjadwal untuk setiap domain. Pada awalnya orang mungkin berpikir bahwa satu instance Penjadwal harus menangani perintah yang diluncurkan untuk domain mana pun, namun Penjadwal itu sendiri dijalankan dalam Aplikasi Laravel, sehingga "env" yang menjalankannya, secara otomatis berlaku untuk setiap perintah terjadwal dan --domain
opsi --domain
tidak berpengaruh sama sekali.
Hal yang sama berlaku untuk alat eksternal seperti Supervisor: jika Anda menggunakan Supervisor untuk perintah artisan, misalnya perintah queue:work
, pastikan untuk menyiapkan perintah untuk setiap domain yang ingin Anda tangani.
Karena hal di atas, ada beberapa kasus di mana paket tidak dapat berfungsi: dalam pengaturan di mana Anda tidak memiliki kemungkinan untuk mengubah misalnya konfigurasi supervisor daripada entri crontab
untuk penjadwal. Contoh seperti itu telah ditunjukkan di sini di mana instance Docker telah digunakan.
Terakhir, ketahuilah bahwa beberapa perintah Laravel memanggil perintah Artisan lainnya dari dalam, jelas tanpa opsi --domain
. Situasi di atas tidak berfungsi dengan baik karena subperintah akan bekerja dengan file lingkungan standar. Contohnya adalah perintah migrate
saat menggunakan opsi --seed
.