diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 796d2d4a01ef281f52332cb4f0055a872f367b5f..3e4c12d5b20f71c06f145b2c03b9bbd26718d361 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -8,7 +8,10 @@ on:
 env:
   DOCKER_IMAGE_NAME: interactive-viewer
   DOCKER_IMAGE_TAG: ${{ github.sha }}
-  DOCKER_CONTAINER_NAME: github-actions-iav-dkr-container
+  DOCKER_CONTAINER_NAME: gha-iav-built-${{ github.sha }}
+  DOCKER_E2E_PPTR: gha-iav-e2e-pptr-${{ github.sha }}
+  DOCKER_E2E_NETWORK: gha-dkr-network-${{ github.sha }}
+  ATLAS_URL: http://gha-iav-built-${{ github.sha }}:3000
 
 jobs:
   buildimage:
@@ -24,22 +27,15 @@ jobs:
       run: |
         docker build --build-arg BACKEND_URL=${BACKEND_URL} -t ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} .
       env:
-        BACKEND_URL: http://localhost:3001/
+        BACKEND_URL: ${{ env.ATLAS_URL }}
 
   test:
     runs-on: self-hosted
     needs: buildimage
     steps:
-    - uses: actions/checkout@v2
-      with:
-        fetch-depth: 2
-        repository: 'FZJ-INM1-BDA/iv-automated-tests'
-    - name: Install dependencies
-      run: |
-        npm i
-    - name: run docker image ${{ env.DOCKER_IMAGE_NAME }}:${{ env.DOCKER_IMAGE_TAG }}
+    - name: run docker image ${{ env.DOCKER_IMAGE_NAME }}:${{ env.DOCKER_IMAGE_TAG }} as container ${{ env.DOCKER_CONTAINER_NAME }}
       run: |
-        docker run -p 3001:3000 \
+        docker run \
           --rm \
           --name ${DOCKER_CONTAINER_NAME} \
           --env HBP_CLIENTID=${{ secrets.HBP_CLIENTID }} \
@@ -47,15 +43,31 @@ jobs:
           --env REFRESH_TOKEN=${{ secrets.REFRESH_TOKEN }} \
           -dit \
           ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG}
-    - name: sleep for 60s
-      run: sleep 60s
-    - name: run pptr tests - ${{ env.TEST_URL }}
-      run: node ./node_modules/.bin/mocha ./test/databrowser.spec.js --timeout 1800000 
-      env:
-        TEST_URL: http://localhost:3001
+
+    - uses: actions/checkout@v1
+    - name: Start pptr docker container with name ${{ env.DOCKER_E2E_PPTR }}
+      run: |
+        docker run --rm \
+          --name ${DOCKER_E2E_PPTR} \
+          -dt \
+          puppeteer
+        docker cp . ${DOCKER_E2E_PPTR}:/iav
+        docker exec -u root ${DOCKER_E2E_PPTR} chown -R pptruser:pptruser /iav
+        docker exec -t -w /iav ${DOCKER_E2E_PPTR} npm i
+        docker exec -t -w /iav ${DOCKER_E2E_PPTR} npm run wd -- update --versions.chrome latest
+        docker exec -t ${DOCKER_E2E_PPTR} npm i puppeteer
+    - name: Setup docker network
+      run: |
+        docker network create ${{ env.DOCKER_E2E_NETWORK }}
+        docker network connect ${{ env.DOCKER_E2E_NETWORK }} ${{ env.DOCKER_E2E_PPTR }}
+        docker network connect ${{ env.DOCKER_E2E_NETWORK }} ${{ env.DOCKER_CONTAINER_NAME }}
+    - name: run pptr tests - ${{ env.ATLAS_URL }}
+      run: |
+        docker exec --env ATLAS_URL=${ATLAS_URL} -t -w /iav ${DOCKER_E2E_PPTR} npm run e2e
     - name: cleanup, stop container ${{ env.DOCKER_CONTAINER_NAME }}
