diff --git a/Dockerfile b/Dockerfile
index a20f2d36324fee46ce3a90f029ba9361839ab550..67876d05bf57addb564b5e6c48622c12719ef1ab 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:8 as builder
+FROM node:10 as builder
 
 ARG BACKEND_URL
 ENV BACKEND_URL=$BACKEND_URL
@@ -8,12 +8,23 @@ WORKDIR /iv
 
 ENV VERSION=devNext
 
+RUN apt update && apt upgrade -y && apt install brotli
+
 RUN npm i
 RUN npm run build-aot
 
+# gzipping container
+FROM ubuntu:18.10 as compressor
+RUN apt upgrade -y && apt update && apt install brotli
+
+RUN mkdir /iv
+COPY --from=builder /iv/dist/aot /iv
+WORKDIR /iv
+
+RUN for f in $(find . -type f); do gzip < $f > $f.gz && brotli < $f > $f.br; done
 
 # prod container
-FROM node:8-alpine 
+FROM node:10-alpine 
 
 ARG PORT
 ENV PORT=$PORT
@@ -23,14 +34,15 @@ RUN apk --no-cache add ca-certificates
 RUN mkdir /iv-app
 WORKDIR /iv-app
 
-# Copy built interactive viewer
-COPY --from=builder /iv/dist/aot ./public
-
 # Copy the express server
 COPY --from=builder /iv/deploy .
 
+# Copy built interactive viewer
+COPY --from=compressor /iv ./public
+
 # Copy the resources files needed to respond to queries
-COPY --from=builder /iv/src/res/ext ./res
+# is this even necessary any more?
+COPY --from=compressor /iv/res/json ./res
 RUN npm i
 
 EXPOSE $PORT
diff --git a/deploy/app.js b/deploy/app.js
index 8b815a3607c836f6810190d68ffb632916bc2ba5..0d97f9469a8acb9002ba53b23f8517b16c39b990 100644
--- a/deploy/app.js
+++ b/deploy/app.js
@@ -62,6 +62,7 @@ const PUBLIC_PATH = process.env.NODE_ENV === 'production'
  */
 app.use('/.well-known', express.static(path.join(__dirname, 'well-known')))
 
+app.use(require('./compression'))
 app.use(express.static(PUBLIC_PATH))
 
 app.use((req, res, next) => {
diff --git a/deploy/compression/index.js b/deploy/compression/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..0136f68687ec7ad592b7c7f27e103a0f6020375a
--- /dev/null
+++ b/deploy/compression/index.js
@@ -0,0 +1,43 @@
+const BROTLI = `br`
+const GZIP = `gzip`
+
+const detEncoding = (acceptEncoding) => /br/i.test(acceptEncoding)
+  ? BROTLI
+  : /gzip/i.test(acceptEncoding)
+    ? GZP
+    : null
+
+const mimeMap = new Map([
+  ['.png', 'image/png'],
+  ['.gif', 'image/gif'],
+  ['.jpg', 'image/jpeg'],
+  ['.jpeg', 'image/jpeg'],
+  ['.css', 'text/css'],
+  ['.html', 'text/html'],
+  ['.js', 'text/javascript']
+])
+
+module.exports = (req, res, next) => {
+  const acceptEncoding = req.get('Accept-Encoding')
+  const encoding = detEncoding(acceptEncoding)
+  
+  const ext = /(\.\w*?)$/.exec(req.url)
+
+  if (!ext || !mimeMap.get(ext[1])) return next()
+  
+  if (encoding === BROTLI) {
+    req.url = req.url + '.br'
+    res.set('Content-Encoding', encoding)
+    res.set('Content-Type', mimeMap.get(ext[1]))
+    return next()
+  }
+
+  if (encoding === GZIP) {
+    req.url = req.url + '.gz'
+    res.set('Content-Encoding', encoding)
+    res.set('Content-Type', mimeMap.get(ext[1]))
+    return next()
+  }
+
+  next()
+}
\ No newline at end of file