# Offline Migration Guide - Step by Step

This guide is designed to be followed **without internet assistance**. Follow each step in order.

---

## PART 1: NEW SERVER PREPARATION

### Step 1: Connect to New Server
```bash
ssh root@vps2.scala4.com
# Password: Sun-Morning-Wind-2026
```

### Step 2: Copy Preparation Script
**From your OLD server** (in a separate terminal or before you go offline):
```bash
scp /var/www/html/wordpress6/wordpress/EP/migration/prepare-new-server.sh root@vps2.scala4.com:/root/
```

### Step 3: Run Preparation Script
**On NEW server:**
```bash
chmod +x /root/prepare-new-server.sh
/root/prepare-new-server.sh
```

**What to expect:**
- Script will take 10-15 minutes
- You'll see progress for each phase
- At one point, it may ask for MySQL admin password (you can press Enter to skip)
- At the end, it will show verification results

**If errors occur:**
- Note the error message
- Check: `journalctl -xe` for details
- Most common issue: Network timeout - just re-run the script

### Step 4: Verify Installation
**On NEW server, run these commands:**

```bash
# Check Apache
systemctl status apache2
# Should show: active (running)

# Check PHP
php8.1 -v
php7.4 -v
php8.1 -m | grep ioncube
# Should show: ioncube

# Check MySQL
systemctl status mariadb
mysql -e "SELECT VERSION();"
# Should show MariaDB version

# Check Git
git --version
# Should show Git version
```

### Step 5: Test PHP Info Page
1. Get server IP: `hostname -I | awk '{print $1}'`
2. Open browser: `http://[SERVER_IP]/info.php`
3. Should show PHP 8.1 information with ionCube loaded
4. **IMPORTANT**: Remove it after testing:
   ```bash
   rm /var/www/html/info.php
   ```

### Step 6: Create MySQL Admin User (Optional but Recommended)
```bash
mysql
```
Then in MySQL prompt:
```sql
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'ChooseASecurePassword123!';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;
```
**Write down the password you choose!**

---

## PART 2: INVENTORY ON OLD SERVER

### Step 7: Run Inventory Scripts on OLD Server
**On OLD server:**
```bash
cd /var/www/html/wordpress6/wordpress/EP/migration

# Run all inventory scripts
./inventory-applications.sh > ../inventory-report.txt
./analyze-databases.sh > ../database-analysis.txt
./find-unused-files.sh > ../unused-files-report.txt

# View results
cat ../inventory-report.txt
cat ../database-analysis.txt
cat ../unused-files-report.txt
```

**Save these reports** - you'll need them for migration planning.

---

## PART 3: COPY MIGRATION TOOLS TO NEW SERVER

### Step 8: Copy Migration Directory
**From OLD server:**
```bash
rsync -avz /var/www/html/wordpress6/wordpress/EP/migration/ root@vps2.scala4.com:/root/migration/
```

This copies all migration scripts and documentation to the new server.

---

## PART 4: START MIGRATION (Priority 1 Applications)

### Step 9: Migrate WHMCS Billing (Priority 1)

#### 9a. Backup on OLD Server
```bash
# Create backup directory
mkdir -p /backup/whmcs-$(date +%Y%m%d)

# Backup files
tar -czf /backup/whmcs-$(date +%Y%m%d)/whmcs-files.tar.gz /var/www/html/billing

# Backup database
mysqldump -u root -p whmcs > /backup/whmcs-$(date +%Y%m%d)/whmcs-database.sql

# Backup Apache config
cp /etc/apache2/sites-available/004-billing.conf /backup/whmcs-$(date +%Y%m%d)/
```

#### 9b. Transfer to NEW Server
```bash
# Create directory on new server
ssh root@vps2.scala4.com "mkdir -p /var/www/html/billing"

# Copy files
rsync -avz --progress /var/www/html/billing/ root@vps2.scala4.com:/var/www/html/billing/

# Copy database backup
scp /backup/whmcs-$(date +%Y%m%d)/whmcs-database.sql root@vps2.scala4.com:/root/

# Copy Apache config
scp /backup/whmcs-$(date +%Y%m%d)/004-billing.conf root@vps2.scala4.com:/root/
```