-      if: always()
-      run: docker stop ${DOCKER_CONTAINER_NAME}
-    - name: cleanup, remove image ${{ env.DOCKER_IMAGE_NAME }}:${{ env.DOCKER_IMAGE_TAG }}
       if: success()
-      run: docker rmi ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG}
+      run: |
+        docker stop ${DOCKER_CONTAINER_NAME}
+        docker stop ${DOCKER_E2E_PPTR}
+        docker network rm ${DOCKER_E2E_NETWORK}
+        docker rmi ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG}
diff --git a/Dockerfile b/Dockerfile
index 87199619f483ddfe45793a012c87171032ece2b7..588e1efca446da79f6d454c1b7c3153522e9117b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -34,6 +34,9 @@ RUN apk --no-cache add ca-certificates
 RUN mkdir /iv-app
 WORKDIR /iv-app
 
+# Copy common folder
+COPY --from=builder /iv/common /common
+
 # Copy the express server
 COPY --from=builder /iv/deploy .
 
diff --git a/e2e/chromeOpts.js b/e2e/chromeOpts.js
new file mode 100644
index 0000000000000000000000000000000000000000..f2239f793d3bd4f104e8f6b8e53edc8e999c8cd6
--- /dev/null
+++ b/e2e/chromeOpts.js
@@ -0,0 +1,7 @@
+module.exports = [
+  '--headless',
+  '--no-sandbox',
+  '--disable-setuid-sandbox',
+  "--disable-extensions",
+  '--window-size=800,600'
+]
\ No newline at end of file
diff --git a/e2e/protractor.conf.js b/e2e/protractor.conf.js
index 344f4ca0ab7d79c29267d8419c30076cdeddca90..531d037f1401c1114262d955a63b59bc263cd37f 100644
--- a/e2e/protractor.conf.js
+++ b/e2e/protractor.conf.js
@@ -2,7 +2,7 @@
 // n.b. to start selenium, run npm run wd -- update && npm run wd -- start
 // n.b. you will need to run `npm i --no-save puppeteer`, so that normal download script does not download chrome binary
 const pptr = require('puppeteer')
-
+const chromeOpts = require('./chromeOpts')
 const SELENIUM_ADDRESS = process.env.SELENIUM_ADDRESS
 
 exports.config = {
@@ -16,8 +16,14 @@ exports.config = {
     // Use headless chrome
     browserName: 'chrome',
     chromeOptions: {
-      args: [ "--headless", "--disable-gpu", "--window-size=800,600"],
-      binary: pptr.executablePath()
+      args: [
+        ...chromeOpts
+      ],
+      ...(
+        SELENIUM_ADDRESS
+          ? {}
+          : { binary: pptr.executablePath() }
+      )
     }
   }
 }
\ No newline at end of file
diff --git a/e2e/src/iv.e2e-spec.js b/e2e/src/iv.e2e-spec.js
index fe1827499b897350eb09ac6c72b86d56c7ce08b2..2d249046dfa8c2ca15c79d0d24c5fc85673a2422 100644
--- a/e2e/src/iv.e2e-spec.js
+++ b/e2e/src/iv.e2e-spec.js
@@ -1,5 +1,4 @@
-const url = 'http://localhost:3000/'
-
+const chromeOpts = require('../chromeOpts')
 const noErrorLog = require('./noErrorLog')
 const { getSelectedTemplate, getSelectedParcellation, getSelectedRegions } = require('./ivApi')
 const { getSearchParam, wait } = require('./util')
@@ -19,7 +18,16 @@ if (ATLAS_URL[ATLAS_URL.length - 1] === '/') throw new Error(`ATLAS_URL should n
 let browser
 describe('IAV', () => {
   beforeAll(async () => {
-    browser = await pptr.launch()
+    browser = await pptr.launch({
+      ...(
+        chromeOpts.indexOf('--headless') >= 0
+          ? { headless: true }
+          : {}
+      ),
+      args: [
+        ...chromeOpts
+      ]
+    })
   })
 
   // TODO figure out how to get jasmine to compare array members