diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 631611fc47ec9a8ff1ee31ade69482d88f3fd27a..0e2bf2977b1d2e8a1d031ae5544d4cd5fa2ed0aa 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,13 +2,66 @@ image: registry-gitlab.pasteur.fr/dsi-tools/docker-images/docker:latest
 
 services:
   - registry-gitlab.pasteur.fr/dsi-tools/docker-images/docker:dind  
-  
-build:
+
+
+
+build-my-base:
   stage: build
-  before_script:
+  variable:
+    STAGE_NAME="my-base"
+  script:
     - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    # pull the latest build
+    - docker pull "$CI_REGISTRY_IMAGE:latest" || true
+    # pull the latest build of main
+    - docker pull "$CI_REGISTRY_IMAGE/main:latest" || true
+    # pull the latest build of this branch
+    - docker pull "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:latest" || true
+    # building
+    - docker build
+      --tag "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/${STAGE_NAME}:$CI_COMMIT_SHA"
+      --file Dockerfile
+      --target ${STAGE_NAME}
+      ./
+    - docker push $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/${STAGE_NAME}:$CI_COMMIT_SHA"
+
+
+
+build-my-r-base:
+  stage: build
+  needs: [build-my-base]
+  variable:
+    STAGE_NAME="my-r-base"
+  script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    # pull the previous stage
+    - docker pull "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/my-base:$CI_COMMIT_SHA"
+    # pull the latest build of the target R version in order to re-use it
+    - docker pull "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$R_VERSION" || true
+    # building
+    - docker build
+      --build-arg R_VERSION
+      --tag "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/${STAGE_NAME}/${R_VERSION}:$CI_COMMIT_SHA"
+      --file Dockerfile
+      -target ${STAGE_NAME}
+      ./
+    # push image tagged with its versions
+    - docker push "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/${STAGE_NAME}/${R_VERSION}:$CI_COMMIT_SHA"
+  parallel:
+    matrix:
+      - R_VERSION: ["3.6.3", "4.2.3", "latest"]
+
+
+
+build-my-r-shiny:
+  stage: build
+  needs: ["build-my-r-base"]
+  variable:
+    STAGE_NAME="my-r-shiny"
   script:
-    - docker --version
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    # pull the previous stage
+    - docker pull "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/my-r-base/${R_VERSION}:$CI_COMMIT_SHA"
     # put both versions in a env var, to be used as tag
     - |
       if [ "latest" == "${R_VERSION}" ]; then
@@ -20,48 +73,33 @@ build:
           export VERSIONS_TAG="${R_VERSION}--${SHINY_SERVER_VERSION}"
         fi
       fi
-    # pull the latest build
-    - docker pull "$CI_REGISTRY_IMAGE:latest" || true
-    # pull the latest build of the targeted versions
-    - docker pull "$CI_REGISTRY_IMAGE:$VERSIONS_TAG" || true
-    # pull the latest build of the target R version in order to re-use it for the targeted SHINY_SERVER_VERSION
-    - docker pull "$CI_REGISTRY_IMAGE:$R_VERSION" || true
-    # pull the latest build of main
-    - docker pull "$CI_REGISTRY_IMAGE/main:latest" || true
-    # pull the latest build of this branch
-    - docker pull "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:latest" || true
-    # build the image while passing commit SHA and versions, and tagging the image with them
+    # building
     - docker build
       --build-arg R_VERSION
       --build-arg SHINY_SERVER_VERSION
-      --cache-from "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:latest"
-      --cache-from "$CI_REGISTRY_IMAGE/main:latest"
-      --cache-from "$CI_REGISTRY_IMAGE:$VERSIONS_TAG"
-      --cache-from "$CI_REGISTRY_IMAGE:$R_VERSION"
-      --cache-from "$CI_REGISTRY_IMAGE:latest"
-      --tag "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA"
-      --tag "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:latest"
       --tag "$CI_REGISTRY_IMAGE:$VERSIONS_TAG"
       --tag "$CI_REGISTRY_IMAGE:$VERSIONS_TAG--$CI_COMMIT_SHORT_SHA"
-      -f Dockerfile
+      --tag "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:latest"
+      --file Dockerfile
+      --target ${STAGE_NAME}
       ./
     # push image as latest for the current branch
     - docker push "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:latest"
-    # push image tagged with its sha
-    - docker push "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA"
     # push image tagged with its versions
-    - docker push "$CI_REGISTRY_IMAGE:$VERSIONS_TAG"
+    - docker push "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$VERSIONS_TAG"
     # push image tagged with its versions and the commit sha (debug purpose)
-    - docker push "$CI_REGISTRY_IMAGE:$VERSIONS_TAG--$CI_COMMIT_SHORT_SHA"
+    - docker push "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$VERSIONS_TAG--$CI_COMMIT_SHORT_SHA"
   parallel:
     matrix:
       - R_VERSION: ["3.6.3", "4.2.3", "latest"]
         SHINY_SERVER_VERSION: ["latest"]
 
 
+
+
 build-example:
   stage: build
-  needs: ["build"]
+  needs: ["build-mr-r-shiny"]
   only:
   - main
   before_script:
diff --git a/Dockerfile b/Dockerfile
index b2eab070ba03c9d5456378d03ccc688f55c4ed8f..b04e38b0509dc4bd06e22902e6174499577cd67c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,10 +1,11 @@
-FROM ubuntu:focal
+###########################################################
+# Ubuntu image with all dependencies
+###########################################################
+FROM ubuntu:focal as my-base
 
 # define geographic location during R installation
 ENV TZ=Etc/UTC
 ENV DEBIAN_FRONTEND noninteractive
-ARG SHINY_SERVER_VERSION=latest
-ARG R_VERSION=latest
 
 EXPOSE 3838
 CMD ["shiny-server"]
@@ -34,11 +35,24 @@ RUN apt-get update \
 
 COPY ./scripts /opt/scripts
 
+
+###########################################################
+# R image
+###########################################################
+FROM my-base as my-r-base
+ARG R_VERSION=latest
+
 #install R, along with its dependencies
 RUN /opt/scripts/install_r_cran.sh
 # test R in another layer
 RUN R -q -e "sessionInfo()"
 
+###########################################################
+# RShiny image
+###########################################################
+FROM my-base as my-r-shiny
+ARG SHINY_SERVER_VERSION=latest
+
 # Install R packages included Shiny, then install shiny server
 RUN Rscript /opt/scripts/install_r_packages.R
 RUN /opt/scripts/install_shiny_server.sh
@@ -46,12 +60,5 @@ RUN /opt/scripts/install_shiny_server.sh
 # allows trafic from all ips
 RUN sed -i "s/3838/3838 0.0.0.0/g" /etc/shiny-server/shiny-server.conf
 
-#RUN chown shiny:shiny /var/lib/shiny-server
 RUN mkdir -p /var/log/shiny-server \
  && chown shiny:shiny /var/log/shiny-server
-
-# USER shiny
-
-
-
-