গাইড
PHP ও Laravel
Meghly-তে Laravel অ্যাপ্লিকেশন (ওয়েবসাইট, কিউ ওয়ার্কার ও শিডিউলার) এবং যেকোনো সাধারণ PHP সাইট ডিপ্লয় ও পরিচালনার গাইড।
সমর্থিত ভার্সন ও এক্সটেনশন
- PHP 8.5, 8.4, 8.3 এবং 8.2 (PHP 8.2 ব্যবহার করলে প্যানেলে সতর্কবার্তা দেখায়)। আপনার
composer.jsonফাইলেরconfig.platform.phpঅথবাrequire.phpথেকে স্বয়ংক্রিয়ভাবে ভার্সন নির্ধারণ করা হয়। - Laravel 10, 11 ও 12 — প্রজেক্টে
artisanফাইল বাlaravel/frameworkপ্যাকেজ দেখে স্বয়ংক্রিয়ভাবে শনাক্ত করা হয়। - সাধারণ PHP সাইট — প্রজেক্টে
composer.jsonবাindex.phpফাইল থাকলে। যদিpublic/index.phpথাকে তবে ডকুমেন্ট রুট হিসেবেpublicফোল্ডার ব্যবহৃত হয়, অন্যথায় রিপোজিটরির রুট ফোল্ডার ব্যবহৃত হয়। - বিল্ট-ইন এক্সটেনশন:
pdo_mysql,pdo_pgsql,zip,bcmath,opcache-সহ প্রয়োজনীয় সব সাধারণ এক্সটেনশন আগে থেকেই ইনস্টল করা থাকে। এছাড়াcomposer.json-এext-pdo_sqlsrv(বাext-sqlsrv) উল্লেখ থাকলে স্বয়ংক্রিয়ভাবে SQL Server-এর ড্রাইভারও যুক্ত হয়।
Laravel প্রজেক্ট প্রস্তুত করার নিয়ম
১. রিপোজিটরিতে .env ফাইল কমিট করবেন না
প্রোডাকশনের সব কনফিগারেশন প্যানেলের Environment ভেরিয়েবল থেকে আসে এবং Laravel রানটাইমে সরাসরি সেখান থেকেই মানগুলো পড়ে নেয়। Meghly বিল্ডের সময় config:cache চালায় না, ফলে প্যানেলে কোনো ভেরিয়েবল পরিবর্তন করে অ্যাপ রিস্টার্ট দিলেই নতুন মান সাথে সাথে কার্যকর হয়।
২. HTTPS প্রক্সি কনফিগারেশন
অ্যাপটি Meghly-র HTTPS রাউটারের মাধ্যমে চলে। Laravel-কে এই রিভার্স প্রক্সি বিশ্বাস করার নির্দেশ না দিলে সাইটের ভেতরের লিংক ও রিডাইরেক্টগুলো ভুলবশত http:// হয়ে যেতে পারে। এজন্য নিচের কনফিগারেশনটি যুক্ত করুন:
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(at: '*');
})Laravel 10 ব্যবহার করলে app/Http/Middleware/TrustProxies.php ফাইলে protected $proxies = '*'; সেট করুন।
৩. হেলথ চেক (Health Check)
হেলথ চেকের জন্য Meghly /up রাউটে 2xx রেসপন্স আশা করে। Laravel 11 ও 12-তে এই রাউটটি ডিফল্টভাবেই থাকে; তবে Laravel 10 ব্যবহার করলে routes/web.php ফাইলে নিচের লাইনটি যোগ করে নিন:
Route::get('/up', fn () => response('OK'));৪. ফ্রন্টএন্ড বিল্ড (Vite)
প্রজেক্টে package.json ফাইল থাকলে বিল্ড ধাপে স্বয়ংক্রিয়ভাবে npm ci এবং npm run build কমান্ড রান হয় এবং কম্পাইল করা অ্যাসেটগুলো public/build ফোল্ডারে জমা হয়।
প্রয়োজনীয় এনভায়রনমেন্ট ভেরিয়েবল
প্যানেলের Environment সেকশনে অন্তত নিচের ভেরিয়েবলগুলো সেট করুন:
APP_KEY=base64:... # নিজের পিসিতে রান করুন: php artisan key:generate --show
APP_ENV=production
APP_DEBUG=false
APP_URL=https://shop.example.com
LOG_CHANNEL=stderrAPP_KEYএকবার সেট করার পর পরবর্তীতে আর পরিবর্তন করবেন না; এটি পরিবর্তন করলে পূর্বের এনক্রিপ্টেড ডেটা এবং ইউজার সেশন অকার্যকর হয়ে যাবে।LOG_CHANNEL=stderrসেট করলে অ্যাপের সব এরর ও লগ সরাসরি প্যানেলের Logs পেজে দেখা যাবে।
অ্যাপের সাথে ডেটাবেস যুক্ত করলে DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME ও DB_PASSWORD ভেরিয়েবলগুলো স্বয়ংক্রিয়ভাবে যুক্ত হয়ে যায়—তাই config/database.php ফাইলে হাত দেওয়ার প্রয়োজন হয় না। একইভাবে Redis যুক্ত করলে REDIS_HOST, REDIS_PASSWORD এবং REDIS_CLIENT=phpredis স্বয়ংক্রিয়ভাবে সেট হয়।
ইমেইল পাঠানোর জন্য (যেহেতু পোর্ট 25 বন্ধ) SMTP কনফিগারেশন ব্যবহার করুন:
MAIL_MAILER=smtp
MAIL_HOST=<আপনার মেইল সার্ভার>
MAIL_PORT=587
MAIL_USERNAME=...
MAIL_PASSWORD=...Meghly যে প্রসেসগুলো চালায়
| প্রসেস | যা রান হয় |
|---|---|
web | Apache + PHP, পোর্ট 8080, হেলথ চেক পাথ /up |
worker | php artisan queue:work --sleep=3 --tries=3 --max-time=3600 |
scheduler (cron) | প্রতি মিনিটে php artisan schedule:run |
release | প্রতিটি ডিপ্লয়ের আগে php artisan migrate --force |
আপনার অ্যাপে কিউ (Queue) বা ব্যাকগ্রাউন্ড জবের প্রয়োজন না থাকলে Processes পেজ থেকে worker প্রসেসটি বন্ধ রাখতে পারেন। প্রতিটি নতুন ডিপ্লয়ের পর ওয়ার্কার স্বয়ংক্রিয়ভাবে নতুন কোডে আপডেট হয়ে যায়। এছাড়া প্রজেক্টে Laravel Reverb থাকলে অ্যাপের HTTPS ডোমেইনেই সরাসরি WebSocket কাজ করে।
storage ফোল্ডার ও ফাইল আপলোড
Laravel-এর storage/ ডিরেক্টরিটি একটি স্থায়ী ভলিউমের সাথে যুক্ত থাকে—ফলে ইউজারদের আপলোড করা ফাইল, ক্যাশ, সেশন এবং লগ ফাইল নতুন ডিপ্লয়ের পরেও অক্ষত থাকে।
যেহেতু চলমান কন্টেইনারের মূল ফাইল সিস্টেম রিড-অনলি, তাই রানটাইমে php artisan storage:link কমান্ড চালানো যায় না। পাবলিক ফাইল সার্ভ করার জন্য নিচের যেকোনো একটি পদ্ধতি অনুসরণ করুন:
- আপনার নিজের পিসিতে
php artisan storage:link --relativeকমান্ডটি রান করেpublic/storageসিমলিংকটি (symlink) Git রিপোজিটরিতে কমিট করে দিন (উল্লেখ্য, জিপ ফাইল আপলোড করলে সিমলিংক কাজ নাও করতে পারে)। - অথবা ফাইল স্টোরেজের জন্য S3-কম্প্যাটিবল অবজেক্ট স্টোরেজ ব্যবহার করুন (
FILESYSTEM_DISK=s3)।
পুরনো ডেটাবেস ইমপোর্ট করা
আপনার আগের সার্ভার থেকে ডেটাবেস এক্সপোর্ট করে নিন:
mysqldump --single-transaction --routines --triggers --no-tablespaces mydb > mydb.sqlএরপর প্যানেলে Databases → আপনার ডেটাবেস → Import SQL dump অপশনে গিয়ে .sql ফাইলটি আপলোড করুন। ইমপোর্ট প্রক্রিয়াটি সরাসরি আপনার বরাদ্দকৃত ডেটাবেসের ভেতরে রান হয়—তাই ডাম্প ফাইলের ভেতরে অন্য কোনো ডেটাবেসের নাম (যেমন USE other_db;) লেখা থাকলে তা কাজ করবে না।
সচরাচর সমস্যা ও সমাধান
| যে সমস্যা বা এরর দেখছেন | কারণ ও সমাধান |
|---|---|
500 Server Error এবং লগে No application encryption key | প্যানেলের Environment-এ APP_KEY ভেরিয়েবলটি সেট করুন। |
সাইটের লিংক বা রিডাইরেক্ট http:// হয়ে যাচ্ছে / Mixed content এরর | ওপরে দেখানো নিয়ম অনুযায়ী trustProxies(at: '*') যুক্ত করুন এবং APP_URL-এ https:// ব্যবহার করুন। |
| হেলথ চেক ধাপে ডিপ্লয় আটকে যাচ্ছে (Laravel 10) | routes/web.php ফাইলে /up রাউটটি যুক্ত করুন। |
Permission denied … bootstrap/cache | গিট রিপোজিটরিতে bootstrap/cache ফোল্ডারের ভেতরের ফাইল কমিট করবেন না; বিল্ডের সময় এটি স্বয়ংক্রিয়ভাবে তৈরি হয়। |
Release: could not find driver (SQL Server) | প্রজেক্টের composer.json ফাইলে ext-pdo_sqlsrv যুক্ত করুন। |
| Queue-এর জবগুলো রান হচ্ছে না | Processes পেজে worker চালু আছে কি না এবং QUEUE_CONNECTION সঠিক আছে কি না তা যাচাই করুন। |
| Scheduled কাজগুলো সময়মতো চলছে না | Processes পেজে scheduler ক্রন প্রসেসটি চালু আছে কি না তা দেখে নিন। |
আটকে গেছেন?
আমাদের ইঞ্জিনিয়ারদের সাথে সরাসরি কথা বলুন — ফোন বা ইমেইলে, বাংলায়।