Docker improvements (#571)

- Copy the current checkout to the Dockerfile.
- Add .dockerignore to exclude files while copying.
- Test tip-of-tree build within CI.
- Run the test suite outside the Docker image.
- Perform extra sanity tests.
- Switch to make commands for CircleCI.
- Improve Docker README.
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 36acaf1..d0d6af5 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -96,9 +96,13 @@
           name: install docker
           command: apt-get update -q && apt-get install -q -y docker.io
       - setup_remote_docker
+      # Build and test the tip-of-tree build of EMSDK
       - run:
           name: build
-          command: docker build --network host ./docker
+          command: make -C ./docker version=tot build
+      - run:
+          name: test
+          command: make -C ./docker version=tot test
 
   publish-docker-image:
     executor: bionic
@@ -110,16 +114,15 @@
       - setup_remote_docker
       - run:
           name: build
-          command: docker build --network host --build-arg EMSCRIPTEN_VERSION=${CIRCLE_TAG} --tag emscripten/emsdk:${CIRCLE_TAG} ./docker
+          command: make -C ./docker version=${CIRCLE_TAG} build
       - run:
-          name: tag image
-          command: docker tag emscripten/emsdk:${CIRCLE_TAG} emscripten/emsdk:latest
+          name: test
+          command: make -C ./docker version=${CIRCLE_TAG} test
       - run:
           name: push image
           command: |
             docker login -u "$DOCKER_USER" -p "$DOCKER_PASS"
-            docker push emscripten/emsdk:${CIRCLE_TAG}
-            docker push emscripten/emsdk:latest
+            make -C ./docker version=${CIRCLE_TAG} alias=latest push
 
 workflows:
   flake8:
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..0e32b67
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,25 @@
+# Ignore all subdirectories
+*/*
+
+# Allow to run the test script inside the Docker container
+!/docker/test_dockerimage.sh
+
+# Allow the Dockerfile for future re-creation/reference
+!/docker/Dockerfile
+
+# Ignore unnecessary files inside top-level directory
+*.bat
+*.csh
+*.fish
+*.ps1
+*.pyc
+.emscripten
+.emscripten.old
+.emscripten_cache
+.emscripten_cache__last_clear
+.emscripten_sanity
+.emscripten_sanity_wasm
+.flake8
+emscripten-releases-tot.txt
+legacy-*-tags.txt
+README.md
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 8f3f159..e183c21 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -1,6 +1,6 @@
 FROM debian:buster AS stage_build
 
-ARG EMSCRIPTEN_VERSION=1.39.20
+ARG EMSCRIPTEN_VERSION=tot
 ENV EMSDK /emsdk
 
 # ------------------------------------------------------------------------------
@@ -18,12 +18,12 @@
         python3-pip \
     && echo "## Done"
 
-RUN echo "## Get EMSDK" \
-    && git clone https://github.com/emscripten-core/emsdk.git ${EMSDK} \
-    && echo "## Done"
+# Copy the contents of this repository to the container
+COPY . ${EMSDK}
 
 RUN echo "## Install Emscripten" \
     && cd ${EMSDK} \
+    && if [ "$EMSCRIPTEN_VERSION" = "tot" ]; then ./emsdk update-tags; fi \
     && ./emsdk install ${EMSCRIPTEN_VERSION} \
     && echo "## Done"
 
@@ -116,18 +116,6 @@
     && echo "## Done"
 
 # ------------------------------------------------------------------------------
-# Internal test suite of tools that this image provides
-COPY test_dockerimage.sh /emsdk/
-
-RUN echo "## Internal Testing of image" \
-    && /emsdk/test_dockerimage.sh \
-    && echo "## Done"
-
-# ------------------------------------------------------------------------------
-# Copy this Dockerimage into image, so that it will be possible to recreate it later
-COPY Dockerfile /emsdk/dockerfiles/emscripten-core/emsdk/
-
-# ------------------------------------------------------------------------------
 # Use commonly used /src as working directory
 WORKDIR /src
 
diff --git a/docker/Makefile b/docker/Makefile
index fa02f45..0c961ca 100644
--- a/docker/Makefile
+++ b/docker/Makefile
@@ -1,21 +1,28 @@
-#!/usr/bin/env make
+# A Makefile to build, test, tag and publish the Emscripten SDK Docker container.
 
 # Emscripten version to build: Should match the version that has been already released.
-# i.e.:  1.38.45, 1.38.45-upstream
+# i.e.:  1.39.18
 version =
 alias =
 
+image_name ?= emscripten/emsdk
+
 .TEST:
 ifndef version
 	$(error argument 'version' is not set. Please call `make version=SOME_VERSION ...`)
 endif
 
-build: .TEST
-	docker build --network host --build-arg=EMSCRIPTEN_VERSION=${version} --tag emscripten/emsdk:${version} .
+build: Dockerfile .TEST
+	cd .. && docker build --network host --build-arg=EMSCRIPTEN_VERSION=${version} -t ${image_name}:${version} -f docker/$< .
+
+test: test_dockerimage.sh .TEST
+	# test as non-root
+	docker run --rm -u `id -u`:`id -g` -w /emsdk/docker --net=host ${image_name}:${version} \
+		bash $<
 
 push: .TEST
-	docker push emscripten/emsdk:${version}
+	docker push ${image_name}:${version}
 ifdef alias
-	docker tag emscripten/emsdk:${version} emscripten/emsdk:${alias}
-	docker push emscripten/emsdk:${alias}
+	docker tag ${image_name}:${version} ${image_name}:${alias}
+	docker push ${image_name}:${alias}
 endif
diff --git a/docker/README.md b/docker/README.md
index 7199de8..d7c7fc8 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -1,6 +1,6 @@
 # Dockerfile for EMSDK
 
-This Dockerfile builds a self-contained version of emsdk that enables emscripten to be used without any
+This Dockerfile builds a self-contained version of Emscripten SDK that enables Emscripten to be used without any
 other installation on the host system.
 
 It is published at https://hub.docker.com/u/emscripten/emsdk
@@ -23,7 +23,7 @@
 # compile with docker image
 docker run \
   --rm \
-  -v $(pwd):$(pwd) \
+  -v $(pwd):/src \
   -u $(id -u):$(id -g) \
   emscripten/emsdk \
   emcc helloworld.cpp -o helloworld.js
@@ -51,7 +51,7 @@
 
 | arg | description |
 | --- | --- |
-| `EMSCRIPTEN_VERSION` | One of released version of Emscripten. For example `1.38.45`<br/> Can be used with `-upstream` variant like: `1.38.45-upstream`<br /> Minimal supported version is **1.38.40**|
+| `EMSCRIPTEN_VERSION` | One of released version of Emscripten. For example `1.39.17`<br/> Minimal supported version is **1.39.0**|
 
 **Building**
 
@@ -60,13 +60,14 @@
 # using docker
 docker build \
     --network host \
-    --build-arg=EMSCRIPTEN_VERSION=1.38.43-upstream \
-    --tag emscripten/emsdk:1.38.43-upstream \
+    --build-arg=EMSCRIPTEN_VERSION=1.39.17 \
+    -t emscripten/emsdk:1.39.17 \
+    -f docker/Dockerfile \
     .
 ```
 ```bash
 # using predefined make target
-make version=1.38.43-upstream build
+make version=1.39.17 build test
 ```
 
 **Tagging**
@@ -79,35 +80,24 @@
 
 ```bash
 # using docker
-docker push emscripten/emsdk:1.38.43-upstream
+docker push emscripten/emsdk:1.39.17
 ```
 ```bash
 # using predefined make target
-make version=1.38.43-upstream push
+make version=1.39.17 push
 ```
 
-In case of pushing the most recent version, this version should be also tagged as `latest` or `latest-upstream` and pushed.
+In case of pushing the most recent version, this version should be also tagged as `latest` and pushed.
 ```bash
 # using docker cli
-
-# in case of fastcomp variant (default backend)
-docker tag emscripten/emsdk:1.38.43 emscripten/emsdk:latest
+docker tag emscripten/emsdk:1.39.17 emscripten/emsdk:latest
 docker push emscripten/emsdk:latest
 
-# in case of upstream variant
-docker tag emscripten/emsdk:1.38.43-upstream emscripten/emsdk:latest-upstream
-docker push emscripten/emsdk:latest-upstream
-
-```
-
 ```bash
-# using predefined make target
-
-make version=1.38.43-upstream alias=latest-upstream push
-
+# using make
+make version=1.39.17 alias=latest push
 ```
 
-
 ### Extending
 
 If your project uses packages that this image doesn't provide you might want to:
@@ -117,20 +107,19 @@
 1. create own Dockerfile that holds:
     ```dockerfile
     # Point at any base image that you find suitable to extend.
-    FROM emscripten/emsdk:1.38.25
+    FROM emscripten/emsdk:1.39.17
 
     # Install required tools that are useful for your project i.e. ninja-build
     RUN apt update && apt install -y ninja-build
-
     ```
+
 2. build it
-    ```shell
+    ```bash
     docker build -t extended_emscripten .
     ```
 
 3. test
-    ```shell
+    ```bash
     docker run --rm extended_emscripten ninja --version
-    # Python 2.7.16
+    # 1.10.0
     ```
-
diff --git a/docker/test_dockerimage.sh b/docker/test_dockerimage.sh
index 9c8b92b..4f44806 100755
--- a/docker/test_dockerimage.sh
+++ b/docker/test_dockerimage.sh
@@ -1,9 +1,10 @@
-#!/bin/bash
+#!/usr/bin/env bash
 set -ex
 
-sudo -u nobody `which emcc` --version
+if [ $EUID -eq 0 ]; then
+  sudo -u nobody `which emcc` --version
+fi
 
-which asm2wasm
 which llvm-ar
 which emsdk
 node --version
@@ -15,5 +16,15 @@
 java -version
 cmake --version
 
-# cleanup after test
-find ${EMSDK} -name "*.pyc" -exec rm {} \;
+exit_code=0
+
+# test emcc compilation
+echo 'int main() { return 0; }' | emcc -o /tmp/main.js -xc -
+node /tmp/main.js || exit_code=$?
+if [ $exit_code -ne 0 ]; then
+  echo "Node exited with non-zero exit code: $exit_code"
+  exit $exit_code
+fi
+
+# test embuilder
+embuilder build zlib --force