Skip to content

Commit 615bf0e

Browse files
authored
Merge pull request #81 from bombinmybag/feat-nginx-br-support
Nginx: brotli support
2 parents 95270f3 + 1a8764f commit 615bf0e

File tree

11 files changed

+170
-5
lines changed

11 files changed

+170
-5
lines changed

Dockerfile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ FROM behance/docker-base:5.0.1-ubuntu-20.04
22

33
# Use in multi-phase builds, when an init process requests for the container to gracefully exit, so that it may be committed
44
# Used with alternative CMD (worker.sh), leverages supervisor to maintain long-running processes
5+
#
6+
# NGINX_VERSION is the MAJOR.MINOR.PATCH version available from upstream
7+
# providers (https://launchpad.net/~ondrej/+archive/ubuntu/nginx) at the time
8+
# of the build
59
ENV CONTAINER_ROLE=web \
610
CONTAINER_PORT=8080 \
711
CONF_NGINX_SITE="/etc/nginx/sites-available/default" \
812
CONF_NGINX_SERVER="/etc/nginx/nginx.conf" \
13+
NGINX_VERSION="1.22.0" \
914
NOT_ROOT_USER=www-data \
1015
S6_KILL_FINISH_MAXTIME=55000
1116

@@ -23,8 +28,9 @@ RUN /bin/bash -e /security_updates.sh && \
2328
add-apt-repository ppa:ondrej/nginx -y && \
2429
apt-get update -yqq && \
2530
apt-get install -yqq --no-install-recommends \
26-
nginx-light \
31+
nginx-light=${NGINX_VERSION}-* \
2732
ca-certificates \
33+
libnginx-mod-brotli=${NGINX_VERSION}-* \
2834
&& \
2935
apt-get remove --purge -yq \
3036
manpages \

container/root/etc/cont-init.d/10-nginx-config.sh

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,35 @@ then
8484
sed -i "s/^[ ]*listen ${CONTAINER_PORT}/ listen ${CONTAINER_PORT} ssl/" $CONF_NGINX_SITE
8585
fi
8686

87+
if [[ $SERVER_ENABLE_NGX_BROTLI ]];
88+
then
89+
echo "[nginx] enabling nginx brotli module"
90+
# Enable the brotli module
91+
sed -i "s/#load_module modules\/ngx_http_brotli_/load_module modules\/ngx_http_brotli_/" $CONF_NGINX_SERVER
92+
93+
# Enable brotli-specific configuration. All brotli configs begin with brotli*
94+
# Ref: https://github.com/google/ngx_brotli
95+
sed -i "s/#brotli/brotli/" $CONF_NGINX_SERVER
96+
fi
97+
8798
if [[ $SERVER_ENABLE_NGX_HTTP_JS ]];
8899
then
100+
# Enable the njs module
89101
echo "[nginx] enabling nginx njs module"
90-
sed -i "s/#load_module/load_module/" $CONF_NGINX_SERVER
102+
sed -i "s/#load_module modules\/ngx_http_js_/load_module modules\/ngx_http_js_/" $CONF_NGINX_SERVER
103+
fi
104+
105+
# Useful when you need to debug the contents of nginx.conf
106+
#
107+
# Should be the last entry in this script to ensure that all prior
108+
# modifications have been applied
109+
if [[ $SERVER_SHOW_NGINX_CONF ]];
110+
then
111+
if [[ -f "$CONF_NGINX_SERVER" ]];
112+
then
113+
echo ""
114+
echo "*** SERVER_SHOW_NGINX_CONF is set. Dumping $CONF_NGINX_SERVER ***"
115+
echo ""
116+
cat $CONF_NGINX_SERVER
117+
fi
91118
fi

container/root/etc/nginx/nginx.conf

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ error_log /dev/stdout warn;
1919
# Number of file descriptors used for nginx
2020
worker_rlimit_nofile 40000;
2121

22-
# Set SERVER_ENABLE_NGX_HTTP_JS=true to enable this module
23-
#load_module /usr/lib/nginx/modules/ngx_http_js_module.so;
22+
# Set Set SERVER_ENABLE_NGX_BROTLI=true to enable this module
23+
#load_module modules/ngx_http_brotli_filter_module.so;
24+
#load_module modules/ngx_http_brotli_static_module.so;
2425

26+
# Set SERVER_ENABLE_NGX_HTTP_JS=true to enable this module
27+
#load_module modules/ngx_http_js_module.so;
2528

