# cPanel ডিপ্লয়মেন্ট গাইড — সিলেট মডেল মাদরাসা ERP

> Last updated: 2026-10-27 (Phase 13)
> Audience: হোস্টিং/ওয়েব অ্যাডমিন
> Note: এখানে কোনো বাস্তব credential নেই। সব মান placeholder।

## ১. শর্ত ও সীমাবদ্ধতা

- cPanel-এ **PHP 8.2+**, MySQL 8.0 (বা MariaDB 10.6+), SSH/Terminal, Cron এবং AutoSSL থাকতে হবে।
- Laravel-এর document root অবশ্যই `public/` হবে। cPanel-এর main domain-এর docroot বদলানো যায়; না গেলে একটি subdomain (যেমন `smm.<school-domain>`) তৈরি করে তার docroot `.../public` দিন।
- SSH/Terminal না থাকলে `php artisan` চালানো যাবে না; সে ক্ষেত্রে VPS বা XAMPP হোস্টিং বেছে নিন।
- `php artisan serve` cPanel-এ চালাবেন না।

## ২. প্রয়োজনীয় PHP এক্সটেনশন

MultiPHP Manager-এ PHP 8.2/8.3 নির্বাচন করে MultiPHP INI Editor-এ:

```ini
extension=fileinfo
extension=gd
extension=intl
extension=mbstring
extension=openssl
extension=pdo_mysql
extension=zip
extension=curl

memory_limit = 256M
upload_max_filesize = 16M
post_max_size = 20M
max_execution_time = 120
```

`php -m` (Terminal) দিয়ে যাচাই করুন। হোস্ট এক্সটেনশন না দিলে সাপোর্টে অনুরোধ করুন; `gd`/`zip` ছাড়া PDF/XLSX এক্সপোর্ট কাজ করবে না।

## ৩. ফাইল স্থাপন

১. cPanel **File Manager**-এ ডিপ্লয়মেন্ট zip (`sylhet-model-madrasah-cpanel-<তারিখ>.zip`) আপলোড করুন `/home/<cpanel-user>/`-এ (public_html-এর ভেতরে নয়)।
   - প্যাকেজে `vendor/` থাকায় আকার ~১১৫ MB; File Manager-এর upload limit কম হলে **FTP/SFTP** দিয়ে zip আপলোড করুন, অথবা SSH থাকলে সরাসরি `unzip` চালান।
২. Extract করুন। ভেতরে একটি টপ-লেভেল ফোল্ডার `sylhet-model-madrasah/` পাবেন; চাইলে rename করুন (যেমন `sylhet-smm`)।
   - প্যাকেজে `vendor/` ও `public/build/` আগেই আছে, তাই Composer/Node ছাড়াও সাইট চালু হবে (তবে PHP সংস্করণ মিলতে হবে)।
   - `.env` ইচ্ছাকৃতভাবে প্যাকেজে নেই; `.env.example` থেকে নতুন করে বানাতে হবে।
   - ব্যাকআপ, লগ, সেশন, ক্যাশ ও শিক্ষার্থীর প্রাইভেট ফাইল প্যাকেজে নেই — এগুলো সার্ভারেই তৈরি হবে।
৩. Document root সেট করুন: **Domains → Manage → Document Root** = `/home/<cpanel-user>/sylhet-model-madrasah/public`।
   - Subdomain ব্যবহার করলে subdomain তৈরি করার সময়ই docroot দিন।
৪. `.env` তৈরি করুন `.env.example` কপি করে (File Manager → Copy → `.env`) এবং নিচের মান বসান।

```dotenv
APP_ENV=production
APP_DEBUG=false
APP_URL=https://smm.<school-domain>
APP_TIMEZONE=Asia/Dhaka

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=<cpanel-user>_smm
DB_USERNAME=<cpanel-user>_smm
DB_PASSWORD=<db-password>

SESSION_DRIVER=database
SESSION_ENCRYPT=true
SESSION_SECURE_COOKIE=true
CACHE_STORE=database
QUEUE_CONNECTION=database

MAIL_MAILER=smtp
MAIL_HOST=mail.<school-domain>
MAIL_PORT=587
MAIL_USERNAME=<mailbox>
MAIL_PASSWORD=<mailbox-password>
MAIL_FROM_ADDRESS="noreply@<school-domain>"

BACKUP_DISK=local
BACKUP_PATH=backups
DB_DUMP_BINARY=/usr/bin/mysqldump
DB_RESTORE_BINARY=/usr/bin/mysql
```

