Taking a Small Blog to the Big Cloud: WordPress on Azure

Mar 21, 2015
Mar212015

Taking a Small Blog to the Big Cloud: WordPress on Azure

Microsoft Azure isn't just an amazing platform for ASP.NET, it's also an excellent platform for hosting the world's most popular blogging engine: WordPress. With WordPress powering 19% of the web and Microsoft Azure adding more services at amazing price points, it's a no-brainer to combine the two. Leave your traditional shared webhost behind and look to the cloud.

In this video, we'll walk through creating a new, git-driven WordPress installation running as a Microsoft Azure Website. We'll also tie into other cloud services, such as Azure Block Blob Storage for storing media, SendGrid for sending emails, and ClearDB for our database. You'll be ready to launch to the cloud in no time!

Update: With this week's Azure announcements, some things are slightly different from what's presented in the video. Main examples: websites are now web apps, WordPress is now a template you have to search for, Web Hosting Plans are now called App Service Plans.

Resources from the Video

WordPress Plugins

wp-config.php snippets

define('WP_DEBUG', false);

// Caching Configuration
define('WP_CACHE', true);
define('WPCACHEHOME', dirname(__FILE__) . '/wp-content/plugins/wp-super-cache/' );

// Memory Config
define('WP_MEMORY_LIMIT', '1024M');

web.config

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Proxy" stopProcessing="true">
                    <match url="^proxy/?(.*)" />
                    <action type="Rewrite" url="http://az736103.vo.msecnd.net/{R:1}" />
                </rule>
                <rule name="WP Super Cache" stopProcessing="true">
                    <match url="^(\d{4})/(\d{2})/(.+?)/?$" ignoreCase="false" />
                    <conditions>
                        <add input="{REQUEST_METHOD}" negate="true" pattern="POST" ignoreCase="false" />
                        <add input="{QUERY_STRING}" negate="true" pattern=".*=.*" ignoreCase="false" />
                        <add input="{QUERY_STRING}" negate="true" pattern=".*attachment_id=.*" ignoreCase="false" />
                        <add input="{HTTP_COOKIE}" negate="true" pattern="^.*(comment_author_|wordpress|wp-postpass_).*$" ignoreCase="false" />
                        <add input="{DOCUMENT_ROOT}\wp-content\cache\supercache\{HTTP_HOST}\{R:1}\{R:2}\{R:3}\index.html" matchType="IsFile" />
                    </conditions>
                    <!-- Normal SuperCache Behavior -->
                    <!-- <action type="Rewrite" url="wp-content/cache/supercache/{HTTP_HOST}/{R:1}/{R:2}/{R:3}/index.html" /> -->
                    <!-- Use Azure CDN in combination -->
                    <action type="Rewrite" url="http://az736103.vo.msecnd.net/site/wwwroot/wp-content/cache/supercache/{HTTP_HOST}/{R:1}/{R:2}/{R:3}/index.html" />
                </rule>
                <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="(^[_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*)" ignoreCase="false" />
                    <action type="Rewrite" url="{R:2}" />
                </rule>
                <rule name="WordPress Rule 6" stopProcessing="true">
                    <match url="^([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" />
                    <action type="Rewrite" url="{R:2}" />
                </rule>
                <rule name="WordPress Rule 7" stopProcessing="true">
                    <match url="." ignoreCase="false" />
                    <action type="Rewrite" url="index.php" />
                </rule>
            </rules>
        </rewrite>
        <staticContent>
            <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
            <mimeMap fileExtension=".otf" mimeType="application/font-otf" />
            <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
        </staticContent>
    </system.webServer>
</configuration>

applicationHost.xdt

<?xml version="1.0"?>  
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">  
    <system.webServer>  
        <proxy xdt:Transform="InsertIfMissing" enabled="true" preserveHostHeader="false" reverseRewriteHostInResponseHeaders="false" />  
    </system.webServer>  
</configuration>

.user.ini

; http://www.windowsazure.com/en-us/develop/php/common-tasks/configure-php-web-site/
 
; Changing the default upload size
memory_limit = 1024M
upload_max_filesize = 32M
post_max_size = 64M
max_execution_time = 1200
default_socket_timeout = 600

Featured photo credit: clouds by Pattys-photos