Great news! PHP 8 is now General Available on Azure App Service Linux resources! Because of policies within Microsoft support for PHP 8 and higher will no longer be supported by Windows App Service instances as was announced on the Azure App Service Linux Documentation on GitHub.
Because several dependent libraries and extensions are not available Microsoft did a soft launch of this version 8 of PHP on July 29, 2021.
First experiences
After playing with PHP 8 on Azure App Services for the past weeks, I’ve noted down my own experiences developing, deploying, and integrating PHP web applications on Azure App Service Linux resources with PHP 8.0.
Performance
The performance of my web applications had improved by about 4%, where the most impactful performance gain I noticed was in processing and transforming huge datasets. The performance of retrieval and storage of this data was almost similar, which I can explain by the fact the service for data storage (Azure Database for MySQL) was not changed during the upgrade.
Deployment
Azure offers a variety of deployment strategies for Azure App Service resources. A common deployment practice is to use git push or git pull from GitHub, BitBucket, GitLab, or any other type of collaborative code repository platform.
Unfortunately, this git push and pull workflow is facing an issue preventing the deployment to execute composer installation. It appears to happen because of a missing library on the system. This issue was reported to the Oryx team on GitHub.
Command: oryx build /home/site/repository -o /home/site/wwwroot --platform php --platform-version 8.0 -i /tmp/ae81445c8ade --log-file /tmp/build-debug.log
Operation performed by Microsoft Oryx, https://github.com/Microsoft/Oryx
You can report issues at https://github.com/Microsoft/Oryx/issues
Oryx Version: 0.2.20210618.2, Commit: d70100fba618b33e529c149b7d2d5f2c981ebbb1, ReleaseTagName: 20210618.2
Build Operation ID: |/Ckpf6cQHak=.9118744c_
Repository Commit : 484dd5e6e91039d1ffc9d57c29679c20ba5efcac
Detecting platforms...
Detected following platforms:
nodejs: 10.22.0
php: 8.0.3
Using intermediate directory '/tmp/ae81445c8ade'.
Copying files to the intermediate directory...
Done in 0 sec(s).
Source directory : /tmp/ae81445c8ade
Destination directory: /home/site/wwwroot
PHP executable: /tmp/oryx/platforms/php/8.0.3/bin/php
php: error while loading shared libraries: libonig.so.4: cannot open shared object file: No such file or directory
Composer archive: /tmp/oryx/platforms/php-composer/2.0.8/composer.phar
Running 'composer install --ignore-platform-reqs --no-interaction'...
php: error while loading shared libraries: libonig.so.4: cannot open shared object file: No such file or directory\n/opt/Kudu/Scripts/starter.sh oryx build /home/site/repository -o /home/site/wwwroot --platform php --platform-version 8.0 -i /tmp/ae81445c8ade --log-file /tmp/build-debug.log
Another common workflow, which I prefer myself, is to deploy a ZIP or TAR archive of the whole project using Azure CLI or the Azure Resource Manager (ARM) REST API. This artifact deployment works without any hiccups and fits in the deployment practices mentioned in the book “Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation (Addison-Wesley Signature Series (Fowler))” by Jez Humble and Dave Farley, published by Addison-Wesley [affiliate link].
zip ../myapp.zip -qr . -x ".git**" -x ".env*" -x "data/**" -x "*.phar" -x "*.publishsettings"
az webapp deployment source config-zip \
--subscription 8a0f7eb0-801e-4a04-ba91-05f840ee89b6
--resource-group WestEuropeRG
--name customer-backend-was
--src ../myapp.zip
The deployment process takes about 5 to 10 minutes depending on the size of the project, but the result is immediately available.
Getting scm site credentials for zip deployment
Starting zip deployment. This operation can take a while to complete ...
Deployment endpoint responded with status code 202
{
"active": true,
"author": "N/A",
"author_email": "N/A",
"complete": true,
"deployer": "Push-Deployer",
"end_time": "2021-09-12T06:41:48.723387Z",
"id": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"is_readonly": true,
"is_temp": false,
"last_success_end_time": "2021-09-12T06:41:48.723387Z",
"log_url": "https://customer-backend-was.scm.azurewebsites.net/api/deployments/latest/log",
"message": "Created via a push deployment",
"progress": "",
"received_time": "2021-09-12T06:41:41.2288234Z",
"site_name": "customer-backend-was",
"start_time": "2021-09-12T06:41:42.5610668Z",
"status": 4,
"status_text": "",
"url": "https://customer-backend-was.scm.azurewebsites.net/api/deployments/latest"
}
Web server [Edit 2021-09-15]
The Azure team are using a new container for running PHP 8 within a Linux App Service. Where previous it was possible to modify routing using a basic “.htaccess” file, now there is no convenient way to provide this within your application code (unless you manage your own container).
Fortunately on Azure OSS Development Support there is an article that is dedicated to solve this problem: “NGINX Rewrite Rules for Azure App Service Linux PHP 8.x“.
I added a customised Nginx server configuration where I provided two changes:
- Changing the document root to the folder containing my application entry
- Adding the “try_files” line as described in the article
root /home/site/wwwroot/api;
try_files $uri $uri/ /index.php?$args;
Now in order to change these settings, I added the following line as container startup script:
cp nginx.default /etc/nginx/sites-available/default && service nginx restart
Not the cleanest way but it got the job done.
Limitation [edit 2021-09-16]
There is a limitation on the amount of free Linux App Service instances you can run in a single region within a single subscription.
This subscription has reached the limit of 1 Free Linux app service plan(s) it can create in this region. Please choose a different sku or region.
This could be a problem if you want to run multiple proof of concepts at the same time, or you’re trying out a new hypothesis on a project while a team member already claimed the one free tier App Service.
My personal findings
I am really happy that Azure now supports PHP 8 natively on their App Service resources. This is a huge leap forward for the security, performance, and maintainability of applications. I needed to switch from Windows-based App Service resources to Linux-based instances, a switch that was mainly impacted by how I forced PHP requests to be handled by my “index.php” entry point. It is a small inconvenience compared to the bigger gains this switch will have in the long run.
The “hacky” way of ensuring the entry point of my application was actually used is not great, but I have faith this will come with either a configuration setting in the portal (as was the case for Windows) of by providing a “web.config” or “.htaccess” kind of alternative.
I hope the Oryx team is able to solve the issue with the missing dependency library component as this blocks a lot of people in their release processes.
We had to wait over 9 months for the release of 8.0 on Azure App Services. I hope that the availability for PHP 8.1, which is to be released at the end of this year, will be made available within the first 3 months.
Conclusion
There is no reason to postpone the upgrade to PHP 8 on Azure App Services. Deploy your application as an artifact and you will be able to enjoy all the good stuff PHP 8 offers.