How to upgrade WordPress with DDEV: from local development to production

Title slide with logos and mountain range photo: How to upgrade WordPress: local to production with DDEV

Goals: update WordPress core, PHP version, and plugins

We wanted to upgrade our WordPress site,, to the latest version of PHP as well as updating WordPress Core and some plugins. We are hosting on our own DDEV-Live hosting platform and we used both the ddev-live CLI and DDEV-Local to perform these updates. In this scenario, we were primarily updating the backend and server configuration, so it didn’t make sense to use DDEV Preview for this task. For work that includes a lot of frontend changes and visual review, Preview is super helpful so you may want to employ it if your updates fit that bill.

Takeaways and wins for this WordPress upgrade workflow

Easing the pain of the WordPress uploads folder

Moving the entire uploads folder from WordPress is notoriously painful and DDEV makes it very simple. It was also very easy to optimize all of the images in the uploads folder and move them seamlessly into production using the push files command in DDEV-Live.

Eliminating the complexity of PHP upgrades

Upgrading PHP versions can be tricky, but DDEV offers commands for deploying a new site with the desired PHP version specified and leveraging the hostname functionality in DDEV-Live. We had minimal downtime.

Removing the risk of WP plugin upgrades

DDEV also streamlines the plugin upgrade process using the local environment. We were able to check compatibility on a staging site to verify that everything was running as expected before simply pointing at the new site.

Procedure from local development to deployment

This tutorial assumes that you have a site existing on DDEV-Live for the deployment steps. If you don’t, try the walkthrough on after you create an account, or read more on how to deploy to DDEV-Live.

Spin up a version of the remote site in DDEV-Local

First, pull the code for your production site locally. In our case, this means a git pull of the currently deployed branch from the repository on GitHub because our project is already configured with Git and DDEV-Local. If you’re doing this for the first time, you’ll want to read more.

Pull down and import the production database export using DDEV-Live

First we create a database backup using the ddev-live CLI tool, referring to the site by our DDEV-Live <org-name>/<site-name>. Then we pull that backup locally and import to DDEV-Local.

ddev-live backup database ddev-live-org-name/live-slug

Initiated database backup: ddev-live-org-name/live-slug-9wzbl
For backup status, run:
  ddev-live describe backup database ddev-live-org-name/live-slug-9wzbl

ddev-live pull database ddev-live-org-name/live-slug-9wzbl

Downloaded: live-slug-9wzbl.sql.gz
# From the local project directory
## Using DDEV
ddev import-db local-site-slug --src=live-slug-9wzbl.sql.gz
## Using WP CLI
ddev exec `wp import db live-slug-9wzbl.sql.gz`

Pull down and import the production WordPress uploads folder using DDEV-Live

Same principle as the database: create a backup of the files, then pull the backup down into the local files destination.

ddev-live backup files ddev-live-org-name/live-slug
Initiated files backup: ddev-live-org-name/live-slug-hZYt3
For backup status, run:
  ddev-live describe backup files ddev-live-org-name/live-slug-hZYt3

ddev-live pull files ddev-live-org-name/live-slug-hZYt3 --dest=docroot
(This took about an hour for our site)

You can also use ddev pull if you’d like to automate bringing the project local, but we wanted to do things in a more step by step way on this particular upgrade.

Update WordPress to latest version

First, configure your DDEV-Local project settings with the PHP version you will be using in production. In our case, PHP 7.4.

Then update WordPress:

## Using WP-CLI
ddev exec "wp core update"

Update plugins to latest version.

We recommend updating plugins one at a time. If your local site is still in good shape after you update a plugin, move on to the next one.
You can update your plugins the old fashioned way with WP-CLI, or simply use Composer if you’re using WPackagist:

## Using WP-CLI
ddev exec "wp plugin update <plugin-slug>"
## Using Composer and WPackagist
composer update wpackagist-plugin/<your-plugin-slug>

Pro-tip: Make a Git commit after each plugin update to make your pull requests more manageable and easier to code review. It also makes it easier to roll back and understand what went wrong, if needed.

## Using Composer
git add composer.json
git commit -m "Updated Advanced Custom Fields 5.8.7 => 5.9.1"
## Old-fashioned WP-CLI way
git add wp-app/plugins/advanced-custom-fields
git commit -m "Updated Advanced Custom Fields 5.8.7 => 5.9.1"

Change branch from master to main

We saw this as a great time to make the switch.

Push our new updated code to GitHub on the new main branch

git push origin main

Create a new DDEV-Live site using the GitHub repo’s main branch, and use PHP 7.4 on new site

ddev-live create site wordpress new-site-php74 \
--git-repo=<your-account>/<your-repo> \
--git-rev=main \
--docroot=docroot \
--php-version=7.4 \
--persistent-paths app/uploads \
--ephemeral-paths=content/cache \
--org=ddev-live-org-name \

Push the production database export using DDEV-Live to the new site

ddev-live push database ddev-org-name/new-site-php74 live-slug-9wzbl.sql.gz

Push the production uploads folder export using DDEV-Live to the new site

ddev-live push files ddev-org-name/new-site-php74 docroot/app/uploads app/uploads

Pro-tip: We losslessly optimized every image in our uploads folder before pushing them up to help with page load times.

Remove the hostnames from the old site using DDEV-Live and add them to the new site.

You should remove the hostnames from the old site and apply to the new site as quickly as possible to avoid downtime.

ddev-live config hostname remove ddev-external-sites/live-site
ddev-live config hostname remove ddev-external-sites/live-site
ddev-live config hostname add ddev-external-sites/new-site-php74
ddev-live config hostname add ddev-external-sites/new-site-php74

That’s it! As you can see, the site is up and running successfully with WordPress 5.6, “Simone”, which includes the latest security releases, on top of PHP 7.4. By using DDEV to make the upgrades locally and configure the production environment we were able to update and launch the site and move assets quickly and painlessly. This resulted in a more secure and more usable site for editors as well as visitors.

Let us know how this goes for you, feel free to drop a tweet @ddevHQ or use our contact form for additional feedback. Thanks for stopping by.

Share this post: