Skip to content

Commit

Permalink
feat(ETHOS-39682): Add goss and basic tests
Browse files Browse the repository at this point in the history
* Parameterize NGINX_VERSION
* Rename SERVER_ENABLE_BROTLI to SERVER_ENABLE_NGX_BROTLI
* Add SERVER_SHOW_NGINX_CONF to help with debugging
* Fix sed for SERVER_ENABLE_NGX_HTTP_JS
* Update nginx.conf with the brotli modules and configuration
* Add brotli goss test
* Add dgoss test for testing the brotli module
  • Loading branch information
Jan Michael Ong committed Aug 17, 2022
1 parent ca1521a commit 1a8764f
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 17 deletions.
9 changes: 7 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ FROM behance/docker-base:5.0.1-ubuntu-20.04

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

Expand All @@ -23,9 +28,9 @@ RUN /bin/bash -e /security_updates.sh && \
add-apt-repository ppa:ondrej/nginx -y && \
apt-get update -yqq && \
apt-get install -yqq --no-install-recommends \
nginx-light=1.22.0-* \
nginx-light=${NGINX_VERSION}-* \
ca-certificates \
libnginx-mod-brotli=1.22.0-* \
libnginx-mod-brotli=${NGINX_VERSION}-* \
&& \
apt-get remove --purge -yq \
manpages \
Expand Down
40 changes: 28 additions & 12 deletions container/root/etc/cont-init.d/10-nginx-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,6 @@ then
sed -i "s/\#gzip/gzip/" $CONF_NGINX_SERVER
fi

if [[ $SERVER_ENABLE_BROTLI ]]
then
echo "[nginx] enabling brotli"
TYPES_TO_COMPRESS="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;"
sed -i "s|#plugins_placeholder|#plugins_placeholder\nload_module modules/ngx_http_brotli_filter_module.so;\nload_module modules/ngx_http_brotli_static_module.so;\n|" $CONF_NGINX_SERVER
sed -i "s/#brotli on;/brotli on;\n\
brotli_static on;\n\
brotli_comp_level 6;\n\
brotli_types ${TYPES_TO_COMPRESS}/" $CONF_NGINX_SERVER
fi

if [[ $SERVER_KEEPALIVE ]]
then
echo "[nginx] setting keepalive ${SERVER_KEEPALIVE}"
Expand Down Expand Up @@ -95,8 +84,35 @@ then
sed -i "s/^[ ]*listen ${CONTAINER_PORT}/ listen ${CONTAINER_PORT} ssl/" $CONF_NGINX_SITE
fi

if [[ $SERVER_ENABLE_NGX_BROTLI ]];
then
echo "[nginx] enabling nginx brotli module"
# Enable the brotli module
sed -i "s/#load_module modules\/ngx_http_brotli_/load_module modules\/ngx_http_brotli_/" $CONF_NGINX_SERVER

# Enable brotli-specific configuration. All brotli configs begin with brotli*
# Ref: https://github.com/google/ngx_brotli
sed -i "s/#brotli/brotli/" $CONF_NGINX_SERVER
fi

if [[ $SERVER_ENABLE_NGX_HTTP_JS ]];
then
# Enable the njs module
echo "[nginx] enabling nginx njs module"
sed -i "s/#load_module/load_module/" $CONF_NGINX_SERVER
sed -i "s/#load_module modules\/ngx_http_js_/load_module modules\/ngx_http_js_/" $CONF_NGINX_SERVER
fi

# Useful when you need to debug the contents of nginx.conf
#
# Should be the last entry in this script to ensure that all prior
# modifications have been applied
if [[ $SERVER_SHOW_NGINX_CONF ]];
then
if [[ -f "$CONF_NGINX_SERVER" ]];
then
echo ""
echo "*** SERVER_SHOW_NGINX_CONF is set. Dumping $CONF_NGINX_SERVER ***"
echo ""
cat $CONF_NGINX_SERVER
fi
fi
12 changes: 10 additions & 2 deletions container/root/etc/nginx/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ error_log /dev/stdout warn;
# Number of file descriptors used for nginx
worker_rlimit_nofile 40000;

#plugins_placeholder
# Set Set SERVER_ENABLE_NGX_BROTLI=true to enable this module
#load_module modules/ngx_http_brotli_filter_module.so;
#load_module modules/ngx_http_brotli_static_module.so;

# Set SERVER_ENABLE_NGX_HTTP_JS=true to enable this module
#load_module /usr/lib/nginx/modules/ngx_http_js_module.so;
#load_module modules/ngx_http_js_module.so;

