WordPress MultiSite - Azure WordPress on Linux

WordPress MultiSite - Azure WordPress on Linux

In this tutorial we will be going over how to enable and create a WordPress Multisite on Azure using the WordPress on Linux marketplace resource.

You will need an Azure Subscription for this tutorial.

Getting Started

Navigate to the Azure Portal (https://portal.azure.com)

Click Create a resource and search for WordPress on Linux.

Once you are here populate your information for your WordPress setup:

Once your site has successfully deployed, navigate to your newly created site.

You should get the following when browsing your set.
This is the WordPress initial setup.

Setting up MultiSite on WordPress

Once you have WordPress installed and able to access into your WordPress dashboard, lets move along to setup MultiSite for your WordPress.

From the Azure Portal, SSH into your running container.

You will need to change your directory to /home/site/wwwroot and make a change in the wp-config.php file.
NOTE: If you are not accustom to using VI you could also make these changes via FTP.

Scroll down in the file until you fine:
/* That’s all, stop editing! Happy blogging. */
Above here you will add the following:
define(‘WP_ALLOW_MULTISITE’, true)’

Additionally, you will need to comment out the following as it will cause issues with your application. This code is added by Azure to help with using staging slots with your WordPress environment. However, this will currently break your MultiSite if left in.

You can then login to your /wp-admin dashboard and go to Settings > Network Setup
In this example, we want to use sub-directories and NOT sub-domains.

Once completed you will then need to go back into the wp-config.php file to add the following:

define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', false);
define('DOMAIN_CURRENT_SITE', 'yoursitename.azurewebsites.net');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);

We are almost there !!

Now that we have our MultiSite network setup, we need to also update our rewrite rules.
WordPress does an assumption that you are using Apache, however on Azure App Service when using the marketplace item, we use NGINX.

Before we modify NGINX, we need to add the following plugin to WordPress:
NGINX Helper – https://wordpress.org/plugins/nginx-helper/

Once installed and activated, go to Settings > Nginx Helper. You will need to enable Nginx Map.

Keep track of the path provided in the Nginx Map view. This will be used in the following NGINX config change.

Update NGINX Config

Since we are using NGINX in our container, you will need to modify the existing configuration.
This could be found here:

Again, you could modify using VI or FTP. Whichever is easier for you.

To make things easier, below is the default.conf file with needed modifications:

upstream php {
        server unix:/var/run/php/php7.0-fpm.sock;        

map $uri $blogname{
    ~^(?P<blogpath>/[^/]+/)files/(.*)       $blogpath;

map $blogname $blogid {
    default -999;
    #Ref: https://wordpress.org/extend/plugins/nginx-helper/
    include /home/site/wwwroot/wp-content/uploads/nginx-helper/map.conf;

server {
        listen 80;
        ## Your website name goes here.
        server_name _;
        ## Your only path reference.
        root /home/site/wwwroot;
        ## This should be in your http block and if it is, it's not needed here.
        index index.php;

        ## Added from WordPress and Nginx site
        ## https://wordpress.org/support/article/nginx/#wordpress-multisite-subdirectory-rules
        ## https://www.nginx.com/resources/wiki/start/topics/recipes/wordpress/#rewrite-rules-for-multisite-using-subdirectories
        location ~ ^(/[^/]+/)?files/(.+) {
                try_files /wp-content/blogs.dir/$blogid/files/$2 /wp-includes/ms-files.php?file=$2 ;
                access_log off;     log_not_found off; expires max;

        #avoid php readfile()
        location ^~ /blogs.dir {
                alias /home/site/wwwroot/wp-content/blogs.dir ;
                access_log off;     log_not_found off; expires max;

        ## End of MultiSite Modifications

        location = /favicon.ico {
                log_not_found off;
                access_log off;

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;

    if (!-e $request_filename) {
        rewrite /wp-admin$ $scheme://$host$uri/ permanent;
        rewrite ^(/[^/]+)?(/wp-.*) $2 last;
        rewrite ^(/[^/]+)?(/.*\.php) $2 last;

  # Add locations of phpmyadmin here.

  # Disable sendfile as per https://docs.vagrantup.com/v2/synced-folders/virtualbox.html
  sendfile off;

  set $skip_cache 0;

  # POST requests and urls with a query string should always go to PHP
  if ($request_method = POST) {
    set $skip_cache 1;
  if ($query_string != "") {
    set $skip_cache 1;

  # Don't cache uris containing the following segments
  if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
    set $skip_cache 1;

  # Don't use the cache for logged in users or recent commenters
  if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
    set $skip_cache 1;

  # Don't cache WooCommerce URLs
  # Cart widgets are still a problem: https://github.com/emcniece/docker-wordpress/issues/3
  if ($request_uri ~* "/(cart|checkout|my-account)/*$") {
    set $skip_cache 1;

        location / {
                # This is cool because no php is touched for static content.
                # include the "?$args" part so non-default permalinks doesn't break when using query string
                try_files $uri $uri/ /index.php?$args;

        location ~ \.php$ {
                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                include fastcgi.conf;
                fastcgi_intercept_errors on;
                fastcgi_pass php;

                fastcgi_read_timeout 300;
                fastcgi_cache_bypass $skip_cache;
                fastcgi_no_cache $skip_cache;
                fastcgi_cache WORDPRESS;
                fastcgi_cache_valid 60m;                

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;

Once you have updated the /home/etc/nginx/conf.d/default.conf file, you will need to stop/start your Azure Web App so that the new NGINX configurations are loaded.

Once they have loaded, you should have all the needed configuration steps to get your WordPress MultiSite up and running.

Have fun !!