From a8a174928829e528ab21783f372e86cee63e0993 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 20 Oct 2021 15:44:27 -0300 Subject: [PATCH] Enable gzip/brotli precompressed artifacts in the production docker image --- Dockerfile | 65 +++++++++++++++++++++++++++++++++++++-- nginx/conf.d/default.conf | 5 +-- nginx/nginx.conf | 1 + package-lock.json | 38 +++++++++++++++++++++++ package.json | 3 +- 5 files changed, 107 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8f44312..aec42e4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,8 +23,69 @@ FROM alpine:3.14.0 AS topic0builder WORKDIR /topic0 COPY topic0/with_parameter_names /topic0/ -FROM nginx:1.21.1-alpine -RUN apk add jq +# Add brotli module to official nginx image +# Based on: https://github.com/nginxinc/docker-nginx/tree/master/modules +FROM nginx:1.21.3-alpine as nginxbuilder + +RUN set -ex \ + && apk update \ + && apk add linux-headers openssl-dev pcre-dev zlib-dev openssl abuild \ + musl-dev libxslt libxml2-utils make mercurial gcc unzip git \ + xz g++ coreutils \ + # allow abuild as a root user \ + && printf "#!/bin/sh\\nSETFATTR=true /usr/bin/abuild -F \"\$@\"\\n" > /usr/local/bin/abuild \ + && chmod +x /usr/local/bin/abuild \ + && hg clone -r ${NGINX_VERSION}-${PKG_RELEASE} https://hg.nginx.org/pkg-oss/ \ + && cd pkg-oss \ + && mkdir /tmp/packages \ + && for module in "brotli"; do \ + echo "Building $module for nginx-$NGINX_VERSION"; \ + if [ -d /modules/$module ]; then \ + echo "Building $module from user-supplied sources"; \ + # check if module sources file is there and not empty + if [ ! -s /modules/$module/source ]; then \ + echo "No source file for $module in modules/$module/source, exiting"; \ + exit 1; \ + fi; \ + # some modules require build dependencies + if [ -f /modules/$module/build-deps ]; then \ + echo "Installing $module build dependencies"; \ + apk update && apk add $(cat /modules/$module/build-deps | xargs); \ + fi; \ + # if a module has a build dependency that is not in a distro, provide a + # shell script to fetch/build/install those + # note that shared libraries produced as a result of this script will + # not be copied from the builder image to the main one so build static + if [ -x /modules/$module/prebuild ]; then \ + echo "Running prebuild script for $module"; \ + /modules/$module/prebuild; \ + fi; \ + /pkg-oss/build_module.sh -v $NGINX_VERSION -f -y -o /tmp/packages -n $module $(cat /modules/$module/source); \ + BUILT_MODULES="$BUILT_MODULES $(echo $module | tr '[A-Z]' '[a-z]' | tr -d '[/_\-\.\t ]')"; \ + elif make -C /pkg-oss/alpine list | grep -E "^$module\s+\d+" > /dev/null; then \ + echo "Building $module from pkg-oss sources"; \ + cd /pkg-oss/alpine; \ + make abuild-module-$module BASE_VERSION=$NGINX_VERSION NGINX_VERSION=$NGINX_VERSION; \ + apk add $(. ./abuild-module-$module/APKBUILD; echo $makedepends;); \ + make module-$module BASE_VERSION=$NGINX_VERSION NGINX_VERSION=$NGINX_VERSION; \ + find ~/packages -type f -name "*.apk" -exec mv -v {} /tmp/packages/ \;; \ + BUILT_MODULES="$BUILT_MODULES $module"; \ + else \ + echo "Don't know how to build $module module, exiting"; \ + exit 1; \ + fi; \ + done \ + && echo "BUILT_MODULES=\"$BUILT_MODULES\"" > /tmp/packages/modules.env + +FROM nginx:1.21.3-alpine +COPY --from=nginxbuilder /tmp/packages /tmp/packages +RUN set -ex \ + && . /tmp/packages/modules.env \ + && for module in $BUILT_MODULES; do \ + apk add --no-cache --allow-untrusted /tmp/packages/nginx-module-${module}-${NGINX_VERSION}*.apk; \ + done \ + && rm -rf /tmp/packages +RUN apk update && apk add jq COPY --from=topic0builder /topic0 /usr/share/nginx/html/topic0/ COPY --from=fourbytesbuilder /signatures /usr/share/nginx/html/signatures/ COPY --from=logobuilder /assets /usr/share/nginx/html/assets/ diff --git a/nginx/conf.d/default.conf b/nginx/conf.d/default.conf index 78f630e..b5d141b 100644 --- a/nginx/conf.d/default.conf +++ b/nginx/conf.d/default.conf @@ -2,8 +2,7 @@ server { listen 80; server_name localhost; - gzip on; - gzip_types application/javascript text/css; + gzip_static on; #access_log /var/log/nginx/host.access.log main; @@ -118,6 +117,8 @@ server { root /usr/share/nginx/html; index index.html; try_files $uri /index.html; + + brotli_static on; } #error_page 404 /404.html; diff --git a/nginx/nginx.conf b/nginx/nginx.conf index 876db0f..7364514 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -4,6 +4,7 @@ worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; +load_module modules/ngx_http_brotli_static_module.so; events { worker_connections 1024; diff --git a/package-lock.json b/package-lock.json index 178efba..380547a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,6 +53,7 @@ }, "devDependencies": { "autoprefixer": "^9.8.8", + "compress-create-react-app": "^1.1.3", "postcss": "^7.0.39", "source-map-explorer": "^2.5.2", "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.6" @@ -3910,6 +3911,15 @@ "node": ">=0.10.0" } }, + "node_modules/app-root-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", + "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/aproba": { "version": "1.2.0", "license": "ISC" @@ -5969,6 +5979,19 @@ "arity-n": "^1.0.4" } }, + "node_modules/compress-create-react-app": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/compress-create-react-app/-/compress-create-react-app-1.1.3.tgz", + "integrity": "sha512-3HCWi9q7TqxBvklmJY/Pm96Fs8wqEXxduW3LGlK0PUYuezZwKkjB454GjyGhjKmxKpl91Q9b2+ZjXeKdNOIhlA==", + "dev": true, + "dependencies": { + "app-root-path": "^3.0.0" + }, + "bin": { + "compress-cra": "index.js", + "compress-create-react-app": "index.js" + } + }, "node_modules/compressible": { "version": "2.0.18", "license": "MIT", @@ -22192,6 +22215,12 @@ } } }, + "app-root-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", + "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", + "dev": true + }, "aproba": { "version": "1.2.0" }, @@ -23645,6 +23674,15 @@ "arity-n": "^1.0.4" } }, + "compress-create-react-app": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/compress-create-react-app/-/compress-create-react-app-1.1.3.tgz", + "integrity": "sha512-3HCWi9q7TqxBvklmJY/Pm96Fs8wqEXxduW3LGlK0PUYuezZwKkjB454GjyGhjKmxKpl91Q9b2+ZjXeKdNOIhlA==", + "dev": true, + "requires": { + "app-root-path": "^3.0.0" + } + }, "compressible": { "version": "2.0.18", "requires": { diff --git a/package.json b/package.json index c47808d..152fe75 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ }, "scripts": { "start": "craco start", - "build": "craco build", + "build": "craco build && compress-cra", "test": "craco test", "eject": "react-scripts eject", "source-map-explorer": "source-map-explorer build/static/js/*.js", @@ -79,6 +79,7 @@ }, "devDependencies": { "autoprefixer": "^9.8.8", + "compress-create-react-app": "^1.1.3", "postcss": "^7.0.39", "source-map-explorer": "^2.5.2", "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.6"