Skip to content

Commit

Permalink
feat: use brotli instead of gzip for compression in NGINX (#1593)
Browse files Browse the repository at this point in the history
closes: #922
  • Loading branch information
andreassteinmann committed Mar 20, 2024
1 parent b4b45af commit a9c5766
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .vscode/intershop.txt
Expand Up @@ -14,6 +14,7 @@ bars
bitnami
blocklist
breakline
Brotli
categoryref
cobrowse
colorcode
Expand Down Expand Up @@ -97,6 +98,7 @@ noindex
noneditable
notselected
npsc
objs
oidc
openid
ordertemplate
Expand Down
2 changes: 2 additions & 0 deletions docs/guides/migrations.md
Expand Up @@ -33,6 +33,8 @@ With the content model adaptions of `icm-as-customization-headless:1.7.0` a dept
In the PWA the rendering was adapted as well so that an empty `NavigationDepth` value of the 'Static Content Page' component now defaults to `0` instead of no depth limitation, that resulted in the whole content page tree being fetched and saved to the state.
To keep the current behavior in an existing project either adapt the `0` default in `pagelet.numberParam('NavigationDepth', 0)"` to a reasonable number or set the 'Navigation Depth' values for all 'Static Content Page' component instances in the ICM backend to reasonable depth values instead of leaving them empty.

The [Brotli NGINX module](https://github.com/google/ngx_brotli) is used instead of gzip for compression on the NGINX server now, see [NGINX Optimizations](./optimizations.md#nginx-optimizations).

## From 4.2 to 5.0

Starting with the Intershop PWA 5.0 we develop and test against an Intershop Commerce Management 11 server.
Expand Down
25 changes: 25 additions & 0 deletions docs/guides/nginx-startup.md
Expand Up @@ -255,6 +255,31 @@ An additional Redis service is not intended for production environments where a
For that reason also the PWA Helm chart does not support deploying an own Redis service with the PWA.
Only the `redis.uri` can be configured for a Helm deployment.

### Brotli Configuration

All Brotli [configuration directives](https://github.com/google/ngx_brotli?tab=readme-ov-file#configuration-directives) can be set in
[`compression.conf`](../../nginx/features/compression.conf).

The on-the-fly Brotli compression level is set to the [recommended](https://www.brotli.pro/enable-brotli/servers/nginx/) value of `4` instead of `6` ([default](https://github.com/google/ngx_brotli?tab=readme-ov-file#brotli_comp_level)).
This setting provides a balance between the compression rate and CPU usage.
A higher level would achieve better compression but would also consume more CPU resources.

The two NGINX modules

- `ngx_http_brotli_filter_module.so` – for compressing responses on-the-fly
- `ngx_http_brotli_static_module.so` - for serving pre-compressed files

are built in the [`Dockerfile`](../../nginx/Dockerfile) using an NGINX archive in a version which matches the openresty Docker image version and are referenced in [`nginx.conf`](../../nginx/nginx.conf).
The archive needs to be used because it includes the `configure` command.
The `./configure` [arguments](https://github.com/google/ngx_brotli?tab=readme-ov-file#dynamically-loaded) are taken from the current openresty configuration using `nginx -V` (`--add-module` arguments are excluded), see [ngx_brotli
](https://github.com/google/ngx_brotli?tab=readme-ov-file#dynamically-loaded).

The modules can also be built using an openresty archive, but in this case the built process is taking longer:

- `wget` the openresty archive version which matches the Docker image version
- replace `make modules` with `make && make install`
- the two Brotli modules are built into the folder _/build/nginx-<version>/objs/_

## Further References

- [Concept - Multi-Site Handling](../concepts/multi-site-handling.md)
Expand Down
10 changes: 7 additions & 3 deletions docs/guides/optimizations.md
Expand Up @@ -7,13 +7,17 @@ kb_sync_latest_only

# Optimizations

## Nginx Optimizations
## NGINX Optimizations

The Nginx building block applies:
The NGINX building block applies:

- Compression of responses

for further information, please refer to the [Guide - Building and Running nginx][nginx-startup].
[ngx_brotli](https://github.com/google/ngx_brotli) is used to compress files on NGINX because Brotli has a better compression ratio compared to gzip.
The configuration of the module is described in [Guide - Building and Running NGINX](./nginx-startup.md#brotli-configuration).

> [!NOTE]
> Brotli compression is typically only used over HTTPS connections. This is because most modern web browsers only advertise support for Brotli encoding to servers when the connection is secure (HTTPS).
## Custom Webpack Build

Expand Down
17 changes: 16 additions & 1 deletion nginx/Dockerfile
@@ -1,3 +1,14 @@
FROM openresty/openresty:1.21.4.3-1-jammy AS buildstep
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev wget git gcc make

WORKDIR /app
RUN wget -q https://nginx.org/download/nginx-1.21.4.tar.gz && tar -zxf nginx-1.21.4.tar.gz \
&& git clone --recurse-submodules -j8 https://github.com/google/ngx_brotli \
&& cd nginx-1.21.4 \
&& ./configure --prefix=/usr/local/openresty/nginx --with-cc-opt='-O2 -DNGX_LUA_ABORT_AT_PANIC -I/usr/local/openresty/pcre/include -I/usr/local/openresty/openssl/include' --with-ld-opt='-Wl,-rpath,/usr/local/openresty/luajit/lib -L/usr/local/openresty/pcre/lib -L/usr/local/openresty/openssl/lib -Wl,-rpath,/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl/lib' --with-pcre --with-file-aio --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_xslt_module=dynamic --with-ipv6 --with-mail --with-mail_ssl_module --with-md5-asm --with-sha1-asm --with-stream --with-stream_ssl_module --with-threads --with-pcre-jit --with-stream --with-stream_ssl_preread_module --with-compat --add-dynamic-module=../ngx_brotli \
&& make modules

FROM openresty/openresty:1.21.4.3-1-jammy
COPY --from=nginx:mainline /docker-entrypoint.sh /
COPY --from=nginx:mainline /docker-entrypoint.d/*.sh /docker-entrypoint.d/
Expand All @@ -11,7 +22,9 @@ ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-c", "/etc/nginx/nginx.conf", "-g", "daemon off;"]

RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y apache2-utils libnss3-tools
&& apt-get install --no-install-recommends --no-install-suggests -y apache2-utils libnss3-tools \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
COPY nginx.conf /etc/nginx/nginx.conf
COPY features /etc/nginx/features/
COPY templates /etc/nginx/templates/
Expand All @@ -23,6 +36,8 @@ RUN chmod 700 /gomplate
ADD https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64 /usr/bin/mkcert
RUN chmod 700 /usr/bin/mkcert
COPY --from=nginx/nginx-prometheus-exporter:1.0.0 /usr/bin/nginx-prometheus-exporter /nginx-prometheus-exporter
COPY --from=buildstep /app/nginx-1.21.4/objs/ngx_http_brotli_static_module.so /etc/nginx/modules/
COPY --from=buildstep /app/nginx-1.21.4/objs/ngx_http_brotli_filter_module.so /etc/nginx/modules/
ENV CACHE=on
ENV COMPRESSION=on
ENV DEVICE_DETECTION=on
Expand Down
14 changes: 8 additions & 6 deletions nginx/features/compression.conf
@@ -1,6 +1,8 @@
gzip on;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
gzip_proxied any;
gzip_buffers 16 8k;
gzip_types *;
gzip_vary on;
brotli on;
brotli_comp_level 4;
brotli_static on;
brotli_types application/atom+xml application/javascript application/json application/vnd.api+json application/rss+xml
application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype
application/x-font-ttf application/x-javascript application/xhtml+xml application/xml
font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon
image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;
3 changes: 3 additions & 0 deletions nginx/nginx.conf
Expand Up @@ -8,6 +8,9 @@ pid /var/run/nginx.pid;

pcre_jit on;

load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;
load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;

events {
worker_connections 1024;
}
Expand Down

0 comments on commit a9c5766

Please sign in to comment.