#### 9c. Setup on NEW Server
```bash
# SSH to new server
ssh root@vps2.scala4.com

# Create database
mysql -u root -p -e "CREATE DATABASE whmcs CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

# Import database
mysql -u root -p whmcs < /root/whmcs-database.sql

# Update configuration.php with new database credentials
nano /var/www/html/billing/configuration.php
# Update: $db_host, $db_username, $db_password, $db_name

# Set permissions
chown -R www-data:www-data /var/www/html/billing
chmod -R 755 /var/www/html/billing

# Copy and adapt Apache config
cp /root/004-billing.conf /etc/apache2/sites-available/004-billing.conf
nano /etc/apache2/sites-available/004-billing.conf
# Update ServerName, DocumentRoot, paths if needed

# Enable site
a2ensite 004-billing.conf
systemctl reload apache2

# Install SSL certificate (if domain is ready)
certbot --apache -d billing.friendlytv.site
```

#### 9d. Test WHMCS
- [ ] Visit: `http://[SERVER_IP]/billing` or domain
- [ ] Login works
- [ ] Database connections work
- [ ] No PHP errors

#### 9e. DNS Cutover (Only after testing!)
- [ ] Update DNS A record to point to new server IP
- [ ] Wait for DNS propagation (5-60 minutes)
- [ ] Test on domain
- [ ] Monitor for 48 hours

---

### Step 10: Migrate Event Registration System (Priority 1)

Follow same pattern as WHMCS:
1. Backup on old server
2. Transfer files and database
3. Setup on new server
4. Test thoroughly
5. DNS cutover

**Databases**: `eventreg`, `eventregdb`  
**Directory**: `/var/www/html/wordpress6/wordpress/EP`

---

### Step 11: Migrate Main WordPress Site (Priority 1)

Same pattern:
1. Backup files and database (`mainsite`)
2. Transfer
3. Setup
4. Update `wp-config.php`
5. Update site URLs in database (if domain changes)
6. Test
7. DNS cutover

---

## PART 5: CONTINUE WITH PRIORITY 2 & 3

After Priority 1 apps are stable, continue with:
- Genealogy/Webtrees
- El Paraiso Systems
- Accounts Receivable
- Other WordPress sites
- YetiForce CRM
- Intranet
- Gym Management

**Use the same pattern for each:**
1. Backup
2. Transfer
3. Setup
4. Test
5. DNS cutover

---

## TROUBLESHOOTING GUIDE

### Apache won't start
```bash
systemctl status apache2
apache2ctl configtest
journalctl -xe
```

### PHP errors
```bash
tail -f /var/log/apache2/error.log
php8.1 -i | grep "Loaded Configuration File"
```

### Database connection fails
```bash
# Test MySQL
mysql -u root -p -e "SHOW DATABASES;"

# Check user permissions
mysql -u root -p -e "SELECT User, Host FROM mysql.user;"

# Check database exists
mysql -u root -p -e "SHOW DATABASES LIKE 'whmcs';"
```

### ionCube not loading
```bash
# Check if installed
php8.1 -m | grep ioncube

# Check file exists
ls -la /usr/lib/php/*/ioncube_loader_lin_*.so

# Reinstall if needed (see prepare-new-server.sh)
```

### Permission errors
```bash
# Fix ownership
chown -R www-data:www-data /var/www/html/[app-name]

# Fix permissions
find /var/www/html/[app-name] -type d -exec chmod 755 {} \;
find /var/www/html/[app-name] -type f -exec chmod 644 {} \;
```

### SSL certificate issues
```bash
# Check certificate
certbot certificates

# Renew if needed
certbot renew

# Test Apache config
apache2ctl configtest
```

---

## IMPORTANT REMINDERS

1. **Always backup before migrating**
2. **Test thoroughly before DNS cutover**
3. **Keep old server running for 48-72 hours after migration**
4. **Document database passwords and credentials**
5. **Update configuration files with new server details**
6. **Check file permissions after transfer**
7. **Monitor error logs after migration**

---

## QUICK REFERENCE

### Old Server IP: [YOUR_OLD_SERVER_IP]
### New Server: vps2.scala4.com
### New Server IP: [GET WITH: ssh root@vps2.scala4.com "hostname -I"]

### Common Commands
```bash
# Check service status
systemctl status [service-name]

# Restart service
systemctl restart [service-name]

# View logs
journalctl -xe
tail -f /var/log/apache2/error.log
tail -f /var/log/mysql/error.log

# Test PHP
php8.1 -v
php8.1 -m

# Test MySQL
mysql -u root -p

# Check disk space
df -h

# Check memory
free -h
```

---

## EMERGENCY ROLLBACK

If something goes wrong:

1. **Revert DNS** to point back to old server
2. **Keep old server running** - it's your backup
3. **Check error logs** on new server
4. **Fix issues** before trying again
5. **Test thoroughly** before next DNS cutover

---

**Good luck with your migration! Take it one application at a time.**

