The idea here is to complete the whole process as quickly as possible and have the minimum downtime to your blog. While we are doing a lot of work on the new blog quite early in this guide you should note that we do not make any changes on the old blog, and we do not change the DNS until right at the end of the process. So, right up until we're ready to change over the blog is up and running on the old hosting. Here is more information on WordPress and the Command Line.
The assumption here is that both the old hosting and the new hosting can be accessed at the same time, although once you have everything from the old hosting you shouldn't need that again. You probably want to keep the old one intact in case you have any issues with the new hosting or transferring the data. This is also assuming that Apache is used on both old and new hosting and that the new hosting is Debian or Ubuntu.
I recently moved four blogs to Digital Ocean hosting with Debian 9 using this method. Please be careful if you follow this guide as some of the steps may be different on different hosting. If I have left out any details or you have any improvements, please let me know.
You only have to do this once per hosting. There is a guide to doing this here.
You do not need to install PHPmyAdmin on the new hosting as that is not used in this guide.
Something like this from the command line...
tar xfz latest.tar.gz
This makes a directory called "wordpress" with all the files inside it. Then, to rename the directory to the name of your website you can do this...
mv wordpress newblog.com
At this point upload the .htaccess and wp-config.php files into the website's root.
Take a look at the .htaccess file and make sure it looks ok. Make sure you always have the original unadulterated .htaccess file backed up somewhere so that if you make any changes to it while troubleshooting, you can always re-add stuff at a later stage once everything is fixed.
Now, you have the latest version of WordPress sat on your new hosting but it will not work because it is not connected to any database. To create a new database you would login to MySQL on the command line and do something like...
create database name_of_new_database;
Now, you've exited from MySQL, so now you can import the SQL file from the command line. Upload the SQL to anywhere you like, perhaps put it with the other WordPress files in the website's root directory. Then, to import the MySQL do something like...
mysql name_of_new_database < /var/www/newblog.com/backup.sql
That should import all the tables. Check that everything is in place by logging in to MySQL and doing something like...
If everything is there, create your blog user with a password and grant access. The easiest/quickest way would be to use the existing username and password from the wp-config.php file, but you can change the username and password here as long as you update the wp-config.php afterwards...
CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON name_of_new_database . * TO 'newuser'@'localhost';
After changing the privileges you'll also want to flush them for them to work...
At this point your blog should still be working on your old hosting, you have not changed anything on the old hosting. On the new hosting the WordPress files are in place and the new database is able to be read by the WordPress files.
Now is as good a time as any to upload the uploads directory, any custom plugins that are not in the WordPress repository and the theme you're using (unless the theme is on the WordPress repository). You can do this later but it's better to do it now before you forget.
This stage has to be done after the blog is connected to the database. Using WP-CLI to re-add the plugins quickly while the website is still working on the old hosting. SFTP or FTP might take a long time, so this is a quick method. If you waited until you switched over the DNS you could login to the admin dashboard and re-add the plugins from there, however, certain plugins might be required to login to the dashboard (e.g. if you're using Cloudflare's flexible SSL) and why wait until then when you can easily get them all added beforehand.
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
Now, once WP-CLI is installed, you can navigate to your blog's root directory on the new hosting if you're not already there. Then have the old hosting open on SFTP/FTP and navigate to the plugins folder. The grab each plugin folder name and do something like this...
wp plugin install wp-plugin-1 wp-plugin-2 wp-plugin-3 wp-plugin-4 wp-plugin-5 --activate
So, instead of "wp-plugin-1", you might have "jetpack", etc. If you are doing this as root you have to use the
--allow-root flag then you should change the owner of all the files to a different user by doing...
chown -R differentuser:differentuser ../newblog.com
If you have not re-uploaded your theme you can also do this using WP-CLI by doing something like...
wp theme install twentysixteen --activate
It's probably a good idea to check everything is owned by differentuser, or just change the owner:group to differentuser after you're finished using WP-CLI.
At this stage, the blog on the old hosting is still working normally. On the new hosting, WordPress should be operational but you haven't changed the DNS over. Hopefully, if the database was copied across correctly and the .htaccess and wp-config.php files are ok you should be able to change over now with the minimum of disruption. However, you may wish to test the blog out on the new hosting to make sure it works before you change the DNS. You can do this if you have a unique IP for your hosting and the website is the default.
To make the new website the default so you can access it with the IP address, go to the sites-available directory and modify the 000-default.conf file...
You may not have to change anything here apart from you want to point the document root to your blog's root to test it out using your unique IP...
Then, to make sure your .htaccess will work you may need to add something like this...
Options Indexes FollowSymLinks MultiViews
Require all granted
allow from all
The default may already be enabled, but if not you would do a...
service apache2 restart
Now, you can find your IP address by running this command...
Copy-paste the IP address into the browser and your blog should be there. Clicking the links of the posts/pages will take you back to your old hosting. To check that the individual post pages work you'll have to modify the URLs so that they look something like http://22.214.171.124/name-of-post in the browser (i.e. swap the domain name with the new IP address).
If everything is working, copy the file and complete if for your new domain...
cp 000-default.conf newblog.com.conf
In addition to the changes we made before, you'll also now want to add your domain name to the virtual host like...
You can also specify a unique error and access file so that you can see exactly what is happening with this one blog if there are any problems.
Now you can save, exit and enable the site...
service apache2 restart
If you're using something like Cloudflare the changeover might be very quick, otherwise you'll have to wait it out. Generally speaking, you'd just create change the A record to the new IP address however, different hosting works different ways.
After your DNS has propagated, the website works fine, and you can login to the admin dashboard and post as normal you should change the permissions of the .htaccess and wp-config.php to 0444.
This method is designed to be as quick as possible. The thing that will take the longest is downloading and uploading the uploads and theme. While this is happening you can either take a break or you can always be working on the other stuff.
If there are any problems with logging into the admin dashboard you can always de-activate the plugins using WP-CLI. To use any WP-CLI commands you must always be in the WordPress site's root directory that you want to work on. The same hosting can have more than one blog, so the location you're in on the command line makes a big difference...
wp plugin deactivate wp-plugin-1
where "wp-plugin-1" is the folder name of a specific plugin that is installed or, to deactivate them all quickly...
wp plugin deactivate --all
If deactivating the plugins does not help, take a look at the access and error logs. If there are any issues highlighted in the logs you can see which file(s) they are related to and then take another look at the .htaccess. The main things to check if there are problems... permissions, owners, .htaccess, plugins, wp-config.php.
After making changes to the .htaccess or plugins you may need to clear your cache to see whether the changes have worked. You may also need to purge everything if you are using a CDN like CloudFlare.
Some plugins need to write to your hosting, so if there are any problems with this you'll get errors, especially if a plugin wants to write to your .htaccess file after you've changed it to 0444. You may have to change the permissions on the .htaccess back to 0755 briefly, then change them back to 0444 afterward. Other plugins may have different problems writing to the uploads directory so making sure that everything is owned by www-data should fix this. Alternatively, it's probably a better idea not to have everything owned by www-data so giving your non-root user ownership of everything will mean that you can update everything with WP-CLI, then you'll have to tweak the uploads folder if you wish to upload using the admin dashboard.
Always consider security with WordPress blogs, especially where there is more than one blog on the same hosting.
I chose Digital Ocean because they were recommended to me. They seem good so far, if you'd like to try them too you can click the link to get $10 free credit with Digital Ocean.