I recently decided it was time to upgrade some WordPress sites I have hosting as Azure App Services sites from the now deprecated PHP 7.4 to PHP 8.1 or 8.2.
However, I immediately hit an issue with permalinks (page slugs) no longer working, every page would return a 404 error.
In this post I will explain why this happens when moving to PHP 8.x and how to resolve the issue.
Why do I get a 404 error?
If you look at the previous screenshot you will notice the error is a Nginx server error not Apache. Microsoft is now delivering PHP 8.x App Services sites bundled with the web server Nginx not Apache.
This matters as Nginx does not use the .htaccess file, so URL rewrites for the permalinks need to be performing in differently.
How to fix the 404 error.
Nginx does support rewrites just not via an .htaccess file. We are going to need to make a change the App Service sites Nginx configuration file. However, as this file is regenerated whenever the App Service site is restarted, we are going to need to use a startup script to re-apply our change and reload Nginx at every startup of the App Service instance.
Creating a custom Nginx configuration file
- Within your App Services Site, under Development Tools click SSH and press Go to open a browser based SSH connection.
- Issue the below command to take a copy of the default Nginx configuration file
cp /etc/nginx/sites-available/default /home/site/default
- Issue the below command to open the newly copied with the editor nano or use vi if preferred.
vi /home/site/default
- You need to add the line “try_files $uri $uri/ /index.php?$args;” into the “location” section towards the start of the file. (press i in VI to enter insert mode)
- Optional – Nginx also has a 1MB upload limit. So, at this point I also like to increase this to 25MB. This is done by adding the line “client_max_body_size 25M;” into the “Server” section.
- In VI press ESX followed by :wq and followed by Enter to save and exit the file
Creating a custom startup script
Next, we need to create our startup script which will replace the default configuration file with our custom configuration at startup and give Nginx a reload.
Issue the below command to create an empty startup.sh file
vi /home/site/startup.sh
- Paste or enter the below connects and again save and exit (ESC followed by :wq! and followed by Enter)
#!/bin/bash
cp /home/site/default /etc/nginx/sites-available/default
cp /home/site/default /etc/nginx/sites-enabled/default
service nginx reload
- Give your new startup script a test (/home/site/startup.sh), and you should see Nginx gets reloaded and no errors. Also, your permalinks should now work
Triggering the Startup Script
The last step is to ensure that our startup script is run whenever the App Service Site is started or restarted.
- Back on the Azure portal for you App Services Site.
- Under Settings => Configuration => Genral Configuration
- Add /home/site/startup.sh as the startup command and save the configuration
- Finally restart your site on the Overview page
Troubleshooting
If when manually triggering, you startup script you get the error “/bin/bash^M: bad interpreter: no such file or directory”.
You may have some hidden characters in the file, sometimes caused by pasting into the SSH web page.
Tun the below command to fix the file.
sed -i -e 's/\r$//' /home/site/startup.sh
References
newline – Bash script – “/bin/bash^M: bad interpreter: No such file or directory” – Stack Overflow
NGINX Rewrite Rules for Azure App Service Linux PHP 8.x – (azureossd.github.io)
Thank you! I’ve been banging my head against a wall for hours on this now. I greatly appreciate it – you have won the internet for the day!
Glad I could help!
Phil
Hi I had followed the steps but still no joy.
Can you help? Appreciate that.
I cannot f***ing believe Microsoft make us jump through these fu**ing hoops all the fu**ing time.
You are my hero man , thanks
Amigo pero no se debe eliminar el htaccess de nuestro código? o al dejarlo igual sigue funcionando con esas configuraciones
Thanks for the good info..
I have question what happened to rewrite rules are those still be under .htaccess ?
Or do
We need to define under the nginx conf file ?