A local copy is the difference between testing a change and hoping about it. Once your site runs in DDEV, every update, module swap, and redesign gets rehearsed on a copy that costs nothing to break. You’ll need DDEV installed, Drush in the project, and SSH access to the live server. If you’re weighing this against a hosted staging site, our note on whether you need staging is the longer conversation — the short version is you want at least this.
Get the code down and configure DDEV
Clone the repository, then tell DDEV what it’s looking at:
git clone git@your-git-host:you/your-site.git your-site
cd your-site
ddev config --project-type=drupal11 --docroot=web
ddev start
ddev composer install
Adjust drupal11 and web to match your version and docroot. If the
site isn’t in git yet, stop here and fix that first — a site that only
exists on its server is one bad day from not existing.
Pull the database
On the live server, make a dump with Drush; then pull it down and feed it to DDEV:
ssh you@your-server "cd /path/to/site && vendor/bin/drush sql:dump --gzip --result-file=/tmp/live.sql"
scp you@your-server:/tmp/live.sql.gz .
ddev import-db --file=live.sql.gz
DDEV handles the gzip itself and replaces your local database with the
dump — no unzipping, no fuss. Delete the /tmp copy off the server
when you’re done; database dumps shouldn’t linger where the web can
reach.
Pull (or stub) the files directory
Uploaded images and documents live outside git. For a modest site, rsync them:
rsync -az you@your-server:/path/to/site/web/sites/default/files/ web/sites/default/files/
For a site with twenty gigabytes of PDFs, that’s a portage you don’t need to make — stub it instead with Stage File Proxy, which fetches each file from production the first time a page asks for it:
ddev composer require drupal/stage_file_proxy
ddev drush pm:install stage_file_proxy -y
ddev drush config:set stage_file_proxy.settings origin "https://www.your-live-site.com" -y
Sanitize what shouldn’t leave production
Your laptop now holds real customer emails and password hashes. Fix that immediately:
ddev drush sql:sanitize -y
That scrambles emails and passwords in the local copy. Two more things to check: DDEV already traps all outgoing email in Mailpit, so your copy can’t accidentally mail real people — but if your config holds live API keys (payment gateways, search services, CRMs), switch them to test credentials locally before anything talks to the outside world.
Point the local site at local services
DDEV generated a settings.ddev.php during config, which wires up the
local database and trusted host settings automatically — confirm your
settings.php includes it (recent Drupal scaffolds do). Then look for
production-only assumptions: a Redis or Solr connection, a CDN or
purge module, a cron that pings production. Disable or repoint them:
ddev drush pm:list --status=enabled --no-core
Read that list once, asking of each module: does this expect a service
my laptop doesn’t have? Clear caches after any changes with
ddev drush cr.
Verify you can log in and see content
The moment of truth:
ddev drush user:login
ddev launch
The first command prints a one-time login link for your local site; open it. You should land in the admin as user 1. Now click around like an ordinary visitor: front page renders with its styles, a few content pages load, images appear (instantly if you rsynced, after a beat if you’re proxying). If all of that holds, you have a working copy of production on your desk — and from today on, no change touches the live site before it’s been tried on the one that can’t hurt anybody.