In this article we are going to take a look at options on how to deploy a standard PHP application to Azure App Service. This article is split into two parts – classical App Service running Windows and the new Docker-based App Service on Linux which recently got some really nice improvements towards PHP support.
I would consider standard PHP application to consist of source files and also Composer packages. A while ago, I opened up an issue in Kudu related repository to actually add a better support for PHP based application deployment. It resulted with having an example deployment script added to the repository and a more automated build process added to App Service on Linux. We are going to explore the current options for deploying PHP applications using these options to App Service and App Service on Linux.
We are going to start off with looking at classic Azure App Service powered by Windows machines. There you have two options – you can either install the Composer extension or deploy using custom deployment script – each has its ups and downs:
The extension itself is very easy to deploy, you simply add it from the Azure Portal. After that, whenever you push new code to the repository and deployment is started, it is going to download the packages as part of the deployment, additionally composer executable will be added to the PATH so it can be very easily called from the Command Line or PowerShell in Kudu.
The great thing about the extension is that it is open source and available on GitHub, so you can see exactly what is it doing on the background.
FYI: How the extension works
The extension basically downloads latest Composer, automatically forces its own deployment script which handles the installation and additionally, it transforms the PATH using applicationHost.xdt to contain the executable so Composer can be called directly from Command Line or PowerShell in Kudu.
Custom deployment script
The custom deployment script gives you a little bit more freedom on how to customize the build process itself. Kudu offers a lot of nice pre-configured build tasks which get applied automatically whenever the specific project type is detected, however PHP is not very likely going to be supported automatically in App Service on Windows (#68). In this case, Kudu offers a repository with pre-made deployment scripts which you can just ship with your code.
One of those scripts is a PHP deployment script. This script is very similar in behavior with the Composer extension, however it doesn’t modify the PATH itself and simply downloads latest version of Composer during the build process (unless downloaded before), downloads the packages and copies the content over to the DEPLOYMENT_TARGET folder (which is usually D:\home\site\wwwroot).
With this script, you can do additional modifications like run Bower or NPM directly in the Batch scripts, so you have a little bit more control over the build process.
The most important part of the deployment script is:
:: 1. Composer.phar
IF EXIST "%DEPLOYMENT_SOURCE%\composer.json" (
IF NOT EXIST "%DEPLOYMENT_SOURCE%\composer.phar" (
echo Composer.phar not found. Downloading...
call curl -s https://getcomposer.org/installer | php
IF !ERRORLEVEL! NEQ 0 goto error
) ELSE (
echo Attempting to update composer.phar
php composer.phar self-update
call php composer.phar install --no-dev
IF !ERRORLEVEL! NEQ 0 goto error
Just like .csproj with C#, Composer allows to execute custom scripts or commands on certain events (more info). This allows you to fully integrate tasks like NPM, Bower install, Gulp tasks and so on directly into the composer.json file, so it is ran whenever composer install is executed. This is similar way how .NET Core and especially ASP.NET Core handles such things (more here).
App Service on Linux
I have already blogged about App Service on Linux multiple times, now we are going to focus on deploying a PHP application there. Again, just like with App Service on Windows, there are multiple ways to achieve the deployment.
Building custom Docker container
One of the ways is to build a custom Docker container which would contain the built application already and you would just deploy it to App Service on Linux. We explored this option in a previous article about building your custom container for ASL, and with slight modifications, you could also leverage VSTS and automate the Composer tasks into the container build process as well.
Deploying directly to ASL
When you create a new App Service on Linux, you can choose from pre-defined runtime containers – for example PHP7. However when you push the code to repository and it gets deployed to ASL, the PHP7 container is not going to be the container where the application gets built. It is actually going to be built in the Kudu container.
Like I mentioned already above – the team behind ASL has done a lot of great work towards adding better out-of-box support for PHP there. Thanks to that, when a deployment script is to be generated for ASL deployment, amongst the other runtimes, it also tries to check if it is a PHP project and if so, it will generate a Bash script which handles the deployment.
Just like with App Service on Windows, you can take the generated Bash script and modify it to your needs – add custom commands to execute on build and so on (you can achieve the same by using scripts in composer.json just like mentioned above with App Service on Windows).
The latest version of Kudu container comes already with Composer installed, so it is very easy and straightforward to go on with such deployment.
App Service or App Service on Linux?
The ultimate question – should I go with App Service on Windows or App Service on Linux for my application? The answer I can give you at the moment is not as straightforward, but let’s simply go with facts:
- App Service on Linux is still in Preview which means it shouldn’t be used for production workloads since breaking changes can still be made and could affect your application.
- App Service on Windows offers more features at the moment – like extensions, WebJobs, more Kudu options and so on.
- App Service on Linux is more native for PHP and other OSS runtimes.
- App Service on Windows is a stable and proven platform – it works really good (from my experience) when running PHP workloads.
So if you are just playing around – I would go with App Service on Linux. If you are doing production things with need for SLAs and such – I would go with App Service on Windows at the moment.
From the GitHub issue’s discussion it is clear that a lot of effort is being put into improving PHP, Node.js and other OSS’s runtimes developer experience on Azure thanks to App Service on Linux, so it is probably the best place to look into.