Skip to content
CH SCShop classwordpress · intermediate · ~60 min · 6 steps

How to copy a live WordPress site to your computer with DDEV

Pull a production WordPress site's database, uploads, and code into DDEV — with the URL rewrites done right — so you can test changes locally.

August 10, 2026 · by Dane Petersen

A local copy is where you test the risky stuff — updates, plugin changes, theme surgery — while live stays untouched. This walks a production WordPress site down into DDEV, URL rewrites and all. You’ll need DDEV installed, WP-CLI on the server for the database export, and SSH access to your host.

Get the code down and configure DDEV

Pull the site’s files into a local folder — git clone if the site is under version control, rsync from the server if not:

rsync -avz --exclude 'wp-content/uploads' you@yourserver:/path/to/site/ ~/Sites/mysite/

We skip uploads for now; that folder is usually gigabytes and gets its own step. Then tell DDEV what it’s looking at:

cd ~/Sites/mysite
ddev config --project-type=wordpress
ddev start

DDEV writes its database credentials into a wp-config-ddev.php it manages itself, so your production wp-config.php values never need touching.

Export and import the database

On the server, export; on your machine, download and import:

ssh you@yourserver "cd /path/to/site && wp db export - | gzip" > live.sql.gz
ddev import-db --file=live.sql.gz

Pull the uploads folder

Now the big folder, straight into place:

rsync -avz you@yourserver:/path/to/site/wp-content/uploads/ wp-content/uploads/

On a huge site, add --exclude '20[0-1]*' or similar to skip old years — missing images break nothing but the images themselves.

Search-replace the URLs

The database is still full of the live URL, so WordPress will try to bounce you back to production. Rewrite it — dry run first, then for real:

ddev wp search-replace 'https://www.yoursite.com' 'https://mysite.ddev.site' --all-tables --dry-run
ddev wp search-replace 'https://www.yoursite.com' 'https://mysite.ddev.site' --all-tables

The --all-tables flag matters: plugins stash URLs in their own tables, and the default scope misses them. If the live site answers on both www and bare domain, run the replace for both forms.

Neutralize the plugins that phone home

A copy of live still thinks it’s live. Switch off the plugins that talk to the outside world — caching, security scanners, backup schedulers, SMTP mailers:

ddev wp plugin list --status=active
ddev wp plugin deactivate wp-rocket wordfence updraftplus wp-mail-smtp

(Adjust the names to what the list shows.) One built-in safety net worth knowing: DDEV traps all outgoing email in Mailpit — ddev launch -m shows it — so even a plugin you missed can’t mail your actual customers from your laptop. Your local copy should be all rehearsal, no audience.

Verify login and a handful of pages

Open the site and give yourself a local login rather than fishing for the production password:

ddev launch
ddev wp user create localadmin dev@example.test --role=administrator --user_pass='pick-something'

Log in at /wp-admin/, then click the front page, a recent post, a page with images, and — if it’s a store — a product page. Images loading proves the uploads sync; no redirect to the live domain proves the search-replace; a working dashboard proves the database. When all three hold, you’ve got a true copy, and every scary change gets rehearsed here before it ever meets production.

That's the lesson. Back to the shop for more — or if this is the chore your organization never gets to,that's literally what we're for.