diff --git a/.github/workflows/docker_img.yml b/.github/workflows/docker_img.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a4db882dd1b3455b742dece71837b6c3bf4b7e5f
--- /dev/null
+++ b/.github/workflows/docker_img.yml
@@ -0,0 +1,70 @@
+name: '[docker image]'
+
+on: [ 'push' ]
+
+jobs:
+  build-docker-img:
+    
+    runs-on: ubuntu-latest
+
+    env:
+      MATOMO_ID_DEV: '7'
+      MATAMO_URL_DEV: 'https://stats-dev.humanbrainproject.eu/'
+      MATOMO_ID_PROD: '12'
+      MATAMO_URL_PROD: 'https://stats.humanbrainproject.eu/'
+      PRODUCTION: 'true'
+      DOCKER_REGISTRY: 'docker-registry.ebrains.eu/siibra-explorer/'
+
+    steps:
+    - uses: actions/checkout@v2
+    - name: 'Set matomo env var'
+      run: |
+        echo "Using github.ref: $GITHUB_REF"
+
+        echo "BRANCH_NAME=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
+        
+        if [[ "$GITHUB_REF" == 'refs/heads/master' ]] || [[ "$GITHUB_REF" == 'refs/heads/staging' ]]
+        then
+          echo "Either master or staging, using prod env..."
+          echo "MATAMO_URL=${{ env.MATAMO_URL_PROD }}" >> $GITHUB_ENV
+          echo "MATOMO_ID=${{ env.MATOMO_ID_PROD }}" >> $GITHUB_ENV
+
+        else
+          echo "Using dev env..."
+          echo "MATAMO_URL=${{ env.MATAMO_URL_DEV }}" >> $GITHUB_ENV
+          echo "MATOMO_ID=${{ env.MATOMO_ID_DEV }}" >> $GITHUB_ENV
+        fi
+
+    - name: 'Set version variable'
+      run: |
+        if [[ "$GITHUB_REF" == 'refs/heads/master' ]] || [[ "$GITHUB_REF" == 'refs/heads/staging' ]]
+        then
+          echo "Either master or staging, using package.json"
+          VERSION=$(jq -r '.version' package.json)
+        else
+          echo "Using git hash"
+          VERSION=$(git rev-parse --short HEAD)
+        fi
+        echo "VERSION=$VERSION" >> $GITHUB_ENV
+    - name: 'Build docker image'
+      run: |
+        DOCKER_BUILT_TAG=${{ env.DOCKER_REGISTRY }}siibra-explorer:$BRANCH_NAME
+        echo "Building $DOCKER_BUILT_TAG"
+        docker build \
+          --build-arg VERSION=$VERSION \
+          --build-arg MATAMO_URL=$MATAMO_URL \
+          --build-arg MATAMO_ID=$MATAMO_ID \
+          -t $DOCKER_BUILT_TAG \
+          .
+        echo "Successfully built $DOCKER_BUILT_TAG"
+        echo "DOCKER_BUILT_TAG=$DOCKER_BUILT_TAG" >> $GITHUB_ENV
+
+    - name: 'Push to docker registry'
+      run: |
+        echo "Login to docker registry"
+        docker login \
+          -u "${{ secrets.EBRAINS_DOCKER_REG_USER }}" \
+          -p "${{ secrets.EBRAINS_DOCKER_REG_TOKEN }}" \
+          docker-registry.ebrains.eu
+        echo "Pushing $DOCKER_BUILT_TAG"
+        docker push $DOCKER_BUILT_TAG
diff --git a/Dockerfile b/Dockerfile
index 7c9bd9f950c437b328f4ba41a9ca59177da4a795..8506687bb8aad14ad1d72bb08c301cb017c8b73b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -18,6 +18,9 @@ ENV KIOSK_MODE=${KIOSK_MODE:-false}
 COPY . /iv
 WORKDIR /iv
 
