How to migrate WordPress from one hosting provider to another.
- Assumes hosting provider provides cPanel and shell access to hosting server
Some takeaways:
- cPanel is a powerful administrative control panel that hosting providers provide to their customers, providing excellent tools for individuals, businesses, and organizations to administer and maintain an online presence.
- cPanel is kind of like David to the Goliath of Big (and evil) Tech
- the regime isn’t happy when you use these tools. They want the Internet to essentially be a big TV network that they have full control over
- fuck the traitorous system pigs (I just had to say that 😀)
- wp-cli is an excellent, powerful tool that can help every WordPress administrator
- So is acme.sh
- Set up DNS records with your DNS provider
temp domain, e.g. d1.example.org
real domain, e.g. example.org
- Create A record pointing to temp domain at new server’s IP address
- Should be A record pointing to real domain at old server’s IP address
- Both records must exist in order for the media transfer to complete when importing the site.
When this process is finished, to go *live* with the new site, switch the A record for the real domain to point to the new server (see last step)
-
If necessary remove existing WP installation of the site via Softalicious WP manager on the new server (through cPanel)
-
Set up domains in cPanel on new server
need temp domain and real domain, both point to same directory
cPanel > Domains
should look like this:
DOMAIN DIRECTORY
d1.example.org /example.org
example.org /example.org
- Create database and database user
cPanel > MySQL Database Wizard > set up new databases
Grant all privileges to the user
Be sure to save the info
- Set database character set and collation
- If this is not set then certain characters and emojis will not display
- This is done *before* the WordPress tables are created
mysql -u <user> -p'<password>' <database>
ALTER DATABASE <database> CHARACTER SET = 'utf8mb4';
ALTER DATABASE <database> COLLATE = 'utf8mb4_unicode_ci';
- SSL
- need to create a cert for the real domain and one for the temp domain
- If server doesn’t support Let’s Encrypt certificates use acme.sh
- acme.sh is a powerful tool to provide SSL certs for your domains
- can do similar things to
certbot
command but doesn’t require root privileges on server - https://github.com/acmesh-official/acme.sh/wiki/Simple-guide-to-add-TLS-cert-to-cpanel
- Save the command you run, such as the example below. If you need to append or remove domains edit the command and re-run it.
- don’t forget to
--deploy
after appending domainsacme.sh --issue -d example.org -w ~/example.org -d www.example.org -w ~/example.org -d mail.example.org -w ~/example.org -d d1.example.org -w ~/example.org acme.sh --deploy --deploy-hook cpanel_uapi --domain example.org
- Install WP
Make sure to create an alias for the site in the wp-cli config.yml
@example:
path: /home/user/example.org
Install and setup Worepress to the temp domain:
wp-cli.phar @example core download
wp-cli.phar @example config create --force --dbname=<database> --dbuser=<db user> --dbpass='<password>' --dbcharset=utf8mb4 --dbcollate=utf8mb4_unicode_ci --locale=en_US
wp-cli.phar @example core install --url='https://d1.example.org' --title='Example site' --admin_user='<admin user>' --admin_password='<admin password>' --admin_email='<admin email>'
- Change tables to InnoDB
Get the database table prefix:
wp-cli.phar @example db prefix
List info including engine type for WordPress tables (insert the prefix near the end of this command):
SELECT TABLE_NAME, TABLE_TYPE, ENGINE, CCSA.character_set_name, COLLATION_NAME FROM information_schema.`TABLES` T,information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA WHERE CCSA.collation_name = T.table_collation AND T.table_name LIKE '<db prefix>%';
This is my own script to convert the tables to InnoDB:
db-set-engine-innodb @site1
Here is the script:
#!/bin/bash -e
if [[ $# -ne 1 ]]; then
echo "USAGE: $(basename "$0") <host alias>)"
exit 0
fi
hostAlias="$1"
if ! wp-cli.phar cli alias list | grep -q ${hostAlias}; then
echo "$hostAlias is not a valid host alias. Exiting."
exit 1
fi
tables=($(wp-cli.phar $hostAlias db query "SHOW TABLE STATUS WHERE Engine = 'MyISAM'" --silent --skip-column-names | awk '{ print $1}'))
if [[ ${#tables[@]} -eq 0 ]]; then
echo "No MyISAM tables found. Exiting."
exit 0
fi
for t in "${tables[@]}"; do
echo "Converting: ${t}"
wp-cli.phar $hostAlias db query "ALTER TABLE ${t} ENGINE=InnoDB"
echo "Done converting ${t}"
done
-
Setup WordPress plugins
wp-cli.phar @site1 plugin install akismet enlighter health-check iframe ninjascanner ... wp-cli.phar @site1 plugin deactivate akismet litespeed-cache w3-total-cache wp-cli.phar @site1 plugin activate enlighter health-check iframe ninjascanner
-
Enable MIME types
- use WP Add Mime Types plugin
Only necessary if you want to upload different files like shell scripts or less documents. Example:
less = text/css
sh = text/sh
- Import
Increase the PHP max file upload size if necessary:
cPanel > Software section > Select PHP Version (opens PHP Selector) > Options tab > upload_max_filesize = 640M
In wp-config.php enable import debugging:
define( 'IMPORT_DEBUG', true );
- Import can safely be run multiple times.
- Review the import log to see if any imports failed.
- Common reasons for failure are characters not supported by the database character set or attachment MIME types that are not allowed.
- The hosting provider’s virus scanner may flag the update .xml as a virus thus blocking import via the WordPress gui importer tool.
If you run the GUI importer in WordPress take note of the user mapping suggestions. If you decide to use wp-cli later to re-do the import these mappings will be useful.
WP > Tools > Import
Or use wp-cli. Read the wp-cli documentation about creating mapping.csv.
Sample mapping.csv:
old_user_login,new_user_login
alex,alex
admin,alex
This maps any posts created by ‘alex’ on the old site to ‘alex’ on the new site. Posts created by ‘admin’ on the old site will also be mapped to ‘alex’ on the new site.
‘alex’ would have to have been created as the admin user in the wp-cli.phar @example core install
step above, or else manually created via the WordPress admin panel prior to running the import.
wp-cli.phar @example import mysite.WordPress.xml --authors=mapping.csv 2>&1 | tee wp-cli-import.log
- Sanitize and review the import log
Check the log to see if any imports failed and why
# convert <br /> in the log to newlines
perl -pi -e 's#<br />#\n#g' wp-cli-import.log
# don't need to see stuff that has already been imported
grep -v 'already exists.' wp-cli-import.log | less
-
Update Site and Home URL
wp-cli.phar @example option update siteurl 'https://example.org' wp-cli.phar @example option get siteurl wp-cli.phar @example option update home 'https://example.org' wp-cli.phar @example option get home
-
Go live
Change the DNS A record for the real domain to point to the new server’s IP address. At this point you can also remove the temp domain DNS record and remove it from cPanel > Domains. You can also remove the cert for the temp domain with the acme.sh command.
- Going further
There is more that needs to be done. For setting up DNS records tools like cloudflare-utils can be useful to quickly delete records from zone files on Cloudflare so that new records can be bulk-imported from cPanel. This is a fast way to get important records like MX, SPF, and DKIM set up.
Leave a Reply
You must be logged in to post a comment.