events {
# Optimized to serve many clients with each thread, essential for linux
Expand Down Expand Up @@ -101,7 +104,12 @@ http {
keepalive_timeout 65;

#gzip on;

# Set SERVER_ENABLE_NGX_BROTLI=true to enable the following brotli settings
#brotli on;
#brotli_static on;
#brotli_comp_level 6;
#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;

client_body_temp_path /tmp/.nginx/client_body;
fastcgi_temp_path /tmp/.nginx/fastcgi_temp;
Expand Down
20 changes: 20 additions & 0 deletions container/root/tests/ubuntu/brotli.goss.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
file:
/etc/nginx/nginx.conf:
exists: true
# By default, the brotli configs are specified in nginx.conf but disabled
contains:
- '/#load_module\s*modules\/ngx_http_brotli_filter_module\.so;/'
- '/#load_module\s*modules\/ngx_http_brotli_static_module\.so;/'
- '/#brotli\s*on;/'
- '/#brotli_static\s*on;/'
- '/#brotli_comp_level\s*6;/'
- '/#brotli_types/'
title: /etc/nginx/nginx.conf should exist and contain brotli-specific configs
/usr/lib/nginx/modules/ngx_http_brotli_filter_module.so:
exists: true
owner: root
title: /usr/lib/nginx/modules/ngx_http_brotli_filter_module.so should exist and owned by root
/usr/lib/nginx/modules/ngx_http_brotli_static_module.so:
exists: true
owner: root
title: /usr/lib/nginx/modules/ngx_http_brotli_static_module.so should exist and owned by root
2 changes: 2 additions & 0 deletions container/root/tests/ubuntu/nginx.goss.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
gossfile:
/tests/common/nginx.goss.yaml: {}
# To be enabled when we add support for Ubuntu 22.04
# /tests/ubuntu/brotli.goss.yaml: {}

user:
www-data:
Expand Down
4 changes: 3 additions & 1 deletion docs/env_vars.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ SERVER_APP_NAME | SERVER_APP_NAME='view' | Gets appended to the default logging
SERVER_GZIP_OPTIONS | SERVER_GZIP_OPTIONS=1 | Allows default set of static content to be served gzipped
SERVER_SENDFILE | SERVER_SENDFILE=off | Allows runtime to specify value of nginx's `sendfile` (default, on)
SERVER_ENABLE_HTTPS | SERVER_ENABLE_HTTPS=true | Enable encrypted transmission using certificates
SERVER_ENABLE_NGX_HTTP_JS | SERVER_ENABLE_NGX_HTTP_JS=true | Enable nginx njs module (default, false)
SERVER_ENABLE_NGX_BROTLI | SERVER_ENABLE_NGX_BROTLI=true | Enable Brotli compression (default: false)
SERVER_ENABLE_NGX_HTTP_JS | SERVER_ENABLE_NGX_HTTP_JS=true | Enable nginx njs module (default: false)
SERVER_KEEPALIVE | SERVER_KEEPALIVE=30 | Define HTTP 1.1's keepalive timeout
SERVER_WORKER_PROCESSES | SERVER_WORKER_PROCESSES=4 | Set to the number of cores in the machine, or the number of cores allocated to container
SERVER_WORKER_CONNECTIONS | SERVER_WORKER_CONNECTIONS=2048 | Sets up the number of connections for worker processes
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)
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)
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)
SERVER_LOG_MINIMAL | SERVER_LOG_MINIMAL=1 | Minimize the logging format, appropriate for development environments
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)
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.
S6_KILL_GRACETIME | S6_KILL_GRACETIME=500 | Wait time (in ms) for S6 finish scripts before sending kill signal

Expand Down
1 change: 1 addition & 0 deletions tests/brotli/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FROM docker-nginx:brotli
16 changes: 16 additions & 0 deletions tests/brotli/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.PHONY: build

# Name of the image to build
IMAGE_TAG=docker-nginx:brotli

default: build

build-src:
cd ../.. && docker build -t $(IMAGE_TAG) -f Dockerfile .

build: build-src
docker build -t $(IMAGE_TAG)-test -f Dockerfile .

dgoss: build
GOSS_WAIT_OPTS="-r 60s -s 5s > /dev/null" dgoss run -e SERVER_ENABLE_NGX_BROTLI=true -p 8080:8080 $(IMAGE_TAG)-test

52 changes: 52 additions & 0 deletions tests/brotli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
brotli
====

This is a simple [dgoss] test to validate that the brotli module is running.

To test:

1. cd `tests/brotli`
1. Run `make dgoss`

Behind the scenes, it builds the `brotli`-enabled docker image, then builds
a test image.

Finally, it runs `dgoss` and passes in `Accept-Encoding: gzip, deflate, br`
as part of the request.

Here's a sample curl request when `SERVER_ENABLE_NGX_BROTLI=true`:

```shell
$ curl http://localhost:8080/ -v -H "Accept-Encoding: gzip, deflate, br"
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8083 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
> Accept-Encoding: gzip, deflate, br
>
< HTTP/1.1 200 OK
< Server: nginx
< Date: Wed, 17 Aug 2022 21:41:21 GMT
< Content-Type: text/html
< Last-Modified: Wed, 17 Aug 2022 17:59:04 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
< ETag: W/"62fd2c68-279"
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< Content-Encoding: br
<
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
* Failed writing body (0 != 299)
* Failed writing data
* Closing connection 0
```
The script assumes that you have `dgoss` installed.
[dgoss]: https://github.com/aelsabbahy/goss/blob/master/extras/dgoss/README.md
23 changes: 23 additions & 0 deletions tests/brotli/goss.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
file:
/etc/nginx/nginx.conf:
exists: true
contains:
- '/load_module\s*modules\/ngx_http_brotli_filter_module\.so;/'
- '/load_module\s*modules\/ngx_http_brotli_static_module\.so;/'
- '/brotli\s*on;/'
- '/brotli_static\s*on;/'
- '/brotli_comp_level\s*6;/'
- '/brotli_types/'
title: brotli-specific modules and configs should be enabled
http:
http://localhost:8080/:
status: 200
allow-insecure: true
request-headers:
- "Accept-Encoding: gzip, deflate, br"
timeout: 5000
headers:
# When you pass in the Accept-Encoding header
# the response header will include "Content-Encoding: br"
# and the output will be compressed/binary
- "Content-Encoding: br"
7 changes: 7 additions & 0 deletions tests/brotli/goss_wait.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
file:
/goss/docker_output.log:
exists: true
contains:
# When starting up the container, this line should show up
# if SERVER_ENABLE_NGX_BROTLI=true
- '[nginx] enabling nginx brotli module'

0 comments on commit 1a8764f

Please sign in to comment.