# Deployment Guide for o2switch

Complete guide for deploying KeywordMatcherPro to o2switch Pro hosting.

## Pre-Deployment Checklist

- [ ] o2switch Pro account active
- [ ] SSH access enabled
- [ ] MySQL database created
- [ ] OpenAI API key obtained
- [ ] Jina.ai API key obtained
- [ ] DataForSEO account setup (optional)
- [ ] Subdomain configured: `keywordmatcherpro` at `kodepilot.com`

## Step 1: Prepare Server

### Create Subdomain

1. Log into cPanel
2. Go to **Domains** → **Subdomains**
3. Create subdomain: `keywordmatcherpro.kodepilot.com`
4. Document root: `public_html/kodepilot.com/keywordmatcherpro/public`

### Create MySQL Database

1. Go to **MySQL Databases**
2. Create database: `kodepilot_kwmp` (or similar)
3. Create user: `kodepilot_kwmp_user`
4. Set strong password
5. Assign user to database with ALL PRIVILEGES
6. Note credentials for `.env` file

## Step 2: Upload Files

### Option A: Via Git (Recommended)

```bash
# SSH into server
ssh username@kodepilot.com

# Navigate to subdomain directory
cd public_html/kodepilot.com
mkdir keywordmatcherpro
cd keywordmatcherpro

# Clone repository (if using Git)
git clone YOUR_REPO_URL .
```

### Option B: Via FTP/File Manager

1. Compress the entire `deploy/` folder as `keywordmatcherpro.zip`
2. Upload via cPanel File Manager to `public_html/kodepilot.com/`
3. Extract the zip file
4. Rename folder to `keywordmatcherpro` if needed

## Step 3: Install Dependencies

```bash
# SSH into the application directory
cd public_html/kodepilot.com/keywordmatcherpro

# Install composer dependencies (production only)
composer install --no-dev --optimize-autoloader

# If composer is not in PATH, use full path
/usr/local/bin/composer install --no-dev --optimize-autoloader
```

## Step 4: Configure Environment

```bash
# Copy environment file
cp .env.example .env

# Edit environment file
nano .env
```

### Essential `.env` Configuration

```env
APP_NAME="KeywordMatcherPro"
APP_ENV=production
APP_DEBUG=false
APP_URL=https://kodepilot.com/keywordmatcherpro

# Database (use credentials from Step 1)
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=kodepilot_kwmp
DB_USERNAME=kodepilot_kwmp_user
DB_PASSWORD=your_secure_password

# Queue
QUEUE_CONNECTION=database

# OpenAI
OPENAI_API_KEY=sk-your-openai-key-here
OPENAI_MODEL=gpt-4o-mini

# Jina.ai
JINA_API_KEY=jina_your-jina-key-here

# DataForSEO (optional)
DATAFORSEO_LOGIN=your_email@example.com
DATAFORSEO_PASSWORD=your_dataforseo_password
DATAFORSEO_ENABLED=false

# Cache durations
JINA_CACHE_DAYS=30
METRICS_CACHE_DAYS=7
```

Save and exit (Ctrl+X, then Y, then Enter).

## Step 5: Application Setup

```bash
# Generate application key
php artisan key:generate

# Run database migrations
php artisan migrate --force

# Cache configuration for better performance
php artisan config:cache
php artisan route:cache

# Create symbolic link for storage
php artisan storage:link
```

## Step 6: Set Permissions

```bash
# Set correct permissions
chmod -R 755 storage
chmod -R 755 bootstrap/cache

# Ensure storage directories exist
mkdir -p storage/app/exports
mkdir -p storage/framework/cache
mkdir -p storage/framework/sessions
mkdir -p storage/framework/views
mkdir -p storage/logs

chmod -R 755 storage/app
```

## Step 7: Configure Cron Job

1. Go to cPanel → **Cron Jobs**
2. Add new cron job:

```cron
* * * * * cd /home/username/public_html/kodepilot.com/keywordmatcherpro && php artisan schedule:run >> /dev/null 2>&1
```

**Replace `username` with your actual cPanel username.**

This runs the Laravel scheduler every minute, which handles:
- Queue processing
- Cache cleanup
- Scheduled maintenance

## Step 8: Configure PHP Settings

If needed, create or edit `.htaccess` in the `public` directory:

```apache
<IfModule mod_php.c>
    php_value upload_max_filesize 10M
    php_value post_max_size 10M
    php_value max_execution_time 300
    php_value memory_limit 512M
</IfModule>
```

## Step 9: Test Installation

### Test 1: Homepage

Visit: `https://kodepilot.com/keywordmatcherpro`

You should see the Laravel welcome page (or your custom homepage).

### Test 2: Database Connection

```bash
php artisan tinker
>>> \DB::connection()->getPdo();
# Should return PDO connection object without errors
```

### Test 3: Queue Worker

```bash
php artisan queue:work --once
# Should run without errors
```

