Skip to content

Pull and push between live sites

Pull and Push copies a whole site to another server over HTTP, with no archive to download or upload and no SSH or FTP. The database and wp-content travel in small pieces, an interrupted pull carries on where it stopped, and a later run fetches only what changed. It is part of the free edition from Migrator 1.5.0.

Pull and push are WP-CLI commands run on the destination: there is no button for them in the browser.

  • Migrator is installed and active on both sites: the one you copy (the source) and the one you copy into (the destination).
  • The destination has WP-CLI.
  • Both sites use the same database table prefix. If they differ, a pull that includes the database stops before it changes anything and tells you which $table_prefix to set in the destination’s wp-config.php.
  • On a multisite network, run the commands as a super admin: add --user=<super admin login>.
  1. On the source, go to Migrator > Pull and Push, tick Let another site pull this one and save. It is off by default.

  2. On the destination, from its WordPress folder, run:

    wp migrator pull https://old-site.example

    The first run prints a key and stops (exit code 4).

  3. On the source’s Pull and Push screen, open Set the token or enrol a key, paste the key and save.

  4. Run the same command on the destination again. The pull starts.

The destination keeps its private key and uses it on every later pull and push to the same source.

A source server without the OpenSSL PHP extension cannot check keys. There, set a connection token on the same screen and add --secret=<token> to every command.

The source answers nothing until a key is enrolled or a token is set. Once it is, whoever holds that key or token can download every file and the whole database of the source, user password hashes included. Treat it like an administrator password, use https, and switch Pull and Push off again when the move is done.

wp migrator pull https://old-site.example

Unless you pass --skip-database, the command asks for confirmation, because the pull replaces the destination’s database.

Option What it does
<url> The source site’s address. Required.
--secret=<token> A connection token set on the source. Only for a source server without the OpenSSL extension; everywhere else, leave it out and use the printed key.
--private-key-path=<file> Use a private key enrolled on the source instead of the stored one.
--insecure Allow a plain http:// source. Anyone on the network path can read the copy, so use it only on a network you control.
--include-host-plugins Also copy the old host’s own platform plugins. By default they are left behind and deactivated, because they rarely work on another host.
--skip-files Pull the database only.
--skip-database Pull wp-content only.
--yes Do not ask for confirmation.

What a pull does, in order:

  1. Checks the source and, when the database is included, compares table prefixes.
  2. On a first pull, checks free disk space. The files are kept twice (a private copy plus wp-content), so it asks for about twice the source’s size and stops before changing anything if the disk is short.
  3. Downloads wp-content and the database into a private folder inside wp-content/migrator-backups. Nothing on the site changes during this step.
  4. Dumps the destination’s current database, then imports the source database and rewrites the source addresses to the destination’s. If the import fails, the dump is put back.
  5. Copies wp-content into place and flushes the object cache.

Run the same command again:

  • after an interruption, the pull carries on where it stopped;
  • after a finished pull, it fetches only what changed on the source since then.
  • WordPress core and wp-config.php on the destination are never touched.
  • Migrator’s own plugin folder (and Migrator Pro’s, if installed) and the migrator-backups folder are never overwritten. Migrator stays active after the import, so the next pull still works.
  • Drop-ins that bind a site to its server are left behind: advanced-cache.php, object-cache.php, db.php, db-error.php, sunrise.php and fatal-error-handler.php.
  • The old host’s platform plugins are left behind and deactivated, unless you pass --include-host-plugins.
  • Files that exist only on the destination are left alone.
wp migrator push https://old-site.example

This sends the destination’s wp-content changes back to the source it was pulled from. Only files that differ from the last pull travel. It accepts --secret, --private-key-path, --insecure and --yes, and asks for confirmation because it overwrites files on the source.

The source must:

  • grant push access to the destination’s key on its Pull and Push screen, under Set the token or enrol a key;
  • have display_errors switched off;
  • have a writable folder beside its web root, on the same disk, where the upload is staged before it is swapped in.

While a push applies its changes, the source shows a maintenance page. If the push stops part way, run it again to finish.

The database is not pushed by this command. A database push works only on a host that serves the transfer API on its own standalone route, which a plugin cannot set up. For such a host, see wp migrator remote db-push --help.

wp migrator remote <command> [<url>] [--<option>=<value>]

Runs a lower-level transfer command against a remote site, for example keygen, files-stats or db-push. Arguments and options pass through unchanged. When you give a remote address, Migrator adds the same --state-dir and --fs-root that pull uses, unless you pass your own. wp migrator remote help lists every command.

wp migrator remote keygen https://old-site.example
wp migrator remote files-stats https://old-site.example