Table of Contents

Wordpress Migration

Steps for Migrating Wordpress (WP) from a sub-domain to another sub-domain or main (www) domain. In the explanation and example below we are migrating WP from live1.example.org sub-domain to example.org (or www.example.org) domain. Overall there are 3 items to consider and change for the migration. These are:

Identify Source and Target items/names

On migration from live1 to www, let's list all the items involved and what their new configuration/names would be. When migrating from live1 to www, I am keeping in mind, that in future, we may do more migrations. So I am naming the target components with different names (such as WP Table Prefix as dain1, WP folder as fain1, etc.) so it will be easier to migrate by component (or the entire website) in future to a different sub-domain or even another domain.

This will make it easy to search on items such as dain1, fain1, etc. to easily identify specific items and rename (replace) them for (future) migration. If for example, if we just want to migrate the database to a different prefix, all we need to do is search everywhere for dain1 and make sure it is configured correctly. If we named everything the same (as I had before for live1), then the task gets tedious to not simply search and replace, but also identify individual item types and make sure only the relevant items are changed. For example a mass search and replace of live1 everywhere (database, files, config) will not result in the correct setup as the new folder name may not be the target sub-domain of www.

Backup

As is obvious, backup all of the existing source items - Web server files, MySQL database, Apache config.

Files

Backup files in /www/example.org/sub/live1 where the current website files reside. Your location may be different of course.

# Create a backup directory
mkdir -p /www/example.org/backups/01
# Change to that directory
cd /www/example.org/backups/01
# zip the files with recursive option to backup
zip -r live1.zip /www/example.org/sub/live1

Database

Backup WP database (named wordpress) having tables prefixed with live1_.

Full

The below script backups all tables in the wordpress database. This is good for backups, but not great for migration as we need only the live1 prefix tables for migration. Anyway, it's good to backup the entire database to be sure.

mysqldump --skip-extended-insert --skip-quick -uroot --password=XXXXX wordpress > wp.sql

By Table filter

For the purpose of migration, do a 2nd extract of just the live1_ prefixed tables. The other alternative is to edit the full backup extract above and delete everything but the live1_1 SQLs. However this may be a cleaner/simpler approach (in my opinion). If your database already only has one set of tables, then this step is redundant. Assuming you have other tables mixed in, in the same database, to extract just the tables starting with live1_ in the wordpress database, 1st step would be to get the extract table list. Then use that list as input to extract only the live1 tables. Once we have a script with just the live1 tables we can start tinkering with the script to modify (search & replace) so the database content changes to point to www instead of live1. Assuming (again) your current database table prefix is live1 you can do the following.

Get table list first

We want to first get the list of tables with prefix live1_. So we can use this as input for the second dump command to only extract the live1_ tables.

mysql -uroot --password=XXXX -N information_schema -e "select table_name from tables where table_schema = 'wordpress' and table_name like 'live1_%'" > tables.txt

This will place the list of tables starting with live1_ in the tables.txt file.

Backup for selected tables

Using the above tables.txt as input, run this 2nd command to give you a clean extract of just the tables we need.

mysqldump --skip-extended-insert --skip-quick -uroot --password=XXXX wordpress `cat tables.txt` > wp_live1.sql

Steps to Migrate

Copy WP file

Copy existing live1 WP files (/www/example.org/sub/live1/main) to fain1 target folder (/www/example.org/fain1/main)

cd /www/example.org/fain1/main
cp -r sub/live1 .

Well, if you noticed, we did not even need to take a backup of the current (live1) folder! We are not going to mess with the source anyway and just creating a new folder for the new website. But again, backups are a good thing because one wrong key stroke and you can erase the wrong folder. Same goes for database backup too.

Backup (Copy) SQL file

Save Original to new file just so it's easy to come back to a starting point without having to export the database again, if you mess up the migration.

cp wp_live1.sql wp_dain1.sql

Rename folder in database script

The data inside the WP database has hard-coded references to the folder in which the install was residing. So this 1st step takes care of searching and replacing all of those folder references.

from:
/www/example.org/sub/live1/main

to:
/www/example.org/fain1/main

The command to do that is:

sed -i s#/www/example.org/sub/live1/main#/www/example.org/fain1/main#g wp_dain1.sql

Change subdomain in database script

Rename HTTP prefix subdomain from live1 to (blank or www). Again, the URL to the site is also hard-coded inside WP. So let's replace those as well.

sed -i s#live1.example.org#example.org#g wp_dain1.sql

Note: It may be a good idea to append http to the search and replace options if you http address coincides with your folder address. Although again, this may not be an issue since we already completed the folder adjustment 1st. Do a quick check (search only) to make sure nothing that should not be changed is getting changed.

Database prefix

Rename Database prefix from live1 to dain1. SKIP THIS STEP for an alternative approach. It is here as a more cautious approach to search/replace items in the database script. At this point you should be able to do a plain / full search and replace of all remaining instances of live1 in step below.

sed -i s#^INSERT\ INTO\ \`live1_#INSERT\ INTO\ \`dain1_# wp_dain1.sql
sed -i s#^CREATE\ TABLE\ \`live1_#CREATE\ TABLE\ \`dain1_# wp_dain1.sql
sed -i s#^DROP\ TABLE\ IF\ EXISTS\ \`live1_#DROP\ TABLE\ IF\ EXISTS\ \`dain1_# wp_dain1.sql
sed -i s#^LOCK\ TABLES\ \`live1_#LOCK\ TABLES\ \`dain1_# wp_dain1.sql
sed -i s#40000\ ALTER\ TABLE\ \`live1_#40000\ ALTER\ TABLE\ \`dain1_# wp_dain1.sql
etc.

Update remaining live1 to dain1

Update rest of live1_ to dain1_ in SQL file.

sed -i s/live1_/dain1_/g wp_dain1.sql

Final SQL file check

Search for live1 anywhere else in SQL file to be sure. Note: Search does not include underscore after live1 so it may find hits that are ignorable.

grep live1 wp_dain1.sql

Take note of results and made final edits if required.

Database prefix in config

Update wp-config.php with table prefix dain1 from live1

$table_prefix  = 'dain1_';

Changing Unique Keys and Salts

Also update wp-config.php's KEYs using the https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service link and replace them in config.php. Below is a sample replacement. Please generate your own!

define('AUTH_KEY',         'AS6GbR*uPvXjso&HCq}.gqZ?Z|5:1{|DiD=vv7+3IwshUKw:uafn5JpF?- >}0qm');
define('SECURE_AUTH_KEY',  'd#&lFT)]4+?J}#ocQ`g8+P:o68H?~d]#+qo5%3uI-6irrF%-XOpz`6?IWd*`E@GE');
define('LOGGED_IN_KEY',    '.mWpq^5R28Z#|(<~V7CYVwb}u&-vR)Rv@CTe;0SKrCAJY rdC!@bFtk*a[ [T`z7');
define('NONCE_KEY',        'EK-#+k|HbBf?#)_O P#,A#03:#kKw![GG#z^/Y+0w4?Owiz<g.+t)[JMsB Mu&#z');
define('AUTH_SALT',        'iXL!G!T:G%ss<L9wACbgDGnPO|-d^f{3F,|w6F!a,fz|@er/aX+)RS~t&)-M+g2|');
define('SECURE_AUTH_SALT', 'Io%h|}zz((P$cCq6-ug+W.e-~}eMev}2 sKc7G4jS|z+ d;fEjd~0XdIuqOg6>M2');
define('LOGGED_IN_SALT',   'K@17hA> Idi13%{9pF$SmjB1u:N&N5OsW2~OQ&RSI|>aCpeu0G#)B]G_>4 x|>h7');
define('NONCE_SALT',       ' u}U0wSwoi]ErDQq ncxvY(M+*p*TR7}gk0:Nyfc4n Q8hV<EuglA|S*MW.oRiD[');

Create Tables

Run wp_dain1.sql to create the new set of tables tables on the wordpress database.

 
mysql -uroot --password=XXXXX wordpress < wp_dain1.sql

Apache config

Test

Of course test the migrated website and it's possible few tweaks are required through the Administrative login. Make sure old cookies if any are cleared in your browser.