### Test 4: API Connections

Create a test script `test-apis.php` in the root:

```php
<?php
require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';
$app->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap();

echo "Testing Jina API...\n";
$jina = new \App\Services\JinaContentExtractor();
$content = $jina->fetchContent('https://example.com');
echo $content ? "✓ Jina OK\n" : "✗ Jina Failed\n";

echo "\nTesting OpenAI API...\n";
$ai = new \App\Services\AIKeywordExtractor();
$keywords = $ai->extractKeywords('This is test content about SEO tools', 'product');
echo !empty($keywords) ? "✓ OpenAI OK\n" : "✗ OpenAI Failed\n";
```

Run: `php test-apis.php`

## Step 10: Security Hardening

### Protect .env File

Add to `public/.htaccess`:

```apache
<Files .env>
    Order allow,deny
    Deny from all
</Files>
```

### Hide Sensitive Files

Create/edit root `.htaccess`:

```apache
# Protect sensitive files
<FilesMatch "^\.env|composer\.(json|lock)|package(-lock)?\.json">
    Order allow,deny
    Deny from all
</FilesMatch>
```

### Disable Directory Listing

In `public/.htaccess`, ensure:

```apache
Options -Indexes
```

## Monitoring & Maintenance

### Check Logs

```bash
# View latest log entries
tail -f storage/logs/laravel.log

# View queue failures
php artisan queue:failed
```

### Monitor Queue

```bash
# Check queue status
php artisan queue:work --once

# Restart queue processing
php artisan queue:restart
```

### Clear Caches

```bash
# Clear all caches
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
```

### Update Application

```bash
# Pull latest changes
git pull

# Update dependencies
composer install --no-dev --optimize-autoloader

# Run migrations
php artisan migrate --force

# Refresh caches
php artisan config:cache
php artisan route:cache
php artisan view:cache

# Restart queue
php artisan queue:restart
```

## Troubleshooting

### Issue: 500 Internal Server Error

**Solution:**
```bash
# Check logs
tail storage/logs/laravel.log

# Ensure permissions are correct
chmod -R 755 storage bootstrap/cache

# Clear and recache
php artisan config:clear
php artisan cache:clear
```

### Issue: Queue Jobs Not Processing

**Solution:**
```bash
# Verify cron job is running
crontab -l

# Manually run queue worker
php artisan queue:work

# Check for failed jobs
php artisan queue:failed

# Retry failed jobs
php artisan queue:retry all
```

### Issue: Database Connection Error

**Solution:**
- Verify database credentials in `.env`
- Check if database user has proper permissions
- Test connection: `php artisan tinker` → `\DB::connection()->getPdo();`

### Issue: Composer Memory Issues

**Solution:**
```bash
# Increase PHP memory limit
php -d memory_limit=512M /usr/local/bin/composer install --no-dev
```

### Issue: API Rate Limits

**Solution:**
- Check API usage logs: `SELECT * FROM api_usage_logs ORDER BY created_at DESC LIMIT 100;`
- Increase rate limit delays in `.env`:
  ```env
  JINA_RATE_LIMIT_MS=200
  OPENAI_RATE_LIMIT_MS=100
  ```

## Performance Optimization

### Enable OPcache

Ask o2switch support to enable OPcache for your account.

### Database Indexing

Indexes are already created in migrations, but verify:

```sql
SHOW INDEX FROM pages;
SHOW INDEX FROM keyword_recommendations;
```

### Optimize Composer Autoloader

```bash
composer dump-autoload --optimize --no-dev
```

## Backup Strategy

### Database Backup

```bash
# Create backup directory
mkdir -p /home/username/backups

# Backup database
mysqldump -u kodepilot_kwmp_user -p kodepilot_kwmp > ~/backups/kwmp_$(date +%Y%m%d).sql
```

### Application Backup

Via cPanel → **Backup Wizard** → **Full Backup**

Or via command line:
```bash
tar -czf ~/backups/kwmp_$(date +%Y%m%d).tar.gz ~/public_html/kodepilot.com/keywordmatcherpro
```

## Support Resources

- **Laravel Docs**: https://laravel.com/docs/10.x
- **o2switch Support**: https://www.o2switch.fr/support
- **Application Logs**: `storage/logs/laravel.log`
- **API Documentation**: Check `/docs` folder in project

## Post-Deployment Checklist

- [ ] Application accessible via browser
- [ ] Database connection working
- [ ] API keys configured and tested
- [ ] Cron job running (check cPanel)
- [ ] Queue worker processing jobs
- [ ] File permissions correct
- [ ] .env file protected
- [ ] Logs directory writable
- [ ] Storage symlink created
- [ ] Cache optimized
- [ ] Backup strategy in place

---

**Deployment Complete! 🚀**

Your KeywordMatcherPro installation should now be live at:
`https://kodepilot.com/keywordmatcherpro`
