WordPress Networks & IIS Rewrite Rules on Azure App Service

Standard

This is a bit of an extension to my previous post.

One of the last blogs I moved was a MU or a multi-user WordPress blog, which is now known as a Network. This turned out to be a bit more challenging than the single WP blogs. To setup a new instance, these instructions should mostly do the trick however, based on my testing you’ll still need the rewrite rules below.

From this post and this post, I was able to assemble the following rewrite rules that have worked for my WPMU blog running on the Azure App Services (as of Sept. 13, 2016)! Don’t miss the <httpRedirect enabled="false" ....> line at the bottom – that was very important. You’ll also need those MU settings out of your wp-config.php file too.

web.config:

<system.webServer>
<rewrite>
<rules>
<rule name="WordPress Rule 1" stopProcessing="true">
<match url="^index\.php$" ignoreCase="false" />
<action type="None" />
</rule>
<rule name="WordPress Rule 2" stopProcessing="true">
<match url="^([_0-9a-zA-Z-]+/)?files/(.+)" ignoreCase="false" />
<action type="Rewrite" url="wp-includes/ms-files.php?file={R:2}" appendQueryString="false" />
</rule>
<rule name="WordPress Rule 3" stopProcessing="true">
<match url="^([_0-9a-zA-Z-]+/)?wp-admin$" ignoreCase="false" />
<action type="Redirect" url="{R:1}wp-admin/" redirectType="Permanent" />
</rule>
<rule name="WordPress Rule 4" stopProcessing="true">
<match url="^" ignoreCase="false" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
</conditions>
<action type="None" />
</rule>
<rule name="WordPress Rule 5" stopProcessing="true">
<match url="^" ignoreCase="false" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
<add input="{URL}" pattern="([a-zA-Z0-9\./_-]+)\.axd" />
</conditions>
<action type="None" />
</rule>
<rule name="WordPress Rule 6" stopProcessing="true">
<match url="^[_0-9a-zA-Z-]+/(wp-(content|admin|includes)?.*)" ignoreCase="false" />
<action type="Rewrite" url="{R:1}" />
</rule>
<rule name="WordPress Rule 7" stopProcessing="true">
<match url="." ignoreCase="false" />
<action type="Rewrite" url="index.php" />
</rule>
</rules>
</rewrite>
<httpRedirect enabled="false" destination="http://www.examplesite.com" />
</system.webServer>

wp-config.php:

define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', false);
define('DOMAIN_CURRENT_SITE', 'www.examplesite.com');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);

WordPress on Azure App Service using MySQL In-app!

Standard

Well, after a very long hiatus from blogging, I thought it was about time I started again. And what better way to start than with an update to my previous post on hosting your WordPress blog in the Azure App Service!

If you have been watching the Azure blogs, specifically from the App Service Team, you may have noticed an interesting one titled “Announcing MySQL in-app (Preview) for Web Apps“. For those of us that just want to host a small blog somewhere and are not concerned about scaling the web app across multiple instances (aka no auto-scaling), this is a pretty intriguing option. I should also note that as of writing this post (September 12, 2016), MySQL in-app is still in preview and not yet at general availability. You should take a look at the product team’s post for a full list of limitations.