+# When building in local, where node_module already exist, prebuilt binary may throw an error
+RUN rm -rf ./node_modules
+
 ARG VERSION
 ENV VERSION=${VERSION}
 
@@ -34,15 +37,6 @@ WORKDIR /iv
 
 RUN for f in $(find . -type f); do gzip < $f > $f.gz && brotli < $f > $f.br; done
 
-# Building doc
-FROM python:3.7 as doc-builder
-
-COPY . /iav
-WORKDIR /iav
-
-RUN pip install mkdocs mkdocs-material mdx_truly_sane_lists errandkun
-RUN mkdocs build
-
 # prod container
 FROM node:12-alpine 
 
@@ -61,12 +55,15 @@ COPY --from=builder /iv/deploy .
 # Copy built interactive viewer
 COPY --from=compressor /iv ./public
 
-# Copy docs
-COPY --from=doc-builder /iav/site ./docs
-
 # Copy the resources files needed to respond to queries
 # is this even necessary any more?
 COPY --from=compressor /iv/res/json ./res
+
+RUN chown -R node:node /iv-app
+
+USER node
 RUN npm i
 
-ENTRYPOINT [ "node", "server.js" ]
\ No newline at end of file
+EXPOSE 3000
+ENV PORT 3000
+ENTRYPOINT [ "node", "server.js" ]
diff --git a/README.md b/README.md
index cd293c3bff01b68474c9fa7389e4961a01e1914a..c6e738a0957b6dc71ebe988167863aff00f053a6 100644
--- a/README.md
+++ b/README.md
@@ -7,140 +7,32 @@ Interactive Atlas Viewer is an frontend module wrapping around [nehuba](https://
 A live version of the Interactive Atlas Viewer is available at [https://interactive-viewer.apps.hbp.eu](https://interactive-viewer.apps.hbp.eu). This section is useful for developers who would like to develop this project.
 
 ### General information
+
 Interactive atlas viewer is built with [Angular (v9.0)](https://angular.io/), [Bootstrap (v4)](http://getbootstrap.com/), and [fontawesome icons](https://fontawesome.com/). Some other notable packages used are [ngrx/store](https://github.com/ngrx/platform) for state management. 
 
 Releases newer than [v0.2.9](https://github.com/HumanBrainProject/interactive-viewer/tree/v0.2.9) also uses a nodejs backend, which uses [passportjs](http://www.passportjs.org/) for user authentication, [express](https://expressjs.com/) as a http framework.
 
-### Develop viewer
+### Develop
 
 #### Prerequisites
 
 - node >= 12
 
-#### Buildtime environments
+#### Environments
 
 It is recommended to manage your environments with `.env` file.
 
-As interactive atlas viewer uses [webpack define plugin](https://webpack.js.org/plugins/define-plugin/), where necessary, the environmental variables are `JSON.stringify`'ed and directly replaced in the code.
-
-| name | description | default | example |
-| --- | --- | --- | --- |
-| `VERSION` | printed in console on viewer startup | `GIT_HASH` \|\| unspecificed hash | v2.2.2 |
-| `PRODUCTION` | if the build is for production, toggles optimisations such as minification | `undefined` | true |
-| `BACKEND_URL` | backend that the viewer calls to fetch available template spaces, parcellations, plugins, datasets | `null` | https://interactive-viewer.apps.hbp.eu/ |
-| `BS_REST_URL` | [brainscape-api](https://jugit.fz-juelich.de/v.marcenko/brainscapes-api) used to fetch different resources | https://brainscapes.apps-dev.hbp.eu/v1_0 |
-| `DATASET_PREVIEW_URL` | dataset preview url used by component <https://github.com/fzj-inm1-bda/kg-dataset-previewer>. Useful for diagnosing issues with dataset previews.| https://hbp-kg-dataset-previewer.apps.hbp.eu/datasetPreview | http://localhost:1234/datasetPreview |
-| `MATOMO_URL` | base url for matomo analytics | `null` | https://example.com/matomo/ |
-| `MATOMO_ID` | application id for matomo analytics | `null` | 6 |
-| `STRICT_LOCAL` | hides **Explore** and **Download** buttons. Useful for offline demo's | `false` | `true` |
-| `KIOSK_MODE` | after 5 minutes of inactivity, shows overlay inviting users to interact | `false` | `true` |
-| `BUILD_TEXT` | overlay text at bottom right of the viewer. set to `''` to hide. | |
+##### Buildtime environments
 
-#### Deploy environments
+Please see [build_env.md](build_env.md)
 
-It is recommended to manage your environments with `.env` file.
+##### Deploy environments
 
-##### Application
-
-| name | description | default | example |
-| --- | --- | --- | --- |
-| `PORT` | port to listen on | 3000 |
-| `HOST_PATHNAME` | pathname to listen on, restrictions: leading slash, no trailing slash | `''` | `/viewer` |
-| `SESSIONSECRET` | session secret for cookie session |
-| `NODE_ENV` | determines where the built viewer will be served from | | `production` |
-| `PRECOMPUTED_SERVER` | redirect data uri to another server. Useful for offline demos | | `http://localhost:8080/precomputed/` |
-| `LOCAL_CDN` | rewrite cdns to local server. useful for offlnie demo | | `http://localhost:7080/` |
-| `PLUGIN_URLS` | semi colon separated urls to be returned when user queries plugins | `''`
-| `STAGING_PLUGIN_URLS` | semi colon separated urls to be returned when user queries plugins | `''`
-| `USE_LOGO` | possible values are `hbp`, `ebrains`, `fzj` | `hbp` | `ebrains` |
-
-##### ebrains user authentication
-
-| name | description | default | example |
-| --- | --- | --- | --- |
-| `HOSTNAME` | 
-| `HBP_CLIENTID` | `{HOSTNAME}{HOST_PATHNAME}/hbp-oidc/cb` |
-| `HBP_CLIENTSECRET` |
-| `HBP_CLIENTID_V2` | `{HOSTNAME}{HOST_PATHNAME}/hbp-oidc-v2/cb`
-| `HBP_CLIENTSECRET_V2` | 
-
-##### Querying ebrains knowledge graph
-
-| name | description | default | example |
-| --- | --- | --- | --- |
-| `REFRESH_TOKEN` |
-| `ACCESS_TOKEN` | **nb** as access tokens are usually short lived, this should only be set for development purposes 
-| `CACHE_DATASET_FILENAME` | | `deploy/dataset/cachedKgDataset.json` |
-| `KG_ROOT` | | `https://kg.humanbrainproject.eu/query` |
-| `KG_SEARCH_VOCAB` | | `https://schema.hbp.eu/myQuery/` |
-| `KG_DATASET_SEARCH_QUERY_NAME` | | `interactiveViewerKgQuery-v0_3` |
-| `KG_DATASET_SEARCH_PATH` | | `/minds/core/dataset/v1.0.0` |
-| `KG_SEARCH_SIZE` | | `1000` |
-| `KG_SPATIAL_DATASET_SEARCH_QUERY_NAME` | | `iav-spatial-query-v2` |
-| `KG_SPATIAL_DATASET_SEARCH_PATH` | | `/neuroglancer/seeg/coordinate/v1.0.0` | 
-
-##### Logging
-
-| name | description | default | example |
-| --- | --- | --- | --- |
-| `FLUENT_PROTOCOL` | protocol for fluent logging | `http` |
-| `FLUENT_HOST` | host for fluent logging | `localhost` |
-| `FLUENT_PORT` | port for fluent logging | 24224 |
-| `IAV_NAME` | application name to be logged | `IAV` | 
-| `IAV_STAGE` | deploy of the application | `unnamed-stage` |
-
-##### CSP
-
-| name | description | default | example |
-| --- | --- | --- | --- |
-| `DISABLE_CSP` | disable csp | | `true` |
-| `CSP_REPORT_URI` | report uri for csp violations | `/report-violation` |
-| `NODE_ENV` | set to `production` to disable [`reportOnly`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only) | `null` |
-| `SCRIPT_SRC` | `JSON.stringify`'ed array of allowed scriptSrc | `[]` |
-| `CSP_CONNECT_SRC` | `JSON.stringify`'ed array of allowed dataSrc | `[]` |
-| `WHITE_LIST_SRC` | `JSON.stringify`'ed array of allowed src | `[]` |
-| `PROXY_HOSTNAME_WHITELIST` |
-
-##### Rate limiting
-
-| name | description | default | example |
-| --- | --- | --- | --- |
-| `REDIS_PROTO` | fall back to `REDIS_RATE_LIMITING_DB_EPHEMERAL_PORT_6379_TCP_PROTO` |
-| `REDIS_ADDR` | fall back to `REDIS_RATE_LIMITING_DB_EPHEMERAL_PORT_6379_TCP_ADDR` |
-| `REDIS_PORT` | fall back to `REDIS_RATE_LIMITING_DB_EPHEMERAL_PORT_6379_TCP_PORT` |
-| `REDIS_USERNAME` |
-| `REDIS_PASSWORD` |
-| `DISABLE_LIMITER` | disable rate limiting (maybe required for automated tests) |
-
-##### SaneUrl
-
-| name | description | default | example |
-| --- | --- | --- | --- |
-| `OBJ_STORAGE_AUTH_URL` |
-| `OBJ_STORAGE_IDP_NAME` |
-| `OBJ_STORAGE_IDP_PROTO` |
-| `OBJ_STORAGE_IDP_URL` |
-| `OBJ_STORAGE_USERNAME` |
-| `OBJ_STORAGE_PASSWORD` |
-| `OBJ_STORAGE_PROJECT_ID` |
-| `OBJ_STORAGE_ROOT_URL` |
-
-##### Test deploy denvironments
-
-| name | description | default | example |
-| --- | --- | --- | --- |
-| `SERVICE_ACCOUNT_CRED` | 
-| `SERVICE_ACCOUNT_CRED_PATH` | 
-| `WAXHOLM_RAT_GOOGLE_SHEET_ID` |
-| `SKIP_RETRY_TEST` | retry tests contains some timeouts, which may slow down tests | 
+Please see [deploy_env.md](deploy_env.md)
 
 ##### e2e test environments
 
-| name | description | default | example | 
-| --- | --- | --- | --- |
-| PROTRACTOR_SPECS | specs relative to `./e2e/` | `./src/**/*.prod.e2e-spec.js` |  |
-| DISABLE_CHROME_HEADLESS | disable headless chrome, spawns chrome window | `unset` (falsy) | 1 |
-| ENABLE_GPU | uses GPU. nb, in headless mode, will show requirement not met | `unset` (falsy) | 1 |
+Please see [e2e_env.md](e2e_env.md)
 
 #### Start dev server
 
diff --git a/build_env.md b/build_env.md
new file mode 100644
index 0000000000000000000000000000000000000000..27ff68e52725910cb9144da5711f4df8d74e6f64
--- /dev/null
+++ b/build_env.md
@@ -0,0 +1,16 @@
+# Build-time environment variables
+
+As interactive atlas viewer uses [webpack define plugin](https://webpack.js.org/plugins/define-plugin/), where necessary, the environmental variables are `JSON.stringify`'ed and directly replaced in the code.
+
+| name | description | default | example |
+| --- | --- | --- | --- |
+| `VERSION` | printed in console on viewer startup | `GIT_HASH` \|\| unspecificed hash | v2.2.2 |
+| `PRODUCTION` | if the build is for production, toggles optimisations such as minification | `undefined` | true |
+| `BACKEND_URL` | backend that the viewer calls to fetch available template spaces, parcellations, plugins, datasets | `null` | https://interactive-viewer.apps.hbp.eu/ |
+| `BS_REST_URL` | [brainscape-api](https://jugit.fz-juelich.de/v.marcenko/brainscapes-api) used to fetch different resources | https://brainscapes.apps-dev.hbp.eu/v1_0 |
+| `DATASET_PREVIEW_URL` | dataset preview url used by component <https://github.com/fzj-inm1-bda/kg-dataset-previewer>. Useful for diagnosing issues with dataset previews.| https://hbp-kg-dataset-previewer.apps.hbp.eu/datasetPreview | http://localhost:1234/datasetPreview |
+| `MATOMO_URL` | base url for matomo analytics | `null` | https://example.com/matomo/ |
+| `MATOMO_ID` | application id for matomo analytics | `null` | 6 |
+| `STRICT_LOCAL` | hides **Explore** and **Download** buttons. Useful for offline demo's | `false` | `true` |
+| `KIOSK_MODE` | after 5 minutes of inactivity, shows overlay inviting users to interact | `false` | `true` |
+| `BUILD_TEXT` | overlay text at bottom right of the viewer. set to `''` to hide. | |
\ No newline at end of file
diff --git a/deploy_env.md b/deploy_env.md
new file mode 100644
index 0000000000000000000000000000000000000000..085fc59d056b66f3e446dab49c6ddfa26a274385
--- /dev/null
+++ b/deploy_env.md
@@ -0,0 +1,95 @@
+# Deploy Environment Variables
+
+##### Application
+
+| name | description | default | example |
+| --- | --- | --- | --- |
+| `PORT` | port to listen on | 3000 |
+| `HOST_PATHNAME` | pathname to listen on, restrictions: leading slash, no trailing slash | `''` | `/viewer` |
+| `SESSIONSECRET` | session secret for cookie session |
+| `NODE_ENV` | determines where the built viewer will be served from | | `production` |
+| `PRECOMPUTED_SERVER` | redirect data uri to another server. Useful for offline demos | | `http://localhost:8080/precomputed/` |
+| `LOCAL_CDN` | rewrite cdns to local server. useful for offlnie demo | | `http://localhost:7080/` |
+| `PLUGIN_URLS` | semi colon separated urls to be returned when user queries plugins | `''`
+| `STAGING_PLUGIN_URLS` | semi colon separated urls to be returned when user queries plugins | `''`
+| `USE_LOGO` | possible values are `hbp`, `ebrains`, `fzj` | `hbp` | `ebrains` |
+
+##### ebrains user authentication
+
+| name | description | default | example |
+| --- | --- | --- | --- |
+| `HOSTNAME` | 
+| `HBP_CLIENTID` | `{HOSTNAME}{HOST_PATHNAME}/hbp-oidc/cb` |
+| `HBP_CLIENTSECRET` |
+| `HBP_CLIENTID_V2` | `{HOSTNAME}{HOST_PATHNAME}/hbp-oidc-v2/cb`
+| `HBP_CLIENTSECRET_V2` | 
+
+##### Querying ebrains knowledge graph
+
+| name | description | default | example |
+| --- | --- | --- | --- |
+| `REFRESH_TOKEN` |
+| `ACCESS_TOKEN` | **nb** as access tokens are usually short lived, this should only be set for development purposes 
+| `CACHE_DATASET_FILENAME` | | `deploy/dataset/cachedKgDataset.json` |
+| `KG_ROOT` | | `https://kg.humanbrainproject.eu/query` |
+| `KG_SEARCH_VOCAB` | | `https://schema.hbp.eu/myQuery/` |
+| `KG_DATASET_SEARCH_QUERY_NAME` | | `interactiveViewerKgQuery-v0_3` |
+| `KG_DATASET_SEARCH_PATH` | | `/minds/core/dataset/v1.0.0` |
+| `KG_SEARCH_SIZE` | | `1000` |
+| `KG_SPATIAL_DATASET_SEARCH_QUERY_NAME` | | `iav-spatial-query-v2` |
+| `KG_SPATIAL_DATASET_SEARCH_PATH` | | `/neuroglancer/seeg/coordinate/v1.0.0` | 
+
+##### Logging
+
+| name | description | default | example |
+| --- | --- | --- | --- |
+| `FLUENT_PROTOCOL` | protocol for fluent logging | `http` |
+| `FLUENT_HOST` | host for fluent logging | `localhost` |
+| `FLUENT_PORT` | port for fluent logging | 24224 |
+| `IAV_NAME` | application name to be logged | `IAV` | 
+| `IAV_STAGE` | deploy of the application | `unnamed-stage` |
+
+##### CSP
+
+| name | description | default | example |
+| --- | --- | --- | --- |
+| `DISABLE_CSP` | disable csp | | `true` |
+| `CSP_REPORT_URI` | report uri for csp violations | `/report-violation` |
+| `NODE_ENV` | set to `production` to disable [`reportOnly`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only) | `null` |
+| `SCRIPT_SRC` | `JSON.stringify`'ed array of allowed scriptSrc | `[]` |
+| `CSP_CONNECT_SRC` | `JSON.stringify`'ed array of allowed dataSrc | `[]` |
+| `WHITE_LIST_SRC` | `JSON.stringify`'ed array of allowed src | `[]` |
+| `PROXY_HOSTNAME_WHITELIST` |
+
+##### Rate limiting
+
+| name | description | default | example |
+| --- | --- | --- | --- |
+| `REDIS_PROTO` | fall back to `REDIS_RATE_LIMITING_DB_EPHEMERAL_PORT_6379_TCP_PROTO` |
+| `REDIS_ADDR` | fall back to `REDIS_RATE_LIMITING_DB_EPHEMERAL_PORT_6379_TCP_ADDR` |
+| `REDIS_PORT` | fall back to `REDIS_RATE_LIMITING_DB_EPHEMERAL_PORT_6379_TCP_PORT` |
+| `REDIS_USERNAME` |
+| `REDIS_PASSWORD` |
+| `DISABLE_LIMITER` | disable rate limiting (maybe required for automated tests) |
+
+##### SaneUrl
+
+| name | description | default | example |
+| --- | --- | --- | --- |
+| `OBJ_STORAGE_AUTH_URL` |
+| `OBJ_STORAGE_IDP_NAME` |
+| `OBJ_STORAGE_IDP_PROTO` |
+| `OBJ_STORAGE_IDP_URL` |
+| `OBJ_STORAGE_USERNAME` |
+| `OBJ_STORAGE_PASSWORD` |
+| `OBJ_STORAGE_PROJECT_ID` |
+| `OBJ_STORAGE_ROOT_URL` |
+
+##### Test deploy denvironments
+
+| name | description | default | example |
+| --- | --- | --- | --- |
+| `SERVICE_ACCOUNT_CRED` | 
+| `SERVICE_ACCOUNT_CRED_PATH` | 
+| `WAXHOLM_RAT_GOOGLE_SHEET_ID` |
+| `SKIP_RETRY_TEST` | retry tests contains some timeouts, which may slow down tests | 
diff --git a/e2e_env.md b/e2e_env.md
new file mode 100644
index 0000000000000000000000000000000000000000..0323b6a621a52a11aa6e2b4783d7452ce748b0da
--- /dev/null
+++ b/e2e_env.md
@@ -0,0 +1,7 @@
+# End-to-end Tests Environment Variables
+
+| name | description | default | example | 
+| --- | --- | --- | --- |
+| PROTRACTOR_SPECS | specs relative to `./e2e/` | `./src/**/*.prod.e2e-spec.js` |  |
+| DISABLE_CHROME_HEADLESS | disable headless chrome, spawns chrome window | `unset` (falsy) | 1 |
+| ENABLE_GPU | uses GPU. nb, in headless mode, will show requirement not met | `unset` (falsy) | 1 |