Setting Up a Local WordPress Multisite with Subdirectories Using DDEV
Setting up a local WordPress multisite environment can be challenging, especially when dealing with subdirectory installs. In this guide, we'll walk through the process of setting up a full local multisite installation supporting subdirectories using DDEV, with a focus on Pantheon integration.
👉 This guide assumes that you already have a WordPress multisite project set up on live and are looking to create a local development environment for it.
If you need to set up a new WordPress multisite project, you can follow the WordPress Codex guide.
Prerequisites
DDEV installed on your local machine
Git
Drush (Optional, for Pantheon integration), to get it, run
ddev composer require drush/drush
Ability to endure pain if things go wrong 😅 (believe me they will)
Let's get started!
Configure DDEV
Clone the Repository
First, clone your project repository to your local machine:
git clone [your-repo-url] cd [your-project-directory]
Run the DDEV configuration command:
ddev config
and answer the prompts.
Modify DDEV Configuration
In the .ddev/config.yaml
file, change the webserver type to Apache:
webserver_type: apache-fpm
We are moving to good ole Apache because handling subdirectory installs are much easier in Apache with .htaccess
compared to Nginx or at least I did not have a good time with it when I was playing with nginx-site.conf
file auto-generated by DDEV 🤦♂️
Create .htaccess
File
Create a .htaccess
file in the root of your project and add it to .gitignore
. Paste the following content into the file:
# BEGIN WordPress RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] # add a trailing slash to /wp-admin RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L] RewriteRule . index.php [L] # END WordPress
I have directly copied the content of .htaccess
file from the WordPress MultiSite Netword Administration docs for WordPRess version 3.5 and higher.
Configure WordPress
Since we're using Pantheon, we'll use wp-config-local.php
instead of wp-config.php
:
Add wp-config-ddev.php
to .gitignore
.
Remove any database connection settings from wp-config-local.php
.
Add the following to the bottom of wp-config-local.php
:
// Include for ddev-managed settings in wp-config-ddev.php. $ddev_settings = dirname(__FILE__) . '/wp-config-ddev.php'; if (is_readable($ddev_settings) && !defined('DB_USER')) { require_once($ddev_settings); }
If we were not using pantheon, or if we were setting up the multisite from scratch, we would have added the following to the bottom of wp-config-local.php
(since the wp-config-ddv.php file is auto-generated by DDEV and we have less control over it):
define('WP_ALLOW_MULTISITE', true); define('MULTISITE', true); define('SUBDOMAIN_INSTALL', false); define('DOMAIN_CURRENT_SITE', 'yoursite.ddev.site'); define('PATH_CURRENT_SITE', '/'); define('SITE_ID_CURRENT_SITE', 1); define('BLOG_ID_CURRENT_SITE', 1);
Optional Pantheon Integration
If you don't need Pantheon integration, you can skip this section and move to the Pull Database and files section.
Follow the Pantheon integration guide for DDEV:
⚠️ Important: Make sure that you follow pantheon guide for Drush and the machine token otherwise non of this is going to work.
Pull Pantheon Data
Pull the database from Pantheon ( I am skipping files and only pull the database because I am not interested in the files, you can pull the files as well if you want):
ddev pull pantheon --skip-files -y
but if you insist on pulling the files as well, you can run the following command:
ddev pull pantheon -y
Note: See the section below for an alternative method to pull the files.
Terminus
If you are using Terminus, you can use the following command to pull the database:
terminus backup:create [site].[env] --element=db terminus backup:get [site].[env] --element=db --to=database.sql.gz
See the Terminus documentation for more information.
Database and files
Export the database from live site
Export your database with whatever tool that your hosting provider provides, or if you use a plugin like WP Migrate DB, you can use that as well.
Import Database
Import the database into your local environment:
ddev import-db --file=path_to_dumpfile.sql.gz
DDEV has a pretty straightforward documentation about this.
Files
Using the command line tools, sftp client, or any other method, copy the files from your live site to the wp-content/uploads directory in your local environment.
for files, I usually use Bill Erickson's Media From Production to read media files from the live site and save myself a couple of GBs of storage. The plugin is a real gem!
Update URLs and Paths
After pulling the database from Pantheon, you need to update the URLs and paths to match your local environment. Use thewp search-replace
command:
ddev wp search-replace 'live-yoursite.pantheonsite.io' 'yoursite.ddev.site'
Replace '<live-yoursite.pantheonsite.io>' with your actual Pantheon live URL, and '<yoursite.ddev.site>'
with your local DDEV URL. Note that you may sometimes need to run this command multiple times to ensure that all URLs and paths are updated correctly. 🤞
Create/Edit WordPress User
Create a new WordPress user:
ddev wp user create your_username_here your_email_here --role=administrator --user_pass=yourpassword
Update a wordpress user role:
ddev wp user update the_id_of_the_user_here --role=administrator
Add Super Admin
Make your user a super admin, because if you are not already, you will not be able to access the network admin area:
ddev wp super-admin add your_username_here
Conclusion
By following these steps, you'll have a fully functional local WordPress multisite environment set up with DDEV,
supporting subdirectory installs and integrated with Pantheon. This setup provides a robust development environment for
working on WordPress multisite projects.
The wp search-replace command is crucial for ensuring that your local site works correctly with the database pulled from the live version.