Migrating to this service was fairly straightforward! Below is the approach I took.

  1. You’ll need to have an App Service Plan for this. I prefer to create a plan before the web app, but you can create both at the same time. Here’s some quick instructions on how to create one. When selecting a specific plan type (Free, Shared, Basic, Standard, or Premium), you should make yourself aware of the limitations to each plan. For example, Always On is not supported by Free and Shared plans. Backup is only support in Standard and Premium. RAM scales up as the plans go up. You can always scale up and down after you create the plan too.
  2. Create your new web app. For this you’ll want to pick the ‘WordPress’ template. This link will get you right to the correct blade in the Azure Portal.
  3. Fill out the fields as per your requirements. For the Database Provider field, be sure to pick “MySQL In App (Preview)” as shown below. Application Insights is enabled by default, your call on leaving this way. There is a WordPress plugin to fully enable it in your blog should you so desire however, I am not sure how frequently it’s maintained, so use as your own risk. I do have plugin version 2.2 running on my blog, which is at version 4.6.1.
  4. Once your web app is spun up, there’s a few things I like to do and these are optional:
    • Configure your custom domain, found under Custom domains > Add
    • Enable Always On, found under Application settings > Always On.
    • Turn off the Affinity Cookie because you can only have a single instance of your site using MySQL in-app., found under Application settings > APR Affinity. More info here.You’re now ready to migrate your blog over to your new web app!
  5. For moving MySQL, I grabbed a backup of the database in .sql format. You may need to compress it of it’s greater 8MB. You’ll need to take that file and import it into your MySQL instance. Because it’s in a protected sandbox environment, MySQL cannot be accessed remotely so you’ll need to use phpMyAdmin. To get there, open the “MySQL In App (Preview)” blade in your web app and click “Manage” as show below. Once in phpMyAdmin, make sure there’s an empty DB called “azuredb”. Select it, click the “Import” tab and follow the instructions.
  6. Next up – your content! You’ll probably need everything in your WordPress home directory including things like the folders wp-admin, wp-content, wp-includes, and files wp-config.php, wp-login.php to name a few. Once you’ve got the files required all together, you’ll need to make a small change to your wp-config.php. From the product team blog post mentioned above, they include some sample code for parsing the db connection string provided by the app service. I’ve included it below. Be sure to just replace the MySQL settings in your wp-config.php or your site may not work. You may also need to adjust an references to the home directory, if a plugin has added them to your wp-config.php. The web app hosted home directory will be “D:\home\site\wwwroot”. Good idea to keep a backup of that file as well.
    /*Add at the begining of the file*/
    $connectstr_dbhost = '';
    $connectstr_dbname = '';
    $connectstr_dbusername = '';
    $connectstr_dbpassword = '';
    
    foreach ($_SERVER as $key =&gt; $value) {
        if (strpos($key, "MYSQLCONNSTR_localdb") !== 0) {
            continue;
        }
        
        $connectstr_dbhost = preg_replace("/^.*Data Source=(.+?);.*$/", "\\1", $value);
        $connectstr_dbname = preg_replace("/^.*Database=(.+?);.*$/", "\\1", $value);
        $connectstr_dbusername = preg_replace("/^.*User Id=(.+?);.*$/", "\\1", $value);
        $connectstr_dbpassword = preg_replace("/^.*Password=(.+?)$/", "\\1", $value);
    }
    
    // ** MySQL settings - You can get this info from your web host ** //
    /** The name of the database for WordPress */
    define('DB_NAME', $connectstr_dbname);
    
    /** MySQL database username */
    define('DB_USER', $connectstr_dbusername);
    
    /** MySQL database password */
    define('DB_PASSWORD', $connectstr_dbpassword);
    
    /** MySQL hostname : this contains the port number in this format host:port . Port is not 3306 when using this feature*/
    define('DB_HOST', $connectstr_dbhost);
    
  7. Upload your files to your web app. I used FTP to move them, FileZilla specifically, but use whatever works best for you. Make sure your WordPress root ends up under “D:\home\site\wwwroot”. As a best practice, I delete the WordPress files created as part of the web app creation, but do what you think is best. You can find your FTP credentials under the Properties blade. I prefer to use FTPS whenever possible. If you don’t know your FTP user’s password, it can be reset under the Deployment credentials blade.
  8. You may need to adjust any DNS entries to reflect the different host and to align with your WordPress config. I use Fiddler to run a quick test to make sure the site is operational and run some quick tests before I flip my DNS entries.
  9. One last thing to do – update your Permalinks config. In your blog, just go to Settings > Permalinks, validate that your preferred structure is selected and click ‘Save Changes’. This will cause your web.config file to be updated to correctly support permalinks. This is especially important if you have moved from Apache on a Linux box. Other than that – you’re all set!

Hopefully that helps you move your blog to an Azure Web App using MySQL in-app…. And yes… this blog is hosted in an Azure Web App with MySQL in-app.