Azure App Service is a way to host your web application in a container without having to think about the server. It’s the same PaaS concept as AWS Elastic Beanstalk and supports all the main web programming languages. It also supports Windows and Linux OS containers.

I have a client that is moving an on-premises PHP application to App Service and so have been looking at what I needed to do to deploy it there.

To get started, Azure have a couple of great tutorials for Linux and Windows with which I got a basic app running in no time, so I could turn my attention to the specifics I cared about.

Database drivers

My app uses SQL Server, so I was pleased to see that both the Windows and Linux PHP containers have the sqlsrv extension installed. However, there’s a bug today where the Linux container is missing the ODBC driver, so SQL Server support doesn’t actually work on the Linux container. This should be fixed in July apparently.

Both containers also support PostgreSQL and MySQL, so the databases I care for are covered.

Rewriting all URLs to index.php in the public directory

In common with many PHP applications, I have a public directory where the files to be served by the web server are kept and my PHP and other source files are elsewhere. I also use rewriting to map all URLs to my public/index.php file.

The way we handle this depends on the container.

Windows container

On the Windows container, we need to change the path mapping so that the public directory is mapped to the / . This can be done in the web portal in Configuration -> Path mappings where by default the / virtual path is mapped to site\wwwroot physical path. Edit this so that it points to site\wwwroot\public . I’m not a fan of web-based tooling for things like this as it’s error-prone. Azure provides a command line tool, so we can make the same path mapping change with:



$ az resource update --name web --resource-group {Resource Group} \ --namespace Microsoft.Web --resource-type config --parent sites/{App Service} \ --api-version 2015-06-01 \ --set properties.virtualApplications[0].physicalPath="site\wwwroot\public" 1 2 3 4 $ az resource update --name web --resource-group {Resource Group} \ --namespace Microsoft.Web --resource-type config --parent sites/{App Service} \ --api-version 2015-06-01 \ --set properties.virtualApplications[0].physicalPath="site\wwwroot\public"



(Change {Resource Group} and {App Service} to the correct names for your installation.)

Now that we’re serving from /public , we can now add the rewrite rule. With IIS, we use a web.config file:

/public/web.config:



<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <rewrite> <rules> <rule name="Pretty URLs to index.php" stopProcessing="true"> <match url="^(.*) <pre wp-pre-tag-1=""> 1 2 3 4 5 6 7 8 9 10 <? xml version = "1.0" encoding = "UTF-8" ?> <configuration> <system.webServer> <rewrite> <rules> <rule name = "Pretty URLs to index.php" stopProcessing = "true" > <match url = "^(.*) <pre wp-pre-tag-1=" " >



quot; />

<conditions logicalGrouping=”MatchAll”>

<add input=”{REQUEST_FILENAME}” matchType=”IsFile” negate=”true” />

<add input=”{REQUEST_FILENAME}” matchType=”IsDirectory” negate=”true” />

</conditions>

<action type=”Rewrite” url=”index.php” />

</rule>

</rules>

</rewrite>

</system.webServer>

</configuration>

Linux container

On Linux, the container runs Apache, so we can rewrite the URL to public/index.php with a single .htaccess file in our root directory:

/.htaccess:



RewriteEngine On RewriteBase / # Rewrite static files that live in public/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)\.(woff|ttf|svg|js|ico|gif|jpg|png|css|htc|xml|txt|pdf)$ /public/$1.$2 [L,NC] # Redirect all other URLs to public/index.php RewriteRule ^((?!public/).*)$ public/index.php/$1 [L,QSA] 1 2 3 4 5 6 7 8 9 10 RewriteEngine On RewriteBase / # Rewrite static files that live in public/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)\.(woff|ttf|svg|js|ico|gif|jpg|png|css|htc|xml|txt|pdf)$ /public/$1.$2 [L,NC] # Redirect all other URLs to public/index.php RewriteRule ^((?!public/).*)$ public/index.php/$1 [L,QSA]



Two rewrite rules are required: firstly we rewrite static files so that the continue to be served by Apache and then we rewrite everything else to index.php.

Environment variables

Environment variables are a common way to set per-installation configuration and this is done vie the portal or the command line:



$ az webapp config appsettings set --name {App Service} \ --resource-group {Resource Group} \ --settings \ ENV_VAR_1="some value" \ ENV_VAR_2="some other value" 1 2 3 4 5 $ az webapp config appsettings set --name {App Service} \ --resource-group {Resource Group} \ --settings \ ENV_VAR_1="some value" \ ENV_VAR_2="some other value"

Summary

Running a PHP application on Azure App Engine with either the Windows or Linux container is much the same as on any other hosting and seems to work well.