Resolving slowiness of built-in Apache+PHP contanier due to files served from network storage, and first time responsiveness of custom Docker image

C Y Tam 11 Reputation points
2020-07-16T04:11:55.167+00:00

I have an application which I'd like to move to Azure. This is a standard web application written in PHP, developed using the Symfony framework. Since I am new to Azure, I looked for the most straightforward solution first. App Service (Linux) + Web App for PHP seems to be a good fit for this kind of application, so I followed the quick start/tutorials and created an App Service (in Linux) and a PHP Web App and deployed the code to the cloud via Git. The deployment is smooth and the application runs fine, but there is one catch - the response time is too slow. It takes around 6 to 10 seconds for the web server to complete a request, sometimes even worse. This is simply unacceptable. It is still slow as hell after I switched the service plan to the P1V2 tier, so the problem should be elsewhere.

After some investigations, I concluded that this is probably caused by the fact that the app service is serving my web application code (i.e. /home/site/wwwroot) through a network storage (cifs?). So I first tried configuring Opcache to use a more aggressive approach, and the response time drops to ~2-4 seconds. Not bad but still far from satisfactory. Then as an experiment I copied the app code to the local disk, tweaked Apache to serve files from it. Now the response time drops to below 400ms. So my speculation seems true. The problem of course is that "data outside '/home' is not persisted", so this is not a viable deployment flow, and I probably need to look elsewhere.

Then I went further and tried deploying the application using a Docker image (via Azure Container Registry) to avoid the CIFS stuff. It also works fine, and the response time is the same as serving files from a local disk, but there is also a catch - the app is responsive except for the client who is the first to visit the website. As stated in the tutorial (https://learn.microsoft.com/en-us/azure/app-service/containers/tutorial-custom-docker-image): "The first time you access the app, it may take some time because App Service needs to pull the entire image". The docker image of my app is around 1.5GB, and in my experience the first user will have to wait for about 5 minutes until the request timeout (and the user needs to refresh the page 1 or 2 times to see a working page). No matter how I strive for trimming down the size of the docker image, this is still a bad user experience.

And hence my questions:

(1) Is there any way to improve the performance of the PHP web app instance? The cause is probably due to files are served via network attached storage. The performance is worse for modern PHP applications where a project contains a significant number of files (Opcache
preloading in PHP 7.4 isn't seem stable enough for me, also Azure currently offers up to PHP 7.3 only). One possible solution is to run a script to copy the files to the local disk whenever a container is started or created. But this doesn't seem possible? Or is there a better way?

(2) For custom Docker image deployment, is it possible to configure App Service to pull the image before serving client requests? This may not be as problemetic as the previous issue as this long-wait-until-timeout issue only happens when the app service is restarted/scaled up/scaled down (not sure if this obsevation is correct), but I still feel like this is something that needs to be tackled, and I do feel strange that the tutorial doesn't see it as something that needs to be eventually handled.

I am unable to find a post facing issues similar to that I have, so I try to ask here.

Thank you!

Azure App Service
Azure App Service
Azure App Service is a service used to create and deploy scalable, mission-critical web apps.
6,908 questions
{count} votes

1 answer

Sort by: Most helpful
  1. ajkuma 22,416 Reputation points Microsoft Employee
    2020-07-17T09:44:40.537+00:00

    Welcome to Microsoft Q&A! This is good question, thanks for posting here with a detailed description of the problem. It’s highly appreciated.

    Apologies for the delayed response here. I completely understand the frustration with the WebApp performance issue.
    Kindly take a look at the suggestions mentioned below, that we could try, if those doesn’t help I wish to engage with you offline for a much closer look and provide a quick and specialized assistance, please send an email with subject line “Attn:Ajay” to AzCommunity[at]Microsoft[dot]com referencing this thread, Azure subscription ID, I will follow-up with you.

    Apologies for the long answer – I’m sharing all the possible options that we could try to benefit the community.

    Having mentioned that, there could several cause for slow performance, in the interim, you may try these options to isolate the issue
    (I understand you have tried several things already, if you have haven’t done any of the following, requesting you to review and try:

    1. Firstly for a quick review, kindly check to see if App Service diagnostics provides any pointers, it reduces the chance of trial and error and expedites problem resolution by recommending potential solutions.
      To access App Service diagnostics, navigate to your App Service app in the Azure portal. In the left navigation, click on Diagnose and solve problems – Checkout the tile for “Diagnostic Tools” and “Availability and Performance”.
    2. If you haven’t done this already so, you may enable Always On to keep the app loaded all the time. From the Azure Portal> Navigate to your WebApp > Under Settings blade > Go to “Configuration” > Enable “Always on” feature under ‘Platform settings’.
    3. You can configure the amount of time the platform will wait before it restarts your container. To do so, set the WEBSITES_CONTAINER_START_TIME_LIMIT app setting to the value you want. The default value is 230 seconds, and the maximum value is 1800 seconds.

    To do this, from the Azure Portal> Navigate to your WebApp > Under Settings blade > Go to “Configuration” >
    Add the above app setting with ‘Name’ with 1800 as ‘Value’ .