For small websites
Use the Duplicator plugin in source and destination!
For large websites
First log in to the server console as the root user.
1. Copy files from source to destination
# Files in different servers
rsync -avzP --delete user@host:/path/to/source user@host:/path/to/destination
# Files in same server
rsync -avzP --delete /path/to/source /path/to/destination
The --delete
option will remove anything else from the destination directory. Otherwise clean it up first.
2. Fix files permissions in destination
# Fix ownership of all files and folders
chown -R user:user /home/user/public_html/
# Fix the ownership of the root directory
chown user:nobody /home/user/public_html/
# Fix the rights of the root directory
chmod 750 /home/user/public_html/
3. Dump source database
For small databases use phpMyAdmin export function with the gzip compression enabled.
For larger databases:
# Dump the database to a file
mysqldump db_name >> db_name.sql
4. Import source database to destination database
For small databases use phpMyAdmin import.
For larger databases:
First drop all database tables in destination database from PHPMyAdmin.
Then:
# Enter mysql mode
mysql
# Select the database to use
> use db_name;
# Import the database
> source /path/to/db_name.sql;
# Exit mysql
> exit;
Note
If this is a new site and its database does not exist then you need to create the database and the database user with their password first. Then assign all privileges of the database to the user and then do the aboveĀ
5. Rename destination urls
Only necessary when the url changes.
Use WPCLI for this:
# Become the correct user if not already
su user
# Do the url rename
wp search-replace --precise --all-tables https://old.url https://new.url
Note 1
The wp-config.php
needs to be edited so that the database name, user and password reflect the correct ones.
Note 2
The WordPress .htaccess
rewrite might need some tweaking in the RewriteBase
and RewriteRule
parts if the source was in a subdirectory and the destination isn't or vice versa.
For instance here is the WordPress core part:
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /subdirectory
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /subdirectory/index.php [L]
</IfModule>
# END WordPress
Also search for all instances of the /subdirectory
in it to replace.