diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c7acc5ad4db665d19ec2e91fff66045ad9b63583..b600d531527ef452a37a03b2a0ecb0d3c13aa754 100755
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,7 +3,8 @@ variables:
   DOCKER_HOST: tcp://docker:2376
   DOCKER_TLS_CERTDIR: "/certs"
   DOCKER_DRIVER: overlay2
-  CONTAINER_IMAGE: $CI_REGISTRY/algebraic-nash/nash-eq-wilson/sagemath:9.0-py3
+  CONTAINER_IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}
+  REF_BASE_IMAGE: registry.forgemia.inra.fr/algebraic-nash/nash-eq-wilson/sagemath:9.0-py3
   DOCKER_BUILDKIT: 1
 
 linter_flake8:
@@ -22,6 +23,40 @@ linter_flake8:
     reports:
       junit: junit.xml
 
+linter_dockerfile:
+  image: hadolint/hadolint:2.8.0-alpine
+  variables:
+    files_to_lint: ""
+  script: |
+    mkdir -p reports
+    hadolint -f gitlab_codeclimate docker/Dockerfile > reports/hadolint-$(md5sum docker/Dockerfile | cut -d" " -f1).json
+  artifacts:
+    name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
+    paths: 
+      - "reports/*"
+    when: always
+
+build_docker:
+  image: docker:stable
+  services:
+    - docker:dind
+  before_script:
+    - docker info
+    - echo $CI_JOB_TOKEN | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
+  script:
+    - docker build 
+        --cache-from $CONTAINER_IMAGE 
+        --tag $CONTAINER_IMAGE:latest 
+        --tag $CONTAINER_IMAGE:$CI_COMMIT_SHA 
+        --file docker/Dockerfile
+        --build-arg BUILDKIT_INLINE_CACHE=1
+        --build-arg REF_BASE_IMAGE=$REF_BASE_IMAGE
+        "."
+  after_script:
+    - docker push $CONTAINER_IMAGE:latest
+    - docker push $CONTAINER_IMAGE:$CI_COMMIT_SHA
+    - docker logout "${CI_REGISTRY}"
+
 
 test_pytest:
   image: docker:stable
@@ -32,18 +67,21 @@ test_pytest:
   before_script:
     - docker info
     - echo $CI_JOB_TOKEN | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
-    - docker pull $CONTAINER_IMAGE
+    - docker pull $CONTAINER_IMAGE:$CI_COMMIT_SHA
   script:
-    - docker run -v "$(pwd):/mnt" -w /mnt $CONTAINER_IMAGE "sage -pip install -e .&&cd $TEST_DIR&&pytest --junitxml=report.xml"
+    - docker run -v "$(pwd):/mnt" -w /mnt/$TEST_DIR $CONTAINER_IMAGE:$CI_COMMIT_SHA "pytest --junitxml=report.xml"
+  after_script:
+    - docker logout "${CI_REGISTRY}"
   artifacts:
     when: always
     paths: 
       - "$TEST_DIR/report.xml"
     reports:
       junit: "$TEST_DIR/report.xml"
+  needs: ["build_docker"]
   
 
-jupyter:
+export_jupyternb:
   image: docker:stable
   services:
     - docker:dind
@@ -55,7 +93,10 @@ jupyter:
     - echo $CI_JOB_TOKEN | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
     - docker pull $CONTAINER_IMAGE
   script:
-    - docker run -v "$(pwd):/mnt" -w /mnt $CONTAINER_IMAGE "sage -pip install -e .&&ls -1 ${JUPYTERNB_FOLDER}${JUPYTERNB_FILE}.ipynb | xargs jupyter nbconvert --to html --execute"
+    - docker run -v "$(pwd):/mnt" -w /mnt $CONTAINER_IMAGE:$CI_COMMIT_SHA "ls -1 ${JUPYTERNB_FOLDER}${JUPYTERNB_FILE}.ipynb | xargs jupyter nbconvert --to html --execute"
+  after_script:
+    - docker logout "${CI_REGISTRY}"
   artifacts:
     paths:
       - ${JUPYTERNB_FOLDER}${JUPYTERNB_FILE}.html
