Use rsync & WP-CLI to painlessly move a WordPress site without plugins

Moving a WordPress site from one domain to another has always been a pain, since WordPress stores hashed information based on the length of the domain name in the database. Not being bound to a single domain name is one of the things that Drupal and Joomla get right and makes it easy for developers to move sites between staging/development and production. It can also be a struggle for WordPress novices.

Many developers quickly discover that you cannot simply change a WordPress site’s domain name from the Settings panel. While there are some free plugins to help, with a little knowledge of the Linux command line and the WP-CLI command line tool it can be done quickly and easily.

Here we will share a quick method of moving a site from one server to another using the Linux command line and WP-CLI. You will need the following:

  • Shell access to the source and destination servers
  • WP-CLI installed on both servers (optional on source)
  • rsync installed on both servers

We assume the following:

  1. You have the site configured on the destination server
  2. You have an empty database configured on the destination server using the same username and password as on the source server.
  3. You have shared SSH keys set up between the servers. If you don’t know what we are talking about here you should probably just hire us to do this for you because you will just end up confused, frustrated and at the bar.
  4. We are migrating from the domain to

Prep the source server:

SSH into the source server and navigate to your WordPress installation directory. If you do not have WP-CLI installed do a MySQL dump of the database and gzip it:

$ mysqldump -uUsername -p [database_name]  | gzip > database_name.sql.gz

Make sure the dump name matches your database name.

If you have WP-CLI installed just run this as an unprivileged user:

$ wp db export

Or as root (not recommended)

# wp db export --allow-root

Then gzip the file:

$ gzip [filename.sql]

Now, get the full path your WordPress installation:

$ pwd

It should print out something like:


Copy it.

On the destination server:

As the root user:

Go to the web root which should be something like /home/sononaco/www/

# cd /home/sononaco/www/

Run this command:

# rsync -avz root@[source_ip]:/home/sononaco/www/ .

Once that is complete gunzip your DB file:

# gunzip database_name.sql.gz

Switch to the unprivileged user and import it:

$ wp db import

If it barks back that the filename can’t be found indicate the filename:

$ wp db import database_name.sql

Next, convert the domain name using this command:

$ wp search-replace --dry-run

You will see a table displaying where in the database and how many changes will occur. To make it so run the command again but omit –dry-run:

$ wp search-replace

Congratulations. That’s it!

Bonus: Permissions

Permissions can be a pain to deal with. Here is a simple approach.

First, find the following:

  • Unix user for FTP (we are assuming “ftpuser”)
  • Unix group for FTP (we are assuming “ftpgroup”)
  • If using nginx: Unix user for PHP (we are assuming “apache”)
  • If using Apache: Unix user for Apache (we are assuming “apache”)

Run the following commands as root or prefix them with “sudo”:

cd to the parent directory of “wordpress”:

# cd ../

(or cd /home/sononaco/sites/ using our example)

Change file ownership of everything:

# chown -R ftp:ftpgroup wordpress

Go into the WordPress directory:

# cd wordpress

Run this to set all files to 644 and folders to 755:

find . -type f -exec chmod 644 {} \;; find .  -type d -exec chmod 755 {} \;

Now you need to let the web/PHP server write to a few folders in wp-content. This may differ for you, if you are running WP Rocket or another caching plugin. These are folders in wp-content which require ownership changes but YMMV:

  • cache
  • infinitewp
  • uploads
  • wp-rocket-config
chown -R apache wp-content/cache wp-content/wp-rocket-config wp-content/uploads

You may also want to make your child theme writable by your SFTP/FTP user (you are using a child theme, right??!) If, like us, you use SFTP/SSH you will have a site user that should own the child theme:

chown -R [username] wp-content/themes/child-theme-name/

That’s it! You have now moved your site and locked down permissions!

Leave a Reply

Your email address will not be published. Required fields are marked *