# Bangla News Portal + ePaper CMS - Deployment Guide

## Complete Production Deployment Documentation

### Table of Contents
1. [System Requirements](#system-requirements)
2. [Local Development Setup](#local-development-setup)
3. [cPanel Deployment](#cpanel-deployment)
4. [Database Setup](#database-setup)
5. [Storage & File Permissions](#storage--file-permissions)
6. [Configuration](#configuration)
7. [SSL Setup](#ssl-setup)
8. [Cron Jobs](#cron-jobs)
9. [Performance Optimization](#performance-optimization)
10. [Backup Strategy](#backup-strategy)
11. [Troubleshooting](#troubleshooting)

---

## System Requirements

### Minimum Requirements
- PHP 8.3 or higher
- MySQL 8.0 or MariaDB 10.5+
- Apache 2.4+ with mod_rewrite
- 512MB RAM minimum (1GB recommended)
- 1GB disk space minimum
- SSL Certificate (Let's Encrypt recommended)

### Required PHP Extensions
- BCMath
- Ctype
- Fileinfo
- JSON
- Mbstring
- OpenSSL
- PDO
- Tokenizer
- XML
- cURL
- GD or Imagick (for image processing)
- Zip

### cPanel Requirements
- Shared hosting with SSH access (recommended)
- File Manager access
- phpMyAdmin access
- Cron job access
- Domain with DNS configured

---

## Local Development Setup

### Step 1: Install Dependencies

Open terminal/command prompt in project root:

```bash
composer install
```

### Step 2: Configure Environment

Copy `.env.example` to `.env`:

```bash
cp .env.example .env
```

Edit `.env` file:

```env
APP_NAME="Bangla News Portal"
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8000

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=news_portal
DB_USERNAME=root
DB_PASSWORD=

CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
```

### Step 3: Generate Application Key

```bash
php artisan key:generate
```

### Step 4: Create Database

```sql
CREATE DATABASE news_portal CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```

### Step 5: Run Migrations

```bash
php artisan migrate
```

### Step 6: Create Storage Link

```bash
php artisan storage:link
```

### Step 7: Seed Database (Optional)

```bash
php artisan db:seed
```

This creates:
- Admin user: admin@example.com / password123
- Sample categories
- Sample reporters
- Sample news articles

### Step 8: Start Development Server

```bash
php artisan serve
```

Visit: http://localhost:8000

Admin Panel: http://localhost:8000/admin

---

## cPanel Deployment

### Step 1: Prepare Project for Upload

1. **Remove development files:**
   ```bash
   # Remove vendor directory (will reinstall on server)
   rm -rf vendor/
   
   # Remove node_modules if exists
   rm -rf node_modules/
   
   # Remove .git directory
   rm -rf .git/
   
   # Remove IDE files
   rm -rf .idea/ .vscode/
   ```

2. **Create zip archive:**
   ```bash
   # From project root
   zip -r news-portal.zip . -x "vendor/*" "node_modules/*" ".git/*"
   ```

### Step 2: Upload to cPanel

1. **Login to cPanel**
2. **Open File Manager**
3. **Navigate to public_html** (or your domain's document root)
4. **Upload the zip file**
5. **Extract the zip file**
6. **Move all files to public_html** (if extracted to subfolder)

**IMPORTANT:** The `public` folder content must be in `public_html` root!

### Step 3: Restructure for Shared Hosting

Move files from `public` folder to `public_html`:

```
public_html/
├── index.php          (from public/)
├── .htaccess          (from public/)
├── css/               (from public/)
├── js/                (from public/)
├── uploads/           (create this folder)
├── app/               (Laravel app folder)
├── bootstrap/         (Laravel bootstrap folder)
├── config/            (Laravel config folder)
├── database/          (Laravel database folder)
├── resources/         (Laravel resources folder)
├── routes/            (Laravel routes folder)
├── storage/           (Laravel storage folder)
├── vendor/            (will be created)
├── .env               (configuration file)
├── artisan
└── composer.json
```

### Step 4: Update index.php

Edit `public_html/index.php`:

```php
<?php

use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request;

define('LARAVEL_START', microtime(true));

// Update these paths if needed
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
    require $maintenance;
}

require __DIR__.'/../vendor/autoload.php';

$app = require_once __DIR__.'/../bootstrap/app.php';

$kernel = $app->make(Kernel::class);

$response = $kernel->handle(
    $request = Request::capture()
)->send();

$kernel->terminate($request, $response);
```

### Step 5: Update .htaccess

Ensure `public_html/.htaccess` contains:

```apache
<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Send Requests To Front Controller
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>
```

---

## Database Setup

### Step 1: Create Database in cPanel

1. **Login to cPanel**
2. **Go to MySQL Databases**
3. **Create New Database:**
   - Database Name: `yourusername_newsportal`
4. **Create Database User:**
   - Username: `yourusername_newsuser`
   - Password: (generate strong password)
5. **Add User to Database:**
   - Grant ALL PRIVILEGES

### Step 2: Import Database

**Option A: Using phpMyAdmin**

1. Open phpMyAdmin in cPanel
2. Select your database
3. Click "Import" tab
4. Upload `database.sql` file
5. Click "Go"

**Option B: Using Command Line (SSH)**

```bash
# SSH into server
ssh username@yourdomain.com

# Import database
mysql -u yourusername_newsuser -p yourusername_newsportal < database.sql
```

### Step 3: Run Migrations (Alternative)

If using SSH access:

```bash
cd ~/public_html
php artisan migrate --force
php artisan db:seed --force
```

---

## Storage & File Permissions

### Step 1: Create Required Directories

```bash
# Via SSH or File Manager
mkdir -p storage/app/public
mkdir -p storage/framework/cache
mkdir -p storage/framework/sessions
mkdir -p storage/framework/views
mkdir -p storage/logs
mkdir -p public/uploads
mkdir -p public/uploads/news
mkdir -p public/uploads/photos
mkdir -p public/uploads/videos
mkdir -p public/uploads/epaper
mkdir -p public/uploads/epaper/pages
mkdir -p public/uploads/users
mkdir -p public/uploads/settings
mkdir -p public/uploads/advertisements
```

### Step 2: Set Permissions

**Via SSH:**

```bash
# Set ownership (replace with your username)
chown -R yourusername:yourusername ~/public_html

# Set directory permissions
find ~/public_html -type d -exec chmod 755 {} \;

# Set file permissions
find ~/public_html -type f -exec chmod 644 {} \;

# Storage and bootstrap cache need write access
chmod -R 775 ~/public_html/storage
chmod -R 775 ~/public_html/bootstrap/cache

# Uploads directory
chmod -R 775 ~/public_html/public/uploads
```

**Via cPanel File Manager:**

1. Right-click on `storage` folder → Change Permissions → 775
2. Right-click on `bootstrap/cache` folder → Change Permissions → 775
3. Right-click on `public/uploads` folder → Change Permissions → 775

### Step 3: Create Storage Link

**Via SSH:**

```bash
cd ~/public_html
php artisan storage:link
```

**Manual Method (if no SSH):**

Create symbolic link via cPanel:
1. Go to public folder
2. Create new folder named `storage`
3. Or add to `.htaccess`:

```apache
RewriteRule ^storage/(.*)$ app/storage/app/public/$1 [L]
```

---

## Configuration

### Step 1: Configure .env File

Create `.env` file in project root:

```env
APP_NAME="Bangla News Portal"
APP_ENV=production
APP_KEY=base64:YOUR_APP_KEY_HERE
APP_DEBUG=false
APP_URL=https://yourdomain.com

LOG_CHANNEL=stack
LOG_LEVEL=error

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=yourusername_newsportal
DB_USERNAME=yourusername_newsuser
DB_PASSWORD=your_secure_password

BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

MAIL_MAILER=smtp
MAIL_HOST=smtp.yourdomain.com
MAIL_PORT=465
MAIL_USERNAME=noreply@yourdomain.com
MAIL_PASSWORD=your_mail_password
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS=noreply@yourdomain.com
MAIL_FROM_NAME="${APP_NAME}"
```

### Step 2: Generate App Key

**Via SSH:**

```bash
cd ~/public_html
php artisan key:generate
```

**Manual Method:**

Visit: https://laravel-news.com/key-generator
Generate key and paste in `.env`:

```env
APP_KEY=base64:generated_key_here
```

### Step 3: Cache Configuration

**Via SSH:**

```bash
cd ~/public_html

# Clear old cache
php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear

# Create new cache
php artisan config:cache
php artisan route:cache
php artisan view:cache
```

---

## SSL Setup

### Step 1: Install SSL Certificate

**Option A: Let's Encrypt (Free)**

1. Login to cPanel
2. Go to "SSL/TLS Status" or "Let's Encrypt SSL"
3. Select your domain
4. Click "Run AutoSSL" or "Issue Certificate"

**Option B: Purchase SSL**

1. Purchase SSL certificate from provider
2. Upload certificate via cPanel SSL/TLS manager

### Step 2: Force HTTPS

Add to `.htaccess` (after RewriteEngine On):

```apache
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
```

### Step 3: Update .env

```env
APP_URL=https://yourdomain.com
```

---

## Cron Jobs

### Step 1: Setup Laravel Scheduler

In cPanel, go to "Cron Jobs" and add:

```bash
# Run every minute
* * * * * cd /home/username/public_html && php artisan schedule:run >> /dev/null 2>&1
```

### Step 2: Optional Queue Worker

For background jobs (if using queues):

```bash
# Run queue worker (restart every hour)
0 * * * * cd /home/username/public_html && php artisan queue:restart >> /dev/null 2>&1
```

Or use Supervisor (if available):

```ini
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /home/username/public_html/artisan queue:work --sleep=3 --tries=3
autostart=true
autorestart=true
user=username
numprocs=2
redirect_stderr=true
stdout_logfile=/home/username/public_html/storage/logs/worker.log
```

---

## Performance Optimization

### Step 1: Enable OPcache

In cPanel → Select PHP Version → Options:

```ini
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
```

### Step 2: Enable Gzip Compression

Add to `.htaccess`:

```apache
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json
</IfModule>
```

### Step 3: Browser Caching

Add to `.htaccess`:

```apache
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpg "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
    ExpiresByType application/pdf "access plus 1 month"
    ExpiresByType font/woff2 "access plus 1 year"
</IfModule>
```

### Step 4: Optimize Images

Use tools like:
- TinyPNG (https://tinypng.com)
- ImageOptim
- ShortPixel

### Step 5: Enable Laravel Caching

```bash
php artisan config:cache
php artisan route:cache
php artisan view:cache
```

### Step 6: Database Optimization

```sql
-- Optimize all tables
OPTIMIZE TABLE users;
OPTIMIZE TABLE categories;
OPTIMIZE TABLE news;
OPTIMIZE TABLE photos;
OPTIMIZE TABLE videos;
```

---

## Backup Strategy

### Automatic Database Backup

**Via cPanel:**

1. Go to "Backup" or "Backup Wizard"
2. Setup automated database backups
3. Schedule: Daily
4. Retention: 7 days minimum

**Via Cron Job:**

```bash
# Daily database backup at 2 AM
0 2 * * * mysqldump -u username_dbuser -p'password' username_newsportal | gzip > /home/username/backups/db_backup_$(date +\%Y\%m\%d).sql.gz
```

### File Backup

**Via cPanel:**

1. Go to "Backup Wizard"
2. Select "Full Backup"
3. Schedule: Weekly
4. Store: Remote location (recommended)

**Manual Backup Script:**

```bash
#!/bin/bash
# backup.sh

BACKUP_DIR="/home/username/backups"
DATE=$(date +%Y%m%d_%H%M%S)

# Backup files
tar -czf $BACKUP_DIR/files_$DATE.tar.gz ~/public_html

# Backup database
mysqldump -u username_dbuser -p'password' username_newsportal | gzip > $BACKUP_DIR/db_$DATE.sql.gz

# Keep only last 7 days
find $BACKUP_DIR -type f -mtime +7 -delete
```

---

## Troubleshooting

### Issue: 500 Internal Server Error

**Solution:**

1. Check error logs:
   ```bash
   tail -f ~/public_html/storage/logs/laravel.log
   tail -f /var/log/apache2/error.log
   ```

2. Check file permissions:
   ```bash
   chmod -R 775 storage/
   chmod -R 775 bootstrap/cache/
   ```

3. Clear cache:
   ```bash
   php artisan cache:clear
   php artisan config:clear
   php artisan route:clear
   ```

### Issue: Database Connection Error

**Solution:**

1. Verify `.env` database credentials
2. Check database user privileges in cPanel
3. Ensure database host is `localhost`

### Issue: Storage Link Not Working

**Solution:**

1. Delete existing storage folder in public:
   ```bash
   rm -rf public/storage
   ```

2. Recreate link:
   ```bash
   php artisan storage:link
   ```

### Issue: Images Not Displaying

**Solution:**

1. Check uploads folder permissions:
   ```bash
   chmod -R 775 public/uploads
   ```

2. Verify image paths in database
3. Check `.htaccess` rules

### Issue: Route Not Found (404)

**Solution:**

1. Enable mod_rewrite:
   ```bash
   sudo a2enmod rewrite
   sudo service apache2 restart
   ```

2. Check `.htaccess` exists in public_html
3. Clear route cache:
   ```bash
   php artisan route:clear
   ```

### Issue: Session/Login Problems

**Solution:**

1. Check session permissions:
   ```bash
   chmod -R 775 storage/framework/sessions
   ```

2. Clear session cache:
   ```bash
   php artisan session:clear
   ```

3. Verify `.env` session settings

### Issue: Composer Install Fails

**Solution:**

1. Increase memory limit:
   ```bash
   php -d memory_limit=512M /usr/local/bin/composer install
   ```

2. Or install locally and upload vendor folder

---

## Post-Deployment Checklist

- [ ] .env file configured correctly
- [ ] APP_KEY generated
- [ ] Database imported successfully
- [ ] Storage link created
- [ ] Upload folders created with correct permissions
- [ ] SSL certificate installed
- [ ] HTTPS forced via .htaccess
- [ ] Cron jobs configured
- [ ] Cache cleared and regenerated
- [ ] Error logs checked
- [ ] Admin login working
- [ ] Frontend loading correctly
- [ ] Images displaying properly
- [ ] ePaper viewer working
- [ ] Contact form working
- [ ] Search functionality working

---

## Default Admin Credentials

After running `php artisan db:seed`:

- **Email:** admin@example.com
- **Password:** password123
- **Role:** Super Admin

**IMPORTANT:** Change password immediately after first login!

---

## Support & Maintenance

### Regular Maintenance Tasks

**Daily:**
- Check error logs
- Monitor disk space
- Review visitor statistics

**Weekly:**
- Backup database
- Update news content
- Review user comments

**Monthly:**
- Update Laravel dependencies
- Review security updates
- Optimize database
- Clean old logs

**Quarterly:**
- Full system backup
- Security audit
- Performance review
- SSL certificate renewal

---

## Security Best Practices

1. **Never commit .env file to Git**
2. **Use strong passwords**
3. **Enable 2FA if possible**
4. **Keep Laravel updated**
5. **Regular backups**
6. **Monitor error logs**
7. **Use HTTPS everywhere**
8. **Restrict file permissions**
9. **Validate all inputs**
10. **Use CSRF protection**

---

## Contact & Support

For issues or questions:
- Check Laravel logs: `storage/logs/laravel.log`
- Check Apache logs: via cPanel
- Review this documentation
- Contact hosting provider for server issues

---

**Version:** 1.0.0
**Last Updated:** 2026-06-05
**Laravel Version:** 12.x
**PHP Version:** 8.3+
