Migrate WordPress sites directly from WHM server to GitHub repositories without local downloads.
Overview
This process will:
- Inventory all WordPress installations on precisewebhosting.com.au
- Create private GitHub repos for each site
- Export MySQL databases on the server
- Push everything directly from server → GitHub (no local storage needed)
Prerequisites
1. GitHub Personal Access Token
Create a token with repo permissions:
- Go to: https://github.com/settings/tokens/new
- Token name: WordPress Migration
- Select scopes:
- ✅ repo (all sub-options)
- ✅ delete_repo (optional, for cleanup)
- Generate token
- Add to .env:
GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2. SSH Access
Already configured:
3. WHM API Token
Already configured in .env:
- WHM_TOKEN=Z7Q6MQKO3ULQ0W8UAIP9DLWTWLJZQ1YI
Step-by-Step Process
Step 1: Inventory WordPress Sites
Scan the server for all WordPress installations:
cd /home/cw/Documents/IBG_HUB/rmm-psa-backend
./migration-scripts/inventory_wordpress_sites.sh
What it does:
Output example:
[
{
"username": "precise01",
"path": "/home/precise01/public_html",
"location": "public_html",
"version": "6.4.2",
"site_url": "https://example.com",
"size": "850M",
"multisite": false,
"database": {
"db_name": "precise01_wp",
"db_user": "precise01_user",
"db_password": "...",
"db_host": "localhost",
"table_prefix": "wp_"
}
}
]
Step 2: Review Inventory
cat exports/wordpress-inventory/wordpress_sites.json | jq
Check:
- Site URLs are correct
- Database credentials present
- Exclude any test/dev sites
Step 3: Migrate to GitHub
Run the migration (pushes directly from server):
./migration-scripts/migrate_wordpress_to_github.sh
What it does for EACH site:
- Creates GitHub repo: Independent-Business-Group/wordpress-[domain]
- Example: wordpress-example-com
- Private repository
- Auto-generated description
- On the server (via SSH):
- Exports MySQL database → database.sql
- Creates .gitignore (excludes wp-config.php, cache, logs)
- Creates README.md with migration notes
- Creates wp-config-template.php (environment variable version)
- Initializes git repository
- Commits all files
- Pushes to GitHub main branch
- Cleans up .git folder (resets for future runs)
- Logs results:
- Success/failure per site
- Saves to: exports/wordpress-migration/migration_log.jsonl
Progress output:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🌐 Migrating: https://example.com
Repo: wordpress-example-com
Path: /home/precise01/public_html
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Creating GitHub repo: Independent-Business-Group/wordpress-example-com
✅ Repo created successfully
📤 Pushing to GitHub from server...
🗄️ Exporting database...
✅ Database exported (database.sql)
✅ Created .gitignore
✅ Created README.md
✅ Created wp-config-template.php
🔧 Initializing git repository...
📦 Adding files to git...
🚀 Pushing to GitHub...
✅ Push complete!
✅ Successfully migrated https://example.com
What Gets Pushed to GitHub
Each repo contains:
wordpress-example-com/
├── wp-admin/
├── wp-content/
│ ├── plugins/
│ ├── themes/
│ └── uploads/ # All media files
├── wp-includes/
├── database.sql # Full MySQL dump
├── wp-config-template.php # Environment variable version
├── .gitignore
├── README.md
└── index.php
Excluded (via .gitignore):
- wp-config.php (sensitive credentials)
- .htaccess (server-specific)
- Cache directories
- Log files
Repository Naming Convention
Format: wordpress-[sanitized-domain]
Examples:
Troubleshooting
Database Export Fails
If database export fails:
# SSH into server and test manually:
ssh -i ~/PreciseITServices.pem centos@precisewebhosting.com.au
# Test mysqldump:
mysqldump -h localhost -u dbuser -p dbname > test.sql
Git Push Fails
Check GitHub token permissions:
- Token must have repo scope
- Token must be valid (not expired)
- Organization must allow token access
Site URLs Unknown
If site_url is "unknown", the database connection failed. Check:
- Database credentials in wp-config.php
- MySQL server is running
- User has SELECT permissions
Next Steps After Migration
1. Link Domains to Customers
Update the RMM+PSA database:
UPDATE domains
SET github_repo = 'Independent-Business-Group/wordpress-example-com'
WHERE domain_name = 'example.com';
2. Deploy to DigitalOcean
For each repository:
- Create DigitalOcean MySQL database
- Import database.sql
- Create App Platform app from GitHub repo
- Configure environment variables:
DB_NAME=wordpress_db
DB_USER=doadmin
DB_PASSWORD=...
DB_HOST=db-mysql-...ondigitalocean.com
WP_HOME=https://example.com
WP_SITEURL=https://example.com
- Point domain DNS to App Platform
3. Update wp-config.php
The wp-config-template.php uses environment variables:
define('DB_NAME', getenv('DB_NAME'));
define('DB_USER', getenv('DB_USER'));
define('DB_PASSWORD', getenv('DB_PASSWORD'));
define('DB_HOST', getenv('DB_HOST'));
Rename to wp-config.php after deployment.
Migration Status
Track progress:
# View summary
cat exports/wordpress-migration/migration_log.jsonl | jq -s '
{
total: length,
success: [.[] | select(.status == "success")] | length,
failed: [.[] | select(.status == "failed")] | length
}'
# List successful migrations
cat exports/wordpress-migration/migration_log.jsonl | jq -r 'select(.status == "success") | .site_url'
# List failures
cat exports/wordpress-migration/migration_log.jsonl | jq -r 'select(.status == "failed") | .site_url'
Cleanup
After verifying all sites migrated successfully:
- On GitHub: Repos are private and safe
- On Server: WordPress files remain unchanged (git folders cleaned)
- Local: Only JSON inventory files created (~few KB)
Estimated Time
- Inventory scan: ~2-5 minutes (depends on server)
- Per site migration: ~1-3 minutes (depends on size)
- 71 sites total: ~2-4 hours
The migration runs unattended - start it and check back later!
Security Notes
- ✅ All repos are private
- ✅ wp-config.php excluded from git
- ✅ Database passwords not in git history
- ✅ GitHub token not logged in output
- ⚠️ database.sql contains all data (keep repos private!)
- ⚠️ Don't commit wp-config.php changes directly
Support
Issues? Check:
- exports/wordpress-migration/migration_log.jsonl for errors
- SSH connection: ssh -i ~/PreciseITServices.pem centos@precisewebhosting.com.au
- GitHub token: verify scopes at https://github.com/settings/tokens
- WHM access: curl -k -H "Authorization: whm $WHM_TOKEN" "https://precisewebhosting.com.au:2087/json-api/listaccts"