> `APP_KEY` পরে `key:generate` দিয়ে তৈরি হবে; কখনো ডকুমেন্টে লিখবেন না।

৫. অনুমতি:

```bash
cd /home/<cpanel-user>/sylhet-smm
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
chmod -R 775 storage bootstrap/cache
```

(কিছু শেয়ার্ড হোস্টে `775`-এর বদলে `755` লাগতে পারে; `storage/logs/laravel.log` লেখা যাচ্ছে কি না দেখুন।)

৬. `storage:link` **চালাবেন না** — এই অ্যাপের ফাইল ও ব্যাকআপ প্রাইভেট ডিস্কে থাকে; পাবলিক symlink নিরাপত্তা সতর্কতা তৈরি করে।

## ৪. Composer নির্ভরতা

Terminal:

```bash
cd /home/<cpanel-user>/sylhet-smm
composer install --no-dev --optimize-autoloader --no-interaction
```

Composer না থাকলে হোস্ট সাপোর্টে অনুরোধ করুন অথবা একই PHP সংস্করণের স্থানীয় মেশিনে `composer install --no-dev --optimize-autoloader` চালিয়ে `vendor/` ফোল্ডার আপলোড করুন। ভিন্ন PHP সংস্করণের `vendor` ব্যবহার করবেন না।

ফ্রন্টএন্ড asset পরিবর্তন না হলে `public/build` আপলোড করাই যথেষ্ট; পরিবর্তন হলে স্থানীয় মেশিনে `npm ci && npm run build` করে `public/build` আপলোড করুন (হোস্টে Node থাকা লাগবে না)।

## ৫. ডাটাবেস

১. **MySQL Databases**-এ database ও user তৈরি করুন; user-কে সেই database-এ **All Privileges** দিন (মাইগ্রেশনের জন্য প্রয়োজন)।
২. `.env`-এ নাম/পাসওয়ার্ড বসান।
৩. স্কিমা ও রেফারেন্স ডেটা:

```bash
php artisan migrate --force
php artisan db:seed --class=DatabaseSeeder --force
```

`DatabaseSeeder` কেবল সেটিংস, ১০ রোল, ২৬১ পারমিশন, বিভাগ, লেজার অ্যাকাউন্ট ও লাইব্রেরি নীতি সিড করে; **নকল শিক্ষার্থী/লেনদেন নয়**।

৪. পুরোনো ডাটাবেসের ডাম্প আনতে হলে ব্যাকআপ ফাইল decompress করে **phpMyAdmin → Import** করুন (character set `utf8mb4`)। বড় ফাইলের জন্য Terminal:

```bash
gunzip -c storage/app/private/backups/<file>.sql.gz > /tmp/restore.sql
mysql -u <db-user> -p <db-name> < /tmp/restore.sql
rm /tmp/restore.sql
```

পাসওয়ার্ড প্রম্পটে দিন; কমান্ড-লাইনে পাসওয়ার্ড লিখবেন না।

## ৬. প্রথম Super Admin

```bash
cd /home/<cpanel-user>/sylhet-smm
php artisan make:superadmin admin@<school-domain>
```

ইন্টারঅ্যাকটিভ পাসওয়ার্ড চাইবে। Terminal-এ interactive না হলে `--generate` ব্যবহার করুন, পাসওয়ার্ড একবার দেখাবে — সাথে সাথে পাসওয়ার্ড ম্যানেজারে সংরক্ষণ করুন। কোনো ডিফল্ট অ্যাডমিন পাসওয়ার্ড নেই এবং তৈরি করবেন না।

## ৭. ক্যাশ ও যাচাই

```bash
php artisan key:generate
php artisan optimize
php artisan security:check
php artisan backup:create
```

- `https://smm.<school-domain>/up` → 200
- `/` → `/login`
- Super Admin লগইন, Dashboard, Settings → Backups
- `storage/logs/laravel.log` পরিষ্কার

`APP_KEY` একবার তৈরি হলে আর বদলাবেন না; বদলালে সব সেশন বাতিল হবে।

## ৮. HTTPS

- cPanel **SSL/TLS Status → Run AutoSSL**।
- তারপর `.env`-এ `SESSION_SECURE_COOKIE=true` এবং `APP_URL=https://...`।
- `public/.htaccess`-এ HTTP→HTTPS redirect (Apache-এ):