2629
events {
2730
# Optimized to serve many clients with each thread, essential for linux
@@ -102,6 +105,12 @@ http {
102105

103106
#gzip on;
104107

108+
# Set SERVER_ENABLE_NGX_BROTLI=true to enable the following brotli settings
109+
#brotli on;
110+
#brotli_static on;
111+
#brotli_comp_level 6;
112+
#brotli_types application/javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font application/x-font-opentype application/x-font-otf application/x-font-truetype application/x-font-ttf application/xhtml+xml application/xml font/opentype font/otf font/ttf image/svg+xml image/x-icon text/css text/javascript text/plain text/xml;
113+
105114
client_body_temp_path /tmp/.nginx/client_body;
106115
fastcgi_temp_path /tmp/.nginx/fastcgi_temp;
107116
proxy_temp_path /tmp/.nginx/proxy_temp;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
file:
2+
/etc/nginx/nginx.conf:
3+
exists: true
4+
# By default, the brotli configs are specified in nginx.conf but disabled
5+
contains:
6+
- '/#load_module\s*modules\/ngx_http_brotli_filter_module\.so;/'
7+
- '/#load_module\s*modules\/ngx_http_brotli_static_module\.so;/'
8+
- '/#brotli\s*on;/'
9+
- '/#brotli_static\s*on;/'
10+
- '/#brotli_comp_level\s*6;/'
11+
- '/#brotli_types/'
12+
title: /etc/nginx/nginx.conf should exist and contain brotli-specific configs
13+
/usr/lib/nginx/modules/ngx_http_brotli_filter_module.so:
14+
exists: true
15+
owner: root
16+
title: /usr/lib/nginx/modules/ngx_http_brotli_filter_module.so should exist and owned by root
17+
/usr/lib/nginx/modules/ngx_http_brotli_static_module.so:
18+
exists: true
19+
owner: root
20+
title: /usr/lib/nginx/modules/ngx_http_brotli_static_module.so should exist and owned by root

container/root/tests/ubuntu/nginx.goss.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
gossfile:
22
/tests/common/nginx.goss.yaml: {}
3+
# To be enabled when we add support for Ubuntu 22.04
4+
# /tests/ubuntu/brotli.goss.yaml: {}
35

46
user:
57
www-data:

docs/env_vars.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@ SERVER_APP_NAME | SERVER_APP_NAME='view' | Gets appended to the default logging
1010
SERVER_GZIP_OPTIONS | SERVER_GZIP_OPTIONS=1 | Allows default set of static content to be served gzipped
1111
SERVER_SENDFILE | SERVER_SENDFILE=off | Allows runtime to specify value of nginx's `sendfile` (default, on)
1212
SERVER_ENABLE_HTTPS | SERVER_ENABLE_HTTPS=true | Enable encrypted transmission using certificates
13-
SERVER_ENABLE_NGX_HTTP_JS | SERVER_ENABLE_NGX_HTTP_JS=true | Enable nginx njs module (default, false)
13+
SERVER_ENABLE_NGX_BROTLI | SERVER_ENABLE_NGX_BROTLI=true | Enable Brotli compression (default: false)
14+
SERVER_ENABLE_NGX_HTTP_JS | SERVER_ENABLE_NGX_HTTP_JS=true | Enable nginx njs module (default: false)
1415
SERVER_KEEPALIVE | SERVER_KEEPALIVE=30 | Define HTTP 1.1's keepalive timeout
1516
SERVER_WORKER_PROCESSES | SERVER_WORKER_PROCESSES=4 | Set to the number of cores in the machine, or the number of cores allocated to container
1617
SERVER_WORKER_CONNECTIONS | SERVER_WORKER_CONNECTIONS=2048 | Sets up the number of connections for worker processes
1718
SERVER_CLIENT_HEADER_BUFFER_SIZE | SERVER_CLIENT_HEADER_BUFFER_SIZE=16k | [docs](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_buffer_size)
1819
SERVER_LARGE_CLIENT_HEADER_BUFFERS | SERVER_LARGE_CLIENT_HEADER_BUFFERS=8 16k | [docs](http://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers)
1920
SERVER_CLIENT_BODY_BUFFER_SIZE | SERVER_CLIENT_BODY_BUFFER_SIZE=128k | [docs](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size)
2021
SERVER_LOG_MINIMAL | SERVER_LOG_MINIMAL=1 | Minimize the logging format, appropriate for development environments
22+
SERVER_SHOW_NGINX_CONF | SERVER_SHOW_NGINX_CONF=true | Dump the contents of nginx.conf. Useful when debugging the config during start up (default: false)
2123
S6_KILL_FINISH_MAXTIME | S6_KILL_FINISH_MAXTIME=55000 | The maximum time (in ms) a script in /etc/cont-finish.d could take before sending a KILL signal to it. Take into account that this parameter will be used per each script execution, it's not a max time for the whole set of scripts. This value has a max of 65535 on Alpine variants.
2224
S6_KILL_GRACETIME | S6_KILL_GRACETIME=500 | Wait time (in ms) for S6 finish scripts before sending kill signal
2325

tests/brotli/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
FROM docker-nginx:brotli

tests/brotli/Makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.PHONY: build
2+
3+
# Name of the image to build
4+
IMAGE_TAG=docker-nginx:brotli
5+
6+
default: build
7+
8+
build-src:
9+
cd ../.. && docker build -t $(IMAGE_TAG) -f Dockerfile .
10+
11+
build: build-src
12+
docker build -t $(IMAGE_TAG)-test -f Dockerfile .
13+
14+
dgoss: build
15+
GOSS_WAIT_OPTS="-r 60s -s 5s > /dev/null" dgoss run -e SERVER_ENABLE_NGX_BROTLI=true -p 8080:8080 $(IMAGE_TAG)-test
16+

tests/brotli/README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
brotli
2+
====
3+
4+
This is a simple [dgoss] test to validate that the brotli module is running.
5+
6+
To test:
7+
8+
1. cd `tests/brotli`
9+
1. Run `make dgoss`
10+
11+
Behind the scenes, it builds the `brotli`-enabled docker image, then builds
12+
a test image.
13+
14+
Finally, it runs `dgoss` and passes in `Accept-Encoding: gzip, deflate, br`
15+
as part of the request.
16+
17+
Here's a sample curl request when `SERVER_ENABLE_NGX_BROTLI=true`:
18+
19+
```shell
20+
$ curl http://localhost:8080/ -v -H "Accept-Encoding: gzip, deflate, br"
21+
* Trying ::1...
22+
* TCP_NODELAY set
23+
* Connected to localhost (::1) port 8083 (#0)
24+
> GET / HTTP/1.1
25+
> Host: localhost:8080
26+
> User-Agent: curl/7.64.1
27+
> Accept: */*
28+
> Accept-Encoding: gzip, deflate, br
29+
>
30+
< HTTP/1.1 200 OK
31+
< Server: nginx
32+
< Date: Wed, 17 Aug 2022 21:41:21 GMT
33+
< Content-Type: text/html
34+
< Last-Modified: Wed, 17 Aug 2022 17:59:04 GMT
35+
< Transfer-Encoding: chunked
36+
< Connection: keep-alive
37+
< ETag: W/"62fd2c68-279"
38+
< X-XSS-Protection: 1; mode=block
39+
< X-Content-Type-Options: nosniff
40+
< Content-Encoding: br
41+
<
42+
Warning: Binary output can mess up your terminal. Use "--output -" to tell
43+
Warning: curl to output it to your terminal anyway, or consider "--output
44+
Warning: <FILE>" to save to a file.
45+
* Failed writing body (0 != 299)
46+
* Failed writing data
47+
* Closing connection 0
48+
```
49+
50+
The script assumes that you have `dgoss` installed.
51+
52+
[dgoss]: https://github.com/aelsabbahy/goss/blob/master/extras/dgoss/README.md

tests/brotli/goss.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
file:
2+
/etc/nginx/nginx.conf:
3+
exists: true
4+
contains:
5+
- '/load_module\s*modules\/ngx_http_brotli_filter_module\.so;/'
6+
- '/load_module\s*modules\/ngx_http_brotli_static_module\.so;/'
7+
- '/brotli\s*on;/'
8+
- '/brotli_static\s*on;/'
9+
- '/brotli_comp_level\s*6;/'
10+
- '/brotli_types/'
11+
title: brotli-specific modules and configs should be enabled
12+
http:
13+
http://localhost:8080/:
14+
status: 200
15+
allow-insecure: true
16+
request-headers:
17+
- "Accept-Encoding: gzip, deflate, br"
18+
timeout: 5000
19+
headers:
20+
# When you pass in the Accept-Encoding header
21+
# the response header will include "Content-Encoding: br"
22+
# and the output will be compressed/binary
23+
- "Content-Encoding: br"

tests/brotli/goss_wait.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
file:
2+
/goss/docker_output.log:
3+
exists: true
4+
contains:
5+
# When starting up the container, this line should show up
6+
# if SERVER_ENABLE_NGX_BROTLI=true
7+
- '[nginx] enabling nginx brotli module'

0 commit comments

Comments
 (0)