Showing posts with label app. Show all posts
Showing posts with label app. Show all posts

Saturday, 3 May 2025

Adding Brotli compression to Azure Linux App Service (nginx)

No, this post isn't related to Sitecore, but recently I've been working on a site which runs on an Azure App Service box running Linux. These boxes run nginx under the hood (which you can see by SSHing in), which is set up to use gzip for common formats (including your usual HTML / CSS / JS). As we (hopefully) all know, brotli is the preferred option (eg. for Google Page Speed / Lighthouse) due to generally having much better compression for these sorts of file types so I looked into adding it to nginx.

Unfortunately the only relevant search result I found was for an old post I'd made myself, however back when Apache was in use and not nginx.

Now I should preface this by saying: for production environments you really should be using something like Azure Frontdoor to do this, however I wanted something that would work in a non-prod environment without Frontdoor.

Fortunately the README for Brotli is nice and easy to follow in explaining how to build it, and there are plenty of articles out there around adding Brotli to nginx

Just SSH in and run the following script to build 2x *.so files (used in the next script)

#eg. nginx version: nginx/1.26.3
version="$(nginx -v 2>&1 | cut -d '/' -f 2)"
#version=1.26.3 #if you'd rather specify a version

echo "Found nginx version $version"

cd /tmp
  
apt -y install git cmake
  
git clone --recurse-submodules -j8 https://github.com/google/ngx_brotli
#git config --global --add safe.directory /tmp/ngx_brotli/deps/brotli
cd ngx_brotli/deps/brotli
mkdir out && cd out
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS="-Ofast -m64 -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_CXX_FLAGS="-Ofast -m64 -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_INSTALL_PREFIX=./installed ..
cmake --build . --config Release --target brotlienc
cd ../../../..

wget https://nginx.org/download/nginx-$version.tar.gz
tar -xzvf nginx-$version.tar.gz
cd nginx-$version
  
./configure --with-compat --add-dynamic-module=/tmp/ngx_brotli
make modules
cp objs/ngx_http_brotli_filter_module.so /home/site/nginx
cp objs/ngx_http_brotli_static_module.so /home/site/nginx

Then add the following start.sh file to your app startup

#!/bin/bash

echo "Replacing nginx configuration"
cp /home/site/nginx/nginx.conf /etc/nginx/sites-available/default

echo "Adding brotli module"
cp /home/site/nginx/60-mod-brotli.conf /etc/nginx/modules-enabled/
cp /home/site/nginx/ngx_http_brotli_filter_module.so /usr/share/nginx/modules/
cp /home/site/nginx/ngx_http_brotli_static_module.so /usr/share/nginx/modules/
 
echo "Reloading nginx to apply new configuration"
service nginx reload

Finally, ensure your nginx.conf file (which you use to overwrite above) specifies to use the brotli module before gzip

#   Compression
brotli on;
brotli_static on;
# brotli_comp_level 4;
brotli_types
	text/plain
	text/css
	text/xml
	text/javascript
	text/x-component
	application/xml
	application/xml+rss
	application/javascript
	application/json
	application/atom+xml
	application/vnd.ms-fontobject
	application/x-font-ttf
	application/x-font-opentype
	application/x-font-truetype
	application/x-web-app-manifest+json
	application/xhtml+xml
	application/octet-stream
	font/opentype
	font/truetype
	font/eot
	font/otf
	image/svg+xml
	image/x-icon
	image/vnd.microsoft.icon
	image/bmp;
gzip on;
	#...etc

Thursday, 9 November 2017

Azure bug in SCM Uri for slots

I thought I'd raise some more attention (mostly out of pure frustration) to a bug in the Azure API that I came across today.

Rackspace, as one of our client's hosting providers, uses a guid as the Sitecore deployment ID, and so it is prepended to all the resource names.  This creates quite long app names, and combining that with a slot name (eg. 'cm-staging'), means that Azure drops some characters in the middle to maintain a 40 character hostname.
eg.
app name: 3dd1a584-abc6-4019-a917-633cb1dbfb40-prod-cm
slot name: cm-staging
becomes: 3dd1a584-abc6-4019-a917-633cb1dbfb40-pro-cm-staging.scm.azurewebsites.net

This unfortunately means that one can't simply use 'webappname-slotname'.azurewebsites.net as the URL, and it requires an API call to find out what Azure has generated.

We are using the Kudu API to run a script on our web apps (and slots) which means making REST calls to <webapp/slot>.scm.azurewebsites.net and this Kudu/scm URL is nicely provided in the publishing profile which can be retrieved with a simple Azure REST call.

Unfortunately the Azure API appears to do a simple 'webappname-slotname', and doesn't generate the 40 character URL which Azure actually uses.
ie. the URL that is returned: 3dd1a584-abc6-4019-a917-633cb1dbfb40-prod-cm-cm-staging.scm.azurewebsites.net

This has apparently been raised to Microsoft who are working on the issue.  However, rather than using the 'hostnames' property, you need to filter on the 'EnabledHostNames' property.

If I could make a suggestion: do your best to avoid using guids in your app names, or really long app names for that matter, it causes a world of pain.