```apache
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
```

(নিশ্চিত করুন হোস্ট reverse proxy ব্যবহার করলে `X-Forwarded-Proto` ঠিকভাবে আসছে; প্রয়োজনে সাপোর্টে জানান।)

## ৯. Cron, Queue ও Scheduler

নিয়ন্ত্রণ প্যানেল → **Cron Jobs**:

```cron
0 2 * * * /usr/local/bin/php /home/<cpanel-user>/sylhet-smm/artisan backup:create >> /home/<cpanel-user>/sylhet-smm/storage/logs/backup-cron.log 2>&1
```

- বর্তমান ফিচারে কোনো scheduled task বা queued job নেই; `queue:work` বা `schedule:run` আবশ্যক নয়।
- ভবিষ্যতে scheduler যোগ হলে প্রতি মিনিটে:
  `* * * * * /usr/local/bin/php /home/<cpanel-user>/sylhet-smm/artisan schedule:run >> /dev/null 2>&1`
- Queue যোগ হলে শেয়ার্ড হোস্টিংয়ে daemon চালানো কঠিন; তখন VPS বিবেচনা করুন।

## ১০. নিরাপত্তা

- cPanel/WHM পাসওয়ার্ড, SSH key ও MySQL পাসওয়ার্ড আলাদা রাখুন; পাসওয়ার্ড ম্যানেজার ব্যবহার করুন।
- Directory listing বন্ধ; `public_html`-এর বাইরে প্রজেক্ট।
- ModSecurity কিছু Livewire POST ব্লক করলে (403/406), হোস্ট সাপোর্টের সাথে domain-ভিত্তিক exception যোগ করুন — WAF সম্পূর্ণ বন্ধ করবেন না।
- Settings → Security-এ idle timeout চালু করুন; Super Admin-দের জন্য আলাদা অ্যাকাউন্ট।
- মাসে অন্তত একবার cPanel **Full Backup** (home + databases) নামিয়ে অফসাইট রাখুন; অ্যাপ-ব্যাকআপ এর বিকল্প নয়, পরিপূরক।
- `php artisan security:check` নিয়মিত চালান; 0 blocking failure থাকতে হবে।

## ১১. আপগ্রেড ও রোলব্যাক

**আপগ্রেড**

১. আগের কোডের zip ও ডাটাবেস ডাম্প সংরক্ষণ।
২. `php artisan down --secret="<token>"`।
৩. নতুন ফাইল আপলোড (`.env` ও `storage/app/private` অক্ষত রাখুন)।
৪. `composer install --no-dev --optimize-autoloader`, `php artisan migrate --force`, `php artisan optimize`।
৫. যাচাই করে `php artisan up`।

**রোলব্যাক**

১. `php artisan down`।
২. আগের কোড ফোল্ডার/zip ফিরিয়ে আনুন; `vendor` ও `public/build` সহ।
৩. ডাটাবেস সমস্যা হলে আগের ডাম্প phpMyAdmin/Terminal দিয়ে রিস্টোর করুন (আগে বর্তমান অবস্থার ডাম্প নিন)।
৪. `php artisan optimize:clear && php artisan optimize`, `/up` ও লগইন যাচাই, `php artisan up`।
৫. `migrate:rollback` কেবল শেষ batch এই ডিপ্লয়ের হলে এবং নতুন ডেটা না লেখা হলে।

## ১২. সমস্যা সমাধান

| লক্ষণ | কারণ | সমাধান |
|---|---|---|
| 500 | `.env` ভুল, APP_KEY নেই, permission | লগ দেখুন, `key:generate`, 775 |
| 404 সব পেজে | docroot `public/` নয় | Domains → Document Root ঠিক করুন |
| CSS বোঝা যাচ্ছে না | `APP_URL`/asset build ভুল | `public/build` আপলোড, `optimize:clear` |
| 419 | session/cookie, HTTPS mismatch | `APP_URL` ও `SESSION_SECURE_COOKIE` মিলান |
| 403 Livewire POST | ModSecurity | হোস্টে exception/whitelist |
| PDF/XLSX ব্যর্থ | `gd`/`zip` নেই বা memory কম | এক্সটেনশন ও `memory_limit` |
| ব্যাকআপ ব্যর্থ | `mysqldump` path/privilege | `DB_DUMP_BINARY` ও DB user privilege |
