From 1211eb6f7efebdb3f47cc53511a0adb75b9bfd3b Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 20 Oct 2021 06:15:37 -0300 Subject: [PATCH 1/4] Enable gzip on production image --- nginx.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nginx.conf b/nginx.conf index 932cfeb..78f630e 100644 --- a/nginx.conf +++ b/nginx.conf @@ -2,6 +2,9 @@ server { listen 80; server_name localhost; + gzip on; + gzip_types application/javascript text/css; + #access_log /var/log/nginx/host.access.log main; location /static { From 7dac2e179e4f3285d015420316f896e585f85267 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 20 Oct 2021 11:34:35 -0300 Subject: [PATCH 2/4] Change nginx configdir layout --- Dockerfile | 2 +- nginx.conf => nginx/conf.d/default.conf | 0 package.json | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename nginx.conf => nginx/conf.d/default.conf (100%) diff --git a/Dockerfile b/Dockerfile index e113ddb..1ceb407 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,7 +28,7 @@ RUN 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/ -COPY nginx.conf /etc/nginx/conf.d/default.conf +COPY nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf COPY --from=builder /otterscan-build/build /usr/share/nginx/html/ COPY --from=builder /otterscan-build/run-nginx.sh / WORKDIR / diff --git a/nginx.conf b/nginx/conf.d/default.conf similarity index 100% rename from nginx.conf rename to nginx/conf.d/default.conf diff --git a/package.json b/package.json index 3b0c375..71e9d47 100644 --- a/package.json +++ b/package.json @@ -52,8 +52,8 @@ "test": "craco test", "eject": "react-scripts eject", "source-map-explorer": "source-map-explorer build/static/js/*.js", - "assets-start": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/signatures:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", - "assets-start-with-param-names": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/with_parameter_names:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", + "assets-start": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/signatures:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", + "assets-start-with-param-names": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/with_parameter_names:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", "assets-stop": "docker stop otterscan-assets", "docker-build": "DOCKER_BUILDKIT=1 docker build -t otterscan -f Dockerfile .", "docker-start": "docker run --rm -p 5000:80 --name otterscan -d otterscan", From 656fbdcc8003c91e4631a63af1a8370eb3d5c5b0 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 20 Oct 2021 11:45:58 -0300 Subject: [PATCH 3/4] Externalize default nginx.conf from docker image to allow further customization --- Dockerfile | 1 + nginx/nginx.conf | 31 +++++++++++++++++++++++++++++++ package.json | 4 ++-- 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 nginx/nginx.conf diff --git a/Dockerfile b/Dockerfile index 1ceb407..8f44312 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,7 @@ 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/ COPY nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf +COPY nginx/nginx.conf /etc/nginx/nginx.conf COPY --from=builder /otterscan-build/build /usr/share/nginx/html/ COPY --from=builder /otterscan-build/run-nginx.sh / WORKDIR / diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..876db0f --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,31 @@ +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/conf.d/*.conf; +} diff --git a/package.json b/package.json index 71e9d47..c47808d 100644 --- a/package.json +++ b/package.json @@ -52,8 +52,8 @@ "test": "craco test", "eject": "react-scripts eject", "source-map-explorer": "source-map-explorer build/static/js/*.js", - "assets-start": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/signatures:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", - "assets-start-with-param-names": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/with_parameter_names:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", + "assets-start": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/signatures:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf -v$(pwd)/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", + "assets-start-with-param-names": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/with_parameter_names:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf -v$(pwd)/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", "assets-stop": "docker stop otterscan-assets", "docker-build": "DOCKER_BUILDKIT=1 docker build -t otterscan -f Dockerfile .", "docker-start": "docker run --rm -p 5000:80 --name otterscan -d otterscan", From a8a174928829e528ab21783f372e86cee63e0993 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 20 Oct 2021 15:44:27 -0300 Subject: [PATCH 4/4] 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"