Skip to content

About

One-command WordPress migration between servers using SSH, rsync, and WP-CLI.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

7 Commits

Folders and files

Repository files navigation

WPClone β€” WordPress Site Migration Tool

One-command WordPress migration between servers using SSH, rsync, and WP-CLI.

License: MIT Shell Status Contributions Welcome GitHub issues GitHub stars GitHub forks


✨ Features

Feature Details
File Transfer rsync over SSH β€” incremental, resume-safe, fast
Database Export WP-CLI (wp db export) or mysqldump fallback
Database Import WP-CLI (wp db import) or mysql fallback
URL Replacement wp search-replace β€” handles serialized PHP safely
Config File Reusable .conf files for repeatable migrations
Dry Run Preview every step without touching anything
Post-migration Cache flush, rewrite rules, permission hardening
Logging Full log of every operation to wpclone.log

πŸ“Š Community Stats

Track how many migrations have been run and sites moved using wpclone.

Metric Badge
Total migrations run GitHub Discussions
Open issues / bug reports GitHub issues
Closed (resolved) issues GitHub closed issues
Stars (people using it) GitHub stars

πŸ’¬ Ran a successful migration? Tell us about it in Discussions! If the "new discussion" page returns 404, see the troubleshooting guide: docs/troubleshooting.md.


πŸ“¦ Requirements


πŸ“š Documentation

The main documentation is built with FumaDocs and is fully featured and interactive.

πŸ‘‰ Visit the documentation: https://vexxo-dev.github.io/wpclone_cli/

On your local machine (where you run wpclone):

  • bash β‰₯ 4.0
  • ssh
  • rsync
  • scp

On the source server:

  • ssh access
  • wp-cli (recommended) or mysqldump

On the destination server:

  • ssh access
  • wp-cli (recommended) or mysql
  • A working WordPress installation with wp-config.php already in place

Tip: No extra packages needed beyond what's standard on any Linux server.


πŸš€ Quick Start

⚑ One-liner (no cloning required)

Run wpclone directly from GitHub β€” no installation, no git clone:

bash <(curl -fsSL https://raw.githubusercontent.com/Vexxo-Dev/wpclone_cli/main/wpclone.sh) \
  --src-host deploy@old-server.com \
  --src-path /var/www/html \
  --dst-host deploy@new-server.com \
  --dst-path /var/www/html \
  --old-url https://old-site.com \
  --new-url https://new-site.com

Install locally (recommended for repeated use)

# Download and make executable
curl -fsSL https://raw.githubusercontent.com/Vexxo-Dev/wpclone_cli/main/wpclone.sh -o wpclone
chmod +x wpclone

# Optional: install system-wide
sudo mv wpclone /usr/local/bin/wpclone

# Verify
wpclone --version

Run a full migration

./wpclone \
  --src-host deploy@old-server.com \
  --src-path /var/www/html \
  --dst-host deploy@new-server.com \
  --dst-path /var/www/html \
  --old-url https://old-site.com \
  --new-url https://new-site.com

βš™οΈ Usage

wpclone [OPTIONS]
wpclone --config <file>

Required Options

Option Description
--src-host <user@host> SSH string for the source server
--src-path <path> Absolute WP root path on the source
--dst-host <user@host> SSH string for the destination server
--dst-path <path> Absolute WP root path on the destination
--old-url <url> Old site URL (as stored in the WP database)
--new-url <url> New site URL

Optional Flags

Option Description
--config <file> Load options from a config file
--src-port <port> SSH port on source (default: 22)
--dst-port <port> SSH port on destination (default: 22)
--src-key <path> SSH private key for source
--dst-key <path> SSH private key for destination
--db-method <m> wpcli (default) or mysqldump
--exclude <pattern> Rsync exclude pattern (repeatable)
--skip-files Skip rsync transfer (DB only)
--skip-db Skip database migration (files only)
--skip-url-replace Skip search-and-replace after import
--dry-run Simulate without making changes
--verbose Verbose rsync output
--no-color Disable colored output
--version Print version and exit
-h, --help Show help

Environment Variables

Variable Description
WPCLONE_DEBUG=1 Enable debug output
WPCLONE_LOG=<path> Override log file location

πŸ“„ Config File

Copy migration.conf.example to migration.conf, fill in your values, and run:

./wpclone --config migration.conf

Config file format (key=value, comments with #):

SRC_HOST=deploy@old-server.com
SRC_PATH=/var/www/html
DST_HOST=deploy@new-server.com
DST_PATH=/var/www/html
OLD_URL=https://old-site.com
NEW_URL=https://new-site.com
DB_METHOD=wpcli
VERBOSE=0
DRY_RUN=0

🎯 Use Cases

Migrate live β†’ new host

./wpclone --config production.conf

Clone live β†’ staging

./wpclone --config production.conf --new-url https://staging.example.com

Sync files only (e.g. after a code deploy)

./wpclone --config production.conf --skip-db

Restore database only

./wpclone --config production.conf --skip-files

Preview everything before running

./wpclone --config production.conf --dry-run

Exclude large upload folders

./wpclone --config production.conf \
  --exclude wp-content/uploads/videos \
  --exclude wp-content/uploads/2020

πŸ”„ Migration Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                       wpclone                           β”‚
β”‚                                                         β”‚
β”‚  1. Validate args & check deps (local + remote)         β”‚
β”‚                                                         β”‚
β”‚  2. rsync: source β†’ local staging β†’ destination         β”‚
β”‚                                                         β”‚
β”‚  3. Export DB: source (wp db export / mysqldump)        β”‚
β”‚     ↓ scp to local                                      β”‚
β”‚  4. Import DB: scp to destination β†’ wp db import / mysqlβ”‚
β”‚                                                         β”‚
β”‚  5. wp search-replace: old URL β†’ new URL                β”‚
β”‚     (handles serialized PHP safely)                     β”‚
β”‚                                                         β”‚
β”‚  6. Post-migration:                                     β”‚
β”‚     - wp cache flush                                    β”‚
β”‚     - wp rewrite flush                                  β”‚
β”‚     - chmod 755/644, wp-config.php 600                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ›‘οΈ Security Notes

  • SSH BatchMode=yes is used β€” no interactive password prompts. Use SSH keys.
  • wp-config.php is set to chmod 600 on the destination after migration.
  • Database credentials are never written to local disk (only the dump file is, in /tmp).
  • The local staging area is always cleaned up on exit (even on error).

πŸ› Bug Reports & Support

Ran into a problem? Please open a GitHub Issue and include:

Field What to include
OS / environment Local OS, bash version (bash --version)
SSH setup Key auth or password? Direct access or jump host?
WP-CLI available? Run wp --info on both servers
Error message Full output from the terminal
Log file Contents of wpclone.log (redact passwords/IPs if needed)
Command used The exact wpclone command (redact credentials)

Tip

Run with --dry-run and WPCLONE_DEBUG=1 first to capture full output without making any changes:

WPCLONE_DEBUG=1 ./wpclone --config migration.conf --dry-run 2>&1 | tee debug.log

Then attach debug.log and wpclone.log to your issue.

Quick links:


🀝 Contributing

Contributions are very welcome! This project is in early development.

Ways to contribute:

  • Add support for direct SSH tunnelling (src ↔ dst without local staging)
  • Add progress bars using pv for database transfer
  • Add Slack/email notifications on completion
  • Add a rollback mechanism (snapshot before migration)
  • Write tests (BATS framework)
  • Improve Windows/WSL compatibility

Please open an issue before submitting large PRs. See CONTRIBUTING.md for guidelines.


πŸ“‹ Roadmap

  • Direct server-to-server rsync (no local staging required)
  • --backup flag β€” snapshot destination before overwriting
  • Interactive TUI mode
  • Slack/webhook notifications
  • BATS test suite
  • brew install / apt install packaging
  • Docker image for environments without rsync/ssh

πŸ“œ License

MIT Β© 2026 β€” See LICENSE for details.

About

One-command WordPress migration between servers using SSH, rsync, and WP-CLI.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages