Deploy WordPress Multisite on Upsun
Back to home
On this page
Note
Before you start, check out the Upsun demo app and the main Getting started guide. These resources provide all the core concepts and common commands you need to know before using the following materials.
You will need to make a few changes to your Upsun configuration for WordPress Multisite to successfully deploy and operate.
Please note that these changes must only be made after completing the Getting started guide. You should also already have a working WordPress site (see Assumptions for the WordPress guides your WordPress site should be based on).
Before you begin
You need:
- Git. Git is the primary tool to manage everything your app needs to run. Push commits to deploy changes and control configuration through YAML files. These files describe your infrastructure, making it transparent and version-controlled.
- A Upsun account. If you don’t already have one, register for a trial account. You can sign up with an email address or an existing GitHub, Bitbucket, or Google account. If you choose one of these accounts, you can set a password for your Upsun account later.
- The Upsun CLI. This lets you interact with your project from the command line. You can also do most things through the Web Console.
Assumptions
There are many ways you can set up a WordPress Multisite or Upsun project. The instructions on this page are based on the following assumptions:
- You selected PHP as your runtime, and MariaDB as a service during the Getting Started guide. It’s also assumed
that while using the Getting Started guide you named the project
myapp
, which you will notice is the top-level key in all configuration below. - Your database relationship name is
mariadb
(the default) - You have a working WordPress site based on either the WordPress Composer, Bedrock, or WordPress Vanilla guides.
- WordPress is installed in the web/public root of the site and not in a subdirectory of its own (or in the default of
wp
if you set up a Bedrock-based site) - You know if you are creating a subdirectory-based multisite or a sub/multi-domain based multisite.
1. Add rewrite rules to your root location
If you are setting up a subdirectory-based multisite, or you followed the Bedrock guide, the following rewrite rules are required. If you followed the Composer based or Vanilla guides and are unsure, or if you think you might convert to a subdirectory-based multisite later, you can add these rules to a sub/multi-domain multisite without any negative effects.
Locate the web:locations
section in your .upsun/config.yaml
file and update the rules section for your root (/
)
location as follows:
applications:
myapp:
<snip>
web:
locations:
"/":
<snip>
rules:
^/license\.text$:
allow: false
^/readme\.html$:
allow: false
'^/([_0-9a-zA-Z-]+/)?wp-(?<wproot>[a-z\-]+).php$':
allow: true
scripts: true
passthru: '/wp-$wproot.php'
# Allows directory-based multisites to still access the wp-admin and wp-include locations
'^/([_0-9a-zA-Z-]+/)?(?<adminrewrite>wp-(admin|includes).*)':
allow: true
scripts: true
passthru: '/$adminrewrite'
'^/([_0-9a-zA-Z-]+)/wp-content/(?<content>.*)':
allow: true
scripts: false
passthru: '/wp-content/$content'
expires: 1w
applications:
myapp:
<snip>
web:
locations:
"/":
<snip>
rules:
^/license\.text$:
allow: false
^/readme\.html$:
allow: false
'^/(?!wp/)([_0-9a-zA-Z-]+/)?wp-(?<wproot>[a-z\-]+).php$':
allow: true
scripts: true
passthru: '/wp/wp-$wproot.php'
# Allows directory-based multisites to still access the wp-admin and wp-include locations
'^/(?!wp/)([_0-9a-zA-Z-]+/)?(?<adminrewrite>wp-(admin|includes).*)':
allow: true
scripts: true
passthru: '/wp/$adminrewrite'
'^/([_0-9a-zA-Z-]+)/wp-content/(?<content>.*)':
allow: true
scripts: false
passthru: '/wp-content/$content'
expires: 1w
Note
If you followed the Bedrock guide and decided to change the default name of the directory where WordPress is installed
(wp
), then you will need to update both the rules and passthru
keys accordingly.
2. Update the database during the deploy hook
The domain(s) of your multisite are stored in the database itself. This creates a challenge in a system like Upsun where you often create preview environments dynamically during development. To ensure the database for your preview environments is updated with the correct domains, we have created a wp-cli package to automate the process of updating the database with the preview environment’s unique domain name.
To install the wp-cli package, locate the build:
section and update it as follows:
applications:
myapp:
<snip>
hooks:
build: |
set -eux
composer install --prefer-dist --optimize-autoloader --apcu-autoloader --no-progress --no-ansi --no-interaction
wp package install upsun/wp-ms-dbu
wp package update upsun/wp-ms-dbu
Note
If you created your site based on the WordPress Vanilla guide, only add the lines above that start with wp package
(i.e. skip the composer install
line).
To instruct the package to update your database with the relevant domains for the preview environment, locate the
deploy
section and update it as follows:
applications:
myapp:
<snip>
hooks:
deploy: |
set -eu
# we need the main production url
PRODURL=$(echo $PLATFORM_ROUTES | base64 --decode | jq -r --arg app "${PLATFORM_APPLICATION_NAME}" '[.[] | select(.primary == true and .type == "upstream" and .upstream == $app )] | first | .production_url')
if [ 'production' != "${PLATFORM_ENVIRONMENT_TYPE}" ] && wp site list --format=count --url="${PRODURL}" >/dev/null 2>&1; then
echo "Updating the database...";
wp ms-dbu update --url="${PRODURL}"
else
echo "Database appears to already be updated. Skipping.";
fi
# Flushes the object cache
wp cache flush
# Runs the WordPress database update procedure
wp core update-db
3. wp-config.php
/ config/application.php
Once our multisite has been set up, we need to expose additional pieces of information inside our wp-config.php
(or
./config/application.php
for Bedrock) file. In your wp-config.php/application.php file, right above the section
outlined below:
/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', dirname( __FILE__ ) . '/' );
}
/**
* Bootstrap WordPress
*/
if (!defined('ABSPATH')) {
define('ABSPATH', $webroot_dir . '/wp/');
}
add the following:
/**
* Multisite support
*/
define('WP_ALLOW_MULTISITE', true); //enables the Network setup panel in Tools
define('MULTISITE', false); //instructs WordPress to run in multisite mode
if( MULTISITE && WP_ALLOW_MULTISITE) {
define('SUBDOMAIN_INSTALL', false); // does the instance contain subdirectory sites (false) or subdomain/multiple domain sites (true)
define('DOMAIN_CURRENT_SITE', parse_url(filter_var(getenv('DOMAIN_CURRENT_SITE'),FILTER_VALIDATE_URL),PHP_URL_HOST));
define('PATH_CURRENT_SITE', '/'); //path to the WordPress site if it isn't the root of the site (e.g. https://foo.com/blog/)
define('SITE_ID_CURRENT_SITE', 1); //main/primary site ID
define('BLOG_ID_CURRENT_SITE', 1); //main/primary/parent blog ID
/**
* we have a sub/multidomain multisite, and the site currently being requested is not the default domain, so we'll
* need to set COOKIE_DOMAIN to the domain being requested
*/
if (SUBDOMAIN_INSTALL && $site_host !== DOMAIN_CURRENT_SITE) {
define('COOKIE_DOMAIN',$site_host);
}
}
/**
* Multisite support
*/
define('WP_ALLOW_MULTISITE', true); //enables the Network setup panel in Tools
define('MULTISITE', false); //instructs WordPress to run in multisite mode
if( MULTISITE && WP_ALLOW_MULTISITE) {
define('SUBDOMAIN_INSTALL', false); // does the instance contain subdirectory sites (false) or subdomain/multiple domain sites (true)
define('DOMAIN_CURRENT_SITE', parse_url(filter_var(getenv('DOMAIN_CURRENT_SITE'),FILTER_VALIDATE_URL),PHP_URL_HOST));
define('PATH_CURRENT_SITE', '/'); //path to the WordPress site if it isn't the root of the site (e.g. https://foo.com/blog/)
define('SITE_ID_CURRENT_SITE', 1); //main/primary site ID
define('BLOG_ID_CURRENT_SITE', 1); //main/primary/parent blog ID
if (SUBDOMAIN_INSTALL && getenv('PLATFORM_RELATIONSHIPS')) {
$site_host = $_SERVER['HTTP_HOST']) ?? "";
//we're not running locally so we need to make sure $site_host is set to something appropriate
try {
$validURLs = json_decode(getenv('UPSTREAM_URLS'), true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $exception) {
$validURLs = [];
error_log($exception->getMessage());
}
//if site_host isnt a valid domain we're expecting, then set it to the default domain
if(!in_array($site_host, array_map(static function (string $url) {
return parse_url($url, PHP_URL_HOST);
}, $validURLs), true)) {
$site_host = parse_url(filter_var(getenv('DOMAIN_CURRENT_SITE'),FILTER_VALIDATE_URL),PHP_URL_HOST);
}
/**
* we have a sub/multidomain multisite, and the site currently being requested is not the default domain, so we'll
* need to set COOKIE_DOMAIN to the domain being requested
*/
if ($site_host !== DOMAIN_CURRENT_SITE) {
define('COOKIE_DOMAIN',$site_host);
}
}
}
SUBDOMAIN_INSTALL
should be set to true
if your multisite is a sub/multi-domain site, or false
if you will be
setting up a subdirectory-based multisite. Note that MULTISITE
is currently set to false
; we will update this once
the database has finished being set up for the multisite.
4. Commit and push
You can now commit all the changes made above .upsun/config.yaml
and push to Upsun.
git add wp-config.php .environment .upsun/config.yaml
git commit -m "Add changes to begin setup of my Upsun WordPress multisite"
upsun push -y
5. Network (Multisite) Setup
Adding define('WP_ALLOW_MULTISITE', true);
will enable the Network Setup item in your Tools menu. Use that
menu item to go to the Create a Network of WordPress Sites screen. Follow the instructions on this screen and click
the Install button. You can ignore the instructions on the resulting screen.
Note
Alternatively, you can access a terminal session in the app container (upsun ssh
), and use
wp core multisite-convert
to install the multisite.
6. Final change to wp-config.php
/ application.php
Return to your wp-config.php / application.php file and change
define('MULTISITE', false);
to
define('MULTISITE', true);
Add and commit the changes, then push to Upsun:
git add wp-config.php
git commit -m "set WordPress to run in multisite mode."
upsun push -y
Once the site has finished deploying, you can return to the Network Admin –> Sites area of wp-admin and begin adding your sites.