+  needs: ["build_docker"]
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100755
index 0000000000000000000000000000000000000000..aa6e046bdd0d9bd74f0fd8c55a32fc0387d854d6
--- /dev/null
+++ b/docker/Dockerfile
@@ -0,0 +1,24 @@
+ARG REF_BASE_IMAGE=sagemath/sagemath:9.0-py3
+# hadolint ignore=DL3006
+FROM $REF_BASE_IMAGE
+
+ENV PYTHONUNBUFFERED 1
+
+RUN /home/sage/sage/local/bin/pip3 install flake8 autopep8
+
+USER root
+# hadolint ignore=DL3008
+RUN apt-get update \
+    && apt-get install --no-install-recommends --no-install-suggests -y -V \
+            pandoc \
+            lynx \
+    && rm -rf /var/lib/apt/lists/*
+USER sage
+
+# Copy the contents of the repo in ${HOME}
+COPY --chown=sage:sage . ${HOME}
+
+RUN sage -pip install -v .
+
+ENTRYPOINT ["/usr/local/bin/sage-entrypoint"]
+CMD ["pandoc",  "docker/README.md | lynx -stdin"]
\ No newline at end of file
diff --git a/docker/README.md b/docker/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..475ab39a6b397c68713605ff60ac79e7fab3dbe5
--- /dev/null
+++ b/docker/README.md
@@ -0,0 +1,51 @@
+# Using container environment
+
+Prerequisites : 
+* https://docs.docker.com/engine/install/
+* https://docs.docker.com/engine/security/rootless/
+
+Using base image sagemath/sagemath:9.0-py3 : https://hub.docker.com/layers/sagemath/sagemath/9.0-py3/images/sha256-65ba865735ee58772d7b7843b4c37bdcd45a97dc1bf958c054cb9d4661d23013?context=explore
+
+## Local building of the container 
+```bash
+docker build --tag gtnash-git --file docker/Dockerfile .
+
+docker build --build-arg REF_BASE_IMAGE=registry.forgemia.inra.fr/algebraic-nash/nash-eq-wilson/sagemath:9.0-py3 --build-arg BUILDKIT_INLINE_CACHE=1 --tag registry.forgemia.inra.fr/game-theory-tools-group/gtnash-git:latest --file docker/Dockerfile .
+
+```
+
+## Running a container 
+```bash
+docker run --rm -it registry.forgemia.inra.fr/game-theory-tools-group/gtnash-git:latest
+
+docker run --rm -it registry.forgemia.inra.fr/game-theory-tools-group/gtnash-git:latest bash
+
+docker run --rm -it -v "$(pwd):/mnt" -w /mnt -u root registry.forgemia.inra.fr/game-theory-tools-group/gtnash-git:latest bash
+
+docker run --rm -it -v "$(pwd):/mnt" -w /mnt -u root -p 8888:8888 registry.forgemia.inra.fr/game-theory-tools-group/gtnash-git:latest bash
+```
+
+example commands from within an interactive container
+```bash
+flake8
+
+autopep8 --in-place --recursive .
+
+cd /mnt/test && pytest && cd /mnt
+
+sage -pip install -e .
+
+sage -n jupyter --allow-root --no-browse --ip=0.0.0.0 --port=8888
+```
+
+
+## Running a container to use flake8, pytest and serve jupyter on local source code
+
+```bash
+docker run --rm -it -v "$(pwd):/mnt" -w /mnt -u root registry.forgemia.inra.fr/game-theory-tools-group/gtnash-git:latest flake8
+
+docker run --rm -it -v "$(pwd):/mnt" -w /mnt/test -u root registry.forgemia.inra.fr/game-theory-tools-group/gtnash-git:latest pytest
+
+docker run --rm -it -v "$(pwd):/mnt" -w /mnt -p 8888:8888 -u root registry.forgemia.inra.fr/game-theory-tools-group/gtnash-git:latest sage -n jupyter --allow-root --no-browse --ip=0.0.0.0 --port=8888
+```
+