One-command WordPress migration between servers using SSH, rsync, and WP-CLI.
| 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 |
Track how many migrations have been run and sites moved using wpclone.
| Metric | Badge |
|---|---|
| Total migrations run | |
| Open issues / bug reports | |
| Closed (resolved) issues | |
| Stars (people using it) |
π¬ Ran a successful migration? Tell us about it in Discussions! If the "new discussion" page returns 404, see the troubleshooting guide: docs/troubleshooting.md.
The main documentation is built with FumaDocs and is fully featured and interactive.
π Visit the documentation: https://vexxo-dev.github.io/wpclone_cli/
- Source code for docs:
docs-fumadocs/
bashβ₯ 4.0sshrsyncscp
sshaccesswp-cli(recommended) ormysqldump
sshaccesswp-cli(recommended) ormysql- A working WordPress installation with
wp-config.phpalready in place
Tip: No extra packages needed beyond what's standard on any Linux server.
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# 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./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.comwpclone [OPTIONS]
wpclone --config <file>
| 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 |
| 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 |
| Variable | Description |
|---|---|
WPCLONE_DEBUG=1 |
Enable debug output |
WPCLONE_LOG=<path> |
Override log file location |
Copy migration.conf.example to migration.conf, fill in your values, and run:
./wpclone --config migration.confConfig 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./wpclone --config production.conf./wpclone --config production.conf --new-url https://staging.example.com./wpclone --config production.conf --skip-db./wpclone --config production.conf --skip-files./wpclone --config production.conf --dry-run./wpclone --config production.conf \
--exclude wp-content/uploads/videos \
--exclude wp-content/uploads/2020βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 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 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- SSH
BatchMode=yesis used β no interactive password prompts. Use SSH keys. wp-config.phpis set tochmod 600on 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).
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.logThen attach debug.log and wpclone.log to your issue.
Quick links:
- π Report a bug
- π‘ Request a feature
- π¬ Start a discussion
Contributions are very welcome! This project is in early development.
- Add support for direct SSH tunnelling (src β dst without local staging)
- Add progress bars using
pvfor 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.
- Direct server-to-server rsync (no local staging required)
-
--backupflag β snapshot destination before overwriting - Interactive TUI mode
- Slack/webhook notifications
- BATS test suite
-
brew install/apt installpackaging - Docker image for environments without rsync/ssh
MIT Β© 2026 β See LICENSE for details.