diff --git a/Dockerfile_ExerciceChecker b/Dockerfile_ExerciceChecker
index fb8bf1bfba21f5847f671b997b421a0c4ca42b1a..4ce2e0829fdd0c046e653391b2c7fa818970106f 100644
--- a/Dockerfile_ExerciceChecker
+++ b/Dockerfile_ExerciceChecker
@@ -31,6 +31,9 @@ FROM docker:latest
 LABEL maintainer="Michaël Minelli <michael-jean.minelli@hesge.ch>"
 LABEL Description="Dojo exercice checker - Container generation for usage in exercice pipelines"
 
+RUN apk update
+RUN apk add git
+
 ARG BUILD_WORKDIR
 
 COPY --from=builder ${BUILD_WORKDIR}/bin/app /usr/local/bin/dojo_exercice_checker
\ No newline at end of file
diff --git a/ExerciceChecker/.idea/vcs.xml b/ExerciceChecker/.idea/vcs.xml
index 6c0b8635858dc7ad44b93df54b762707ce49eefc..d86e73b516141a07b5ba1f16f6f315749512bedc 100644
--- a/ExerciceChecker/.idea/vcs.xml
+++ b/ExerciceChecker/.idea/vcs.xml
@@ -2,5 +2,7 @@
 <project version="4">
   <component name="VcsDirectoryMappings">
     <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
+    <mapping directory="$PROJECT_DIR$/src/shared" vcs="Git" />
+    <mapping directory="$PROJECT_DIR$/src/sharedByClients" vcs="Git" />
   </component>
 </project>
\ No newline at end of file
diff --git a/ExerciceChecker/assets/docker-compose-override.yml b/ExerciceChecker/assets/docker-compose-override.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4f2e6cf0c92cb979143a91d8ebb0fcf6e2294444
--- /dev/null
+++ b/ExerciceChecker/assets/docker-compose-override.yml
@@ -0,0 +1,6 @@
+volumes:
+      {{VOLUME_NAME}}:
+          driver_opts:
+              type  : none
+              device: {{MOUNT_PATH}}
+              o     : bind
diff --git a/ExerciceChecker/package-lock.json b/ExerciceChecker/package-lock.json
index 955f5c55c38f31e439e87be0b6d2f20c6d5442cc..d27a3443c703494fa7d31249914e4ed23421a1b3 100644
--- a/ExerciceChecker/package-lock.json
+++ b/ExerciceChecker/package-lock.json
@@ -8,18 +8,28 @@
             "name": "dojo_exercice_checker",
             "version": "1.0.0",
             "dependencies": {
+                "ajv": "^8.12.0",
                 "axios": "^1.4.0",
+                "boxen": "^5.1.2",
                 "chalk": "^4.1.2",
+                "dockerode": "^3.3.5",
                 "dotenv": "^16.3.1",
+                "fs-extra": "^11.1.1",
                 "http-status-codes": "^2.2.0",
+                "json5": "^2.2.3",
                 "ora": "^5.4.1",
+                "tar-stream": "^3.1.6",
                 "winston": "^3.10.0"
             },
             "bin": {
                 "dirmanager": "dist/app.js"
             },
             "devDependencies": {
+                "@types/dockerode": "^3.3.19",
+                "@types/fs-extra": "^11.0.1",
+                "@types/js-yaml": "^4.0.5",
                 "@types/node": "^18.17.1",
+                "@types/tar-stream": "^2.2.2",
                 "pkg": "^5.8.1",
                 "ts-node": "^10.9.1",
                 "typescript": "^5.1.6"
@@ -83,6 +93,11 @@
                 "node": ">=6.9.0"
             }
         },
+        "node_modules/@balena/dockerignore": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz",
+            "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q=="
+        },
         "node_modules/@colors/colors": {
             "version": "1.5.0",
             "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
@@ -236,12 +251,75 @@
             "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
             "dev": true
         },
+        "node_modules/@types/docker-modem": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.2.tgz",
+            "integrity": "sha512-qC7prjoEYR2QEe6SmCVfB1x3rfcQtUr1n4x89+3e0wSTMQ/KYCyf+/RAA9n2tllkkNc6//JMUZePdFRiGIWfaQ==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*",
+                "@types/ssh2": "*"
+            }
+        },
+        "node_modules/@types/dockerode": {
+            "version": "3.3.19",
+            "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.19.tgz",
+            "integrity": "sha512-7CC5yIpQi+bHXwDK43b/deYXteP3Lem9gdocVVHJPSRJJLMfbiOchQV3rDmAPkMw+n3GIVj7m1six3JW+VcwwA==",
+            "dev": true,
+            "dependencies": {
+                "@types/docker-modem": "*",
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/fs-extra": {
+            "version": "11.0.1",
+            "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.1.tgz",
+            "integrity": "sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==",
+            "dev": true,
+            "dependencies": {
+                "@types/jsonfile": "*",
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/js-yaml": {
+            "version": "4.0.5",
+            "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz",
+            "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==",
+            "dev": true
+        },
+        "node_modules/@types/jsonfile": {
+            "version": "6.1.1",
+            "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.1.tgz",
+            "integrity": "sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
         "node_modules/@types/node": {
             "version": "18.17.1",
             "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.1.tgz",
             "integrity": "sha512-xlR1jahfizdplZYRU59JlUx9uzF1ARa8jbhM11ccpCJya8kvos5jwdm2ZAgxSCwOl0fq21svP18EVwPBXMQudw==",
             "dev": true
         },
+        "node_modules/@types/ssh2": {
+            "version": "1.11.13",
+            "resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.11.13.tgz",
+            "integrity": "sha512-08WbG68HvQ2YVi74n2iSUnYHYpUdFc/s2IsI0BHBdJwaqYJpWlVv9elL0tYShTv60yr0ObdxJR5NrCRiGJ/0CQ==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "^18.11.18"
+            }
+        },
+        "node_modules/@types/tar-stream": {
+            "version": "2.2.2",
+            "resolved": "https://registry.npmjs.org/@types/tar-stream/-/tar-stream-2.2.2.tgz",
+            "integrity": "sha512-1AX+Yt3icFuU6kxwmPakaiGrJUwG44MpuiqPg4dSolRFk6jmvs4b3IbUol9wKDLIgU76gevn3EwE8y/DkSJCZQ==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
         "node_modules/@types/triple-beam": {
             "version": "1.3.2",
             "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.2.tgz",
@@ -280,6 +358,29 @@
                 "node": ">= 6.0.0"
             }
         },
+        "node_modules/ajv": {
+            "version": "8.12.0",
+            "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+            "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+            "dependencies": {
+                "fast-deep-equal": "^3.1.1",
+                "json-schema-traverse": "^1.0.0",
+                "require-from-string": "^2.0.2",
+                "uri-js": "^4.2.2"
+            },
+            "funding": {
+                "type": "github",
+                "url": "https://github.com/sponsors/epoberezkin"
+            }
+        },
+        "node_modules/ansi-align": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
+            "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==",
+            "dependencies": {
+                "string-width": "^4.1.0"
+            }
+        },
         "node_modules/ansi-regex": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -317,6 +418,14 @@
                 "node": ">=8"
             }
         },
+        "node_modules/asn1": {
+            "version": "0.2.6",
+            "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+            "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+            "dependencies": {
+                "safer-buffer": "~2.1.0"
+            }
+        },
         "node_modules/async": {
             "version": "3.2.4",
             "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
@@ -346,6 +455,11 @@
                 "proxy-from-env": "^1.1.0"
             }
         },
+        "node_modules/b4a": {
+            "version": "1.6.4",
+            "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz",
+            "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw=="
+        },
         "node_modules/base64-js": {
             "version": "1.5.1",
             "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -365,6 +479,14 @@
                 }
             ]
         },
+        "node_modules/bcrypt-pbkdf": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+            "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+            "dependencies": {
+                "tweetnacl": "^0.14.3"
+            }
+        },
         "node_modules/bl": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@@ -375,6 +497,27 @@
                 "readable-stream": "^3.4.0"
             }
         },
+        "node_modules/boxen": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz",
+            "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==",
+            "dependencies": {
+                "ansi-align": "^3.0.0",
+                "camelcase": "^6.2.0",
+                "chalk": "^4.1.0",
+                "cli-boxes": "^2.2.1",
+                "string-width": "^4.2.2",
+                "type-fest": "^0.20.2",
+                "widest-line": "^3.1.0",
+                "wrap-ansi": "^7.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
         "node_modules/braces": {
             "version": "3.0.2",
             "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
@@ -410,6 +553,26 @@
                 "ieee754": "^1.1.13"
             }
         },
+        "node_modules/buildcheck": {
+            "version": "0.0.6",
+            "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz",
+            "integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==",
+            "optional": true,
+            "engines": {
+                "node": ">=10.0.0"
+            }
+        },
+        "node_modules/camelcase": {
+            "version": "6.3.0",
+            "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+            "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
         "node_modules/chalk": {
             "version": "4.1.2",
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -428,8 +591,18 @@
         "node_modules/chownr": {
             "version": "1.1.4",
             "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
-            "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
-            "dev": true
+            "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+        },
+        "node_modules/cli-boxes": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
+            "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==",
+            "engines": {
+                "node": ">=6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
         },
         "node_modules/cli-cursor": {
             "version": "3.1.0",
@@ -545,6 +718,20 @@
             "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
             "dev": true
         },
+        "node_modules/cpu-features": {
+            "version": "0.0.8",
+            "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.8.tgz",
+            "integrity": "sha512-BbHBvtYhUhksqTjr6bhNOjGgMnhwhGTQmOoZGD+K7BCaQDCuZl/Ve1ZxUSMRwVC4D/rkCPQ2MAIeYzrWyK7eEg==",
+            "hasInstallScript": true,
+            "optional": true,
+            "dependencies": {
+                "buildcheck": "~0.0.6",
+                "nan": "^2.17.0"
+            },
+            "engines": {
+                "node": ">=10.0.0"
+            }
+        },
         "node_modules/create-require": {
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
@@ -555,7 +742,6 @@
             "version": "4.3.4",
             "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
             "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
-            "dev": true,
             "dependencies": {
                 "ms": "2.1.2"
             },
@@ -641,6 +827,59 @@
                 "node": ">=8"
             }
         },
+        "node_modules/docker-modem": {
+            "version": "3.0.8",
+            "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.8.tgz",
+            "integrity": "sha512-f0ReSURdM3pcKPNS30mxOHSbaFLcknGmQjwSfmbcdOw1XWKXVhukM3NJHhr7NpY9BIyyWQb0EBo3KQvvuU5egQ==",
+            "dependencies": {
+                "debug": "^4.1.1",
+                "readable-stream": "^3.5.0",
+                "split-ca": "^1.0.1",
+                "ssh2": "^1.11.0"
+            },
+            "engines": {
+                "node": ">= 8.0"
+            }
+        },
+        "node_modules/dockerode": {
+            "version": "3.3.5",
+            "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-3.3.5.tgz",
+            "integrity": "sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA==",
+            "dependencies": {
+                "@balena/dockerignore": "^1.0.2",
+                "docker-modem": "^3.0.0",
+                "tar-fs": "~2.0.1"
+            },
+            "engines": {
+                "node": ">= 8.0"
+            }
+        },
+        "node_modules/dockerode/node_modules/tar-fs": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz",
+            "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==",
+            "dependencies": {
+                "chownr": "^1.1.1",
+                "mkdirp-classic": "^0.5.2",
+                "pump": "^3.0.0",
+                "tar-stream": "^2.0.0"
+            }
+        },
+        "node_modules/dockerode/node_modules/tar-stream": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+            "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+            "dependencies": {
+                "bl": "^4.0.3",
+                "end-of-stream": "^1.4.1",
+                "fs-constants": "^1.0.0",
+                "inherits": "^2.0.3",
+                "readable-stream": "^3.1.1"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
         "node_modules/dotenv": {
             "version": "16.3.1",
             "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
@@ -655,8 +894,7 @@
         "node_modules/emoji-regex": {
             "version": "8.0.0",
             "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-            "dev": true
+            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
         },
         "node_modules/enabled": {
             "version": "2.0.0",
@@ -667,7 +905,6 @@
             "version": "1.4.4",
             "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
             "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
-            "dev": true,
             "dependencies": {
                 "once": "^1.4.0"
             }
@@ -690,6 +927,16 @@
                 "node": ">=6"
             }
         },
+        "node_modules/fast-deep-equal": {
+            "version": "3.1.3",
+            "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+            "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+        },
+        "node_modules/fast-fifo": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.0.tgz",
+            "integrity": "sha512-IgfweLvEpwyA4WgiQe9Nx6VV2QkML2NkvZnk1oKnIzXgXdWxuhF7zw4DvLTPZJn6PIUneiAXPF24QmoEqHTjyw=="
+        },
         "node_modules/fast-glob": {
             "version": "3.3.1",
             "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
@@ -812,22 +1059,19 @@
         "node_modules/fs-constants": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
-            "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
-            "dev": true
+            "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
         },
         "node_modules/fs-extra": {
-            "version": "9.1.0",
-            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
-            "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
-            "dev": true,
+            "version": "11.1.1",
+            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz",
+            "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==",
             "dependencies": {
-                "at-least-node": "^1.0.0",
                 "graceful-fs": "^4.2.0",
                 "jsonfile": "^6.0.1",
                 "universalify": "^2.0.0"
             },
             "engines": {
-                "node": ">=10"
+                "node": ">=14.14"
             }
         },
         "node_modules/function-bind": {
@@ -886,8 +1130,7 @@
         "node_modules/graceful-fs": {
             "version": "4.2.11",
             "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
-            "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
-            "dev": true
+            "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
         },
         "node_modules/has": {
             "version": "1.0.3",
@@ -1012,7 +1255,6 @@
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
             "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-            "dev": true,
             "engines": {
                 "node": ">=8"
             }
@@ -1086,11 +1328,26 @@
                 "node": ">=4"
             }
         },
+        "node_modules/json-schema-traverse": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+            "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
+        },
+        "node_modules/json5": {
+            "version": "2.2.3",
+            "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+            "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+            "bin": {
+                "json5": "lib/cli.js"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
         "node_modules/jsonfile": {
             "version": "6.1.0",
             "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
             "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
-            "dev": true,
             "dependencies": {
                 "universalify": "^2.0.0"
             },
@@ -1222,8 +1479,7 @@
         "node_modules/mkdirp-classic": {
             "version": "0.5.3",
             "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
-            "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
-            "dev": true
+            "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
         },
         "node_modules/ms": {
             "version": "2.1.2",
@@ -1254,6 +1510,12 @@
                 "readable-stream": "^3.6.0"
             }
         },
+        "node_modules/nan": {
+            "version": "2.17.0",
+            "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
+            "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
+            "optional": true
+        },
         "node_modules/napi-build-utils": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
@@ -1296,7 +1558,6 @@
             "version": "1.4.0",
             "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
             "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
-            "dev": true,
             "dependencies": {
                 "wrappy": "1"
             }
@@ -1433,6 +1694,36 @@
                 "pkg-fetch": "lib-es5/bin.js"
             }
         },
+        "node_modules/pkg-fetch/node_modules/fs-extra": {
+            "version": "9.1.0",
+            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+            "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+            "dev": true,
+            "dependencies": {
+                "at-least-node": "^1.0.0",
+                "graceful-fs": "^4.2.0",
+                "jsonfile": "^6.0.1",
+                "universalify": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/pkg/node_modules/fs-extra": {
+            "version": "9.1.0",
+            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+            "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+            "dev": true,
+            "dependencies": {
+                "at-least-node": "^1.0.0",
+                "graceful-fs": "^4.2.0",
+                "jsonfile": "^6.0.1",
+                "universalify": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
         "node_modules/prebuild-install": {
             "version": "7.1.1",
             "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
@@ -1483,12 +1774,19 @@
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
             "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
-            "dev": true,
             "dependencies": {
                 "end-of-stream": "^1.1.0",
                 "once": "^1.3.1"
             }
         },
+        "node_modules/punycode": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+            "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
         "node_modules/queue-microtask": {
             "version": "1.2.3",
             "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -1509,6 +1807,11 @@
                 }
             ]
         },
+        "node_modules/queue-tick": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
+            "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
+        },
         "node_modules/rc": {
             "version": "1.2.8",
             "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@@ -1546,6 +1849,14 @@
                 "node": ">=0.10.0"
             }
         },
+        "node_modules/require-from-string": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+            "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
         "node_modules/resolve": {
             "version": "1.22.2",
             "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
@@ -1647,6 +1958,11 @@
                 "node": ">=10"
             }
         },
+        "node_modules/safer-buffer": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+            "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+        },
         "node_modules/semver": {
             "version": "7.5.4",
             "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
@@ -1729,6 +2045,28 @@
                 "node": ">=8"
             }
         },
+        "node_modules/split-ca": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz",
+            "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ=="
+        },
+        "node_modules/ssh2": {
+            "version": "1.14.0",
+            "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.14.0.tgz",
+            "integrity": "sha512-AqzD1UCqit8tbOKoj6ztDDi1ffJZ2rV2SwlgrVVrHPkV5vWqGJOVp5pmtj18PunkPJAuKQsnInyKV+/Nb2bUnA==",
+            "hasInstallScript": true,
+            "dependencies": {
+                "asn1": "^0.2.6",
+                "bcrypt-pbkdf": "^1.0.2"
+            },
+            "engines": {
+                "node": ">=10.16.0"
+            },
+            "optionalDependencies": {
+                "cpu-features": "~0.0.8",
+                "nan": "^2.17.0"
+            }
+        },
         "node_modules/stack-trace": {
             "version": "0.0.10",
             "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
@@ -1776,6 +2114,15 @@
                 "safe-buffer": "~5.1.0"
             }
         },
+        "node_modules/streamx": {
+            "version": "2.15.1",
+            "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz",
+            "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==",
+            "dependencies": {
+                "fast-fifo": "^1.1.0",
+                "queue-tick": "^1.0.1"
+            }
+        },
         "node_modules/string_decoder": {
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@@ -1788,7 +2135,6 @@
             "version": "4.2.3",
             "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
             "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-            "dev": true,
             "dependencies": {
                 "emoji-regex": "^8.0.0",
                 "is-fullwidth-code-point": "^3.0.0",
@@ -1853,7 +2199,7 @@
                 "tar-stream": "^2.1.4"
             }
         },
-        "node_modules/tar-stream": {
+        "node_modules/tar-fs/node_modules/tar-stream": {
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
             "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
@@ -1869,6 +2215,16 @@
                 "node": ">=6"
             }
         },
+        "node_modules/tar-stream": {
+            "version": "3.1.6",
+            "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz",
+            "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==",
+            "dependencies": {
+                "b4a": "^1.6.4",
+                "fast-fifo": "^1.2.0",
+                "streamx": "^2.15.0"
+            }
+        },
         "node_modules/text-hex": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
@@ -1964,6 +2320,22 @@
                 "node": "*"
             }
         },
+        "node_modules/tweetnacl": {
+            "version": "0.14.5",
+            "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+            "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
+        },
+        "node_modules/type-fest": {
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+            "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
         "node_modules/typescript": {
             "version": "5.1.6",
             "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
@@ -1981,11 +2353,18 @@
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
             "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
-            "dev": true,
             "engines": {
                 "node": ">= 10.0.0"
             }
         },
+        "node_modules/uri-js": {
+            "version": "4.4.1",
+            "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+            "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+            "dependencies": {
+                "punycode": "^2.1.0"
+            }
+        },
         "node_modules/util-deprecate": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -2021,6 +2400,17 @@
                 "webidl-conversions": "^3.0.0"
             }
         },
+        "node_modules/widest-line": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
+            "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
+            "dependencies": {
+                "string-width": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
         "node_modules/winston": {
             "version": "3.10.0",
             "resolved": "https://registry.npmjs.org/winston/-/winston-3.10.0.tgz",
@@ -2059,7 +2449,6 @@
             "version": "7.0.0",
             "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
             "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-            "dev": true,
             "dependencies": {
                 "ansi-styles": "^4.0.0",
                 "string-width": "^4.1.0",
@@ -2075,8 +2464,7 @@
         "node_modules/wrappy": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-            "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
-            "dev": true
+            "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
         },
         "node_modules/y18n": {
             "version": "5.0.8",
diff --git a/ExerciceChecker/package.json b/ExerciceChecker/package.json
index de22b9cff0f10fc06b3f281ca913857a8fef376a..1b15b659501c90fede5408afdb8a567154f57759 100644
--- a/ExerciceChecker/package.json
+++ b/ExerciceChecker/package.json
@@ -1,6 +1,6 @@
 {
     "name"           : "dojo_exercice_checker",
-    "version"        : "0.0.1",
+    "version"        : "1.0.0",
     "main"           : "dist/app.js",
     "bin"            : {
         "dirmanager": "./dist/app.js"
@@ -9,7 +9,8 @@
         "scripts": [],
         "assets" : [
             "node_modules/axios/dist/node/axios.cjs",
-            ".env"
+            ".env",
+            "assets/**/*"
         ],
         "targets": [
             "node18-linux-arm64",
@@ -22,17 +23,27 @@
         "test"     : "echo \"Error: no test specified\" && exit 1"
     },
     "dependencies"   : {
+        "ajv"              : "^8.12.0",
         "axios"            : "^1.4.0",
+        "boxen"            : "^5.1.2",
         "chalk"            : "^4.1.2",
+        "dockerode"        : "^3.3.5",
         "dotenv"           : "^16.3.1",
+        "fs-extra"         : "^11.1.1",
         "http-status-codes": "^2.2.0",
+        "json5"            : "^2.2.3",
         "ora"              : "^5.4.1",
+        "tar-stream"       : "^3.1.6",
         "winston"          : "^3.10.0"
     },
     "devDependencies": {
-        "@types/node"        : "^18.17.1",
-        "pkg"                : "^5.8.1",
-        "ts-node"            : "^10.9.1",
-        "typescript"         : "^5.1.6"
+        "@types/dockerode" : "^3.3.19",
+        "@types/fs-extra"  : "^11.0.1",
+        "@types/js-yaml"   : "^4.0.5",
+        "@types/node"      : "^18.17.1",
+        "@types/tar-stream": "^2.2.2",
+        "pkg"              : "^5.8.1",
+        "ts-node"          : "^10.9.1",
+        "typescript"       : "^5.1.6"
     }
 }
diff --git a/ExerciceChecker/src/app.ts b/ExerciceChecker/src/app.ts
index a4f2ffd64f0abf492d16f4dc0565f872fb1991db..afc0cb62d547d4edeef34c18e72cace834e7b359 100644
--- a/ExerciceChecker/src/app.ts
+++ b/ExerciceChecker/src/app.ts
@@ -4,20 +4,173 @@ const path = require('node:path');
 require('dotenv').config({ path: path.join(__dirname, '../.env') });
 require('./shared/helpers/TypeScriptExtensions'); // ATTENTION : This line MUST be the second of this file
 
-import chalk       from 'chalk';
-import HttpManager from './managers/HttpManager';
+import Styles               from './types/Styles';
+import Icon                 from './types/Icon';
+import boxen                from 'boxen';
+import RecursiveFilesStats  from './shared/helpers/recursiveFilesStats/RecursiveFilesStats';
+import Toolbox              from './shared/helpers/Toolbox';
+import ExerciceHelper       from './shared/helpers/ExerciceHelper';
+import ExerciceCheckerError from './types/ExerciceCheckerError';
+import { exec, spawn }      from 'child_process';
+import util                 from 'util';
+import fs                   from 'fs-extra';
+import HttpManager          from './managers/HttpManager';
+import DojoBackendManager   from './managers/DojoBackendManager';
+import Config               from './config/Config';
+import ArchiveHelper        from './shared/helpers/ArchiveHelper';
 
 
-HttpManager.registerAxiosInterceptor();
+(async () => {
+    const execAsync = util.promisify(exec);
 
+    HttpManager.registerAxiosInterceptor();
 
-console.log(chalk.blue('Dojo Exercice Checker'));
+    console.log(Styles.APP_NAME(Config.appName));
 
+    /*
+     //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 1 & 2:
+     -   Read the dojo enonce file from the enonce repository
+     -   Download immutables files (maybe throw or show an error if the files have been modified ?)
+     */
+    console.log(Styles.INFO(`${ Icon.INFO }️ Checking the exercice's enonce and his immutable files`));
+    const exerciceEnonce = await DojoBackendManager.getExerciceEnonce();
+    if ( !exerciceEnonce ) {
+        console.error(Styles.ERROR(`${ Icon.ERROR } Error while getting the exercice's enonce`));
+        process.exit(ExerciceCheckerError.EXERCICE_ENONCE_GET_ERROR);
+    }
 
-// Step 1: Read the dojo enonce file from the enonce repository
-// Step 2: Download immutables files (maybe throw or show an error if the files have been modified ?) - Can be merged with step 1
-// Step 3: Run docker-compose file
-// Step 4: Wait the end of the execution of the result container
-// Step 5: Get the result from the volume
-// Step 6: Check content requirements and content size
-// Step 7: Upload and show the results
\ No newline at end of file
+    exerciceEnonce.immutable.forEach(immutableFile => {
+        const filePath = path.join(Config.folders.project, immutableFile.file_path);
+        fs.mkdirSync(path.dirname(filePath), { recursive: true });
+        fs.writeFileSync(filePath, immutableFile.content, { encoding: 'base64' });
+    });
+
+
+    /*
+     //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 3 & 4 & 5:
+     - Get override of docker-compose file (for override the volume by a bind mount to the results folder shared between dind and the host)
+     - Run docker-compose file
+     - Get logs from linked services
+     */
+    console.log(Styles.INFO(`${ Icon.INFO } Run docker compose file`));
+    const dockerComposeOverride = fs.readFileSync(path.join(__dirname, '../assets/docker-compose-override.yml'), 'utf8').replace('{{VOLUME_NAME}}', exerciceEnonce.enonceFile.result.volume).replace('{{MOUNT_PATH}}', Config.folders.resultsExercice);
+    fs.writeFileSync(`${ Config.folders.project }/docker-compose-override.yml`, dockerComposeOverride);
+
+    const changeDirectoryCommand = `cd "${ Config.folders.project }"`;
+    const dockerComposeCommand = `docker compose --project-name ${ Config.dockerCompose.projectName } --progress plain --file docker-compose.yml --file docker-compose-override.yml`;
+
+    const containerExitStatus = await new Promise<[ number, string ]>((resolve) => {
+        let logs = '####################################################### Docker Compose & Main Container Logs #######################################################\n';
+
+        const dockerCompose = spawn(`${ dockerComposeCommand } run --build ${ exerciceEnonce.enonceFile.result.container }`, {
+            cwd  : Config.folders.project,
+            shell: true,
+            env  : {
+                'DOCKER_BUILDKIT'  : '1',
+                'BUILDKIT_PROGRESS': 'plain', ...process.env
+            }
+        });
+
+        dockerCompose.stdout.on('data', (data) => {
+            logs += data.toString();
+            console.log(data.toString());
+        });
+
+        dockerCompose.stderr.on('data', (data) => {
+            logs += data.toString();
+            console.error(data.toString());
+        });
+
+        dockerCompose.on('exit', (code) => {
+            logs += '####################################################### Other Services Logs #######################################################\n';
+            resolve([ code ?? ExerciceCheckerError.DOCKER_COMPOSE_UP_ERROR, logs ]);
+        });
+    });
+    const containerExitCode = containerExitStatus[0];
+    if ( containerExitCode === ExerciceCheckerError.DOCKER_COMPOSE_UP_ERROR ) {
+        console.error(Styles.ERROR(`${ Icon.ERROR } Error while running the docker compose file`));
+        process.exit(containerExitCode);
+    }
+    fs.writeFileSync(`${ Config.folders.resultsDojo }/dockerComposeLogs.txt`, containerExitStatus[1]);
+
+    console.log(Styles.INFO(`${ Icon.INFO } Acquire logs of linked services`));
+    try {
+        await execAsync(`${ changeDirectoryCommand };${ dockerComposeCommand } logs --timestamps >> ${ Config.folders.resultsDojo }/dockerComposeLogs.txt`);
+    } catch ( error ) {
+        console.error(Styles.ERROR(`${ Icon.ERROR } Error while getting the linked services logs`));
+        process.exit(ExerciceCheckerError.DOCKER_COMPOSE_LOGS_ERROR);
+    }
+
+
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 6: Check content requirements and content size
+    console.log(Styles.INFO(`${ Icon.INFO } Validating results folder size`));
+    const resultsFolderSize = await Toolbox.fs.getTotalSize(Config.folders.resultsExercice);
+    if ( resultsFolderSize > Config.resultsFolderMaxSizeInBytes ) {
+        console.error(Styles.ERROR(`${ Icon.ERROR } Results folder size is too big (bigger than ${ Config.resultsFolderMaxSizeInBytes / 1000000 })`));
+        process.exit(ExerciceCheckerError.EXERCICE_RESULTS_FOLDER_TOO_BIG);
+    }
+
+    console.log(Styles.INFO(`${ Icon.INFO } Checking results file`));
+    const resultsFileOriginPath = path.join(Config.folders.resultsExercice, Config.filenames.results);
+    const resultsFilePath = path.join(Config.folders.resultsDojo, Config.filenames.results);
+
+    if ( !fs.existsSync(resultsFileOriginPath) ) {
+        console.error(Styles.ERROR(`${ Icon.ERROR } Results file not found.`));
+        process.exit(ExerciceCheckerError.EXERCICE_RESULTS_FILE_NOT_FOUND);
+    }
+
+    fs.moveSync(resultsFileOriginPath, resultsFilePath, { overwrite: true });
+
+    const validationResults = ExerciceHelper.validateResultFile(resultsFilePath);
+
+    if ( !validationResults.isValid ) {
+        console.error(Styles.ERROR(`${ Icon.ERROR } Results file is not valid. Here are the errors :`));
+        console.error(Styles.ERROR(JSON.stringify(validationResults.errors)));
+        process.exit(ExerciceCheckerError.EXERCICE_RESULTS_FILE_SCHEMA_NOT_VALID);
+    }
+
+
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 7: Upload and show the results
+    try {
+        console.log(Styles.INFO(`${ Icon.INFO } Uploading results to the dojo server`));
+        const commit: any = {};
+        Toolbox.getKeysWithPrefix(process.env, 'CI_COMMIT_').forEach(key => {
+            commit[Toolbox.snakeToCamel(key.replace('CI_COMMIT_', ''))] = process.env[key];
+        });
+
+        const files = await RecursiveFilesStats.explore(Config.folders.resultsVolume, {
+            replacePathByRelativeOne: true,
+            liteStats               : true
+        });
+
+        await DojoBackendManager.sendResults(containerExitCode, commit, validationResults.results!, files, await ArchiveHelper.getBase64(Config.folders.resultsVolume));
+    } catch ( error ) {
+        console.error(Styles.ERROR(`${ Icon.ERROR } Error while uploading the results`));
+        console.error(JSON.stringify(error));
+        process.exit(ExerciceCheckerError.UPLOAD);
+    }
+
+
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 8: Exit with container exit code
+    const finalLogGlobalResult = `${ Styles.INFO('Global result') } : ${ validationResults.results!.success ? Styles.SUCCESS(`${ Icon.SUCCESS } Success`) : Styles.FAILURE(`${ Icon.FAILURE } Failure`) }`;
+
+    const finalLogExecutionExitCode = `${ Styles.INFO('Execution exit code') } : ${ (containerExitCode == 0 ? Styles.SUCCESS : Styles.ERROR)(containerExitCode) }`;
+
+    const finalLogResultNumbers = validationResults.results!.successfulTests || validationResults.results!.failedTests ? `\n\n${ Styles.SUCCESS('Tests passed') } : ${ validationResults.results!.successfulTests ?? '--' }\n${ Styles.ERROR('Tests failed') } : ${ validationResults.results!.failedTests ?? '--' }` : '';
+
+    const finalLogSuccessResultDetails = (validationResults.results!.successfulTestsList ?? []).map(testName => `- ${ Icon.SUCCESS } ${ testName }`).join('\n');
+    const finalLogFailedResultDetails = (validationResults.results!.failedTestsList ?? []).map(testName => `- ${ Icon.FAILURE } ${ testName }`).join('\n');
+    const finalLogResultDetails = validationResults.results!.successfulTestsList || validationResults.results!.failedTestsList ? `\n\n${ Styles.INFO('Tests') } :${ finalLogSuccessResultDetails != '' ? '\n' + finalLogSuccessResultDetails : '' }${ finalLogFailedResultDetails != '' ? '\n' + finalLogFailedResultDetails : '' }` : '';
+
+    console.log(boxen(`${ finalLogGlobalResult }\n\n${ finalLogExecutionExitCode }${ finalLogResultNumbers }${ finalLogResultDetails }`, {
+        title         : 'Results',
+        titleAlignment: 'center',
+        borderColor   : 'yellow',
+        borderStyle   : 'bold',
+        margin        : 1,
+        padding       : 1,
+        textAlignment : 'left'
+    }));
+
+    process.exit(containerExitCode);
+})();
\ No newline at end of file
diff --git a/ExerciceChecker/src/config/Config.ts b/ExerciceChecker/src/config/Config.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6782c1447cc3451953505896560565b424fda141
--- /dev/null
+++ b/ExerciceChecker/src/config/Config.ts
@@ -0,0 +1,61 @@
+import fs   from 'fs-extra';
+import path from 'path';
+
+
+class Config {
+    public readonly appName: string;
+
+    public readonly resultsFolderMaxSizeInBytes: number;
+
+    public readonly folders: {
+        project: string; resultsVolume: string; resultsDojo: string; resultsExercice: string;
+    };
+
+    public readonly filenames: {
+        results: string;
+    };
+
+    public readonly exercice: {
+        id: string; secret: string;
+    };
+
+    public readonly dockerCompose: {
+        projectName: string
+    };
+
+    constructor() {
+        this.appName = process.env.APP_NAME || '';
+
+        this.resultsFolderMaxSizeInBytes = Number(process.env.RESULTS_FOLDER_MAX_SIZE_IN_BYTES || 0);
+
+        this.folders = {
+            project        : process.env.FILES_FOLDER?.convertWithEnvVars() ?? './',
+            resultsVolume  : process.env.RESULTS_VOLUME?.convertWithEnvVars() ?? '',
+            resultsDojo    : path.join(process.env.RESULTS_VOLUME?.convertWithEnvVars() ?? '', 'Dojo/'),
+            resultsExercice: path.join(process.env.RESULTS_VOLUME?.convertWithEnvVars() ?? '', 'Exercice/')
+        };
+        this.resetResultsVolume();
+
+        this.filenames = {
+            results: process.env.RESULTS_FILENAME || ''
+        };
+
+        this.exercice = {
+            id    : process.env.DOJO_EXERCICE_ID || '',
+            secret: process.env.DOJO_SECRET || ''
+        };
+
+        this.dockerCompose = {
+            projectName: process.env.DOCKER_COMPOSE_PROJECT_NAME || ''
+        };
+    }
+
+    private resetResultsVolume(): void {
+        fs.emptyDirSync(this.folders.resultsVolume);
+        fs.emptyDirSync(this.folders.resultsDojo);
+        fs.emptyDirSync(this.folders.resultsExercice);
+    }
+}
+
+
+export default new Config();
diff --git a/ExerciceChecker/src/managers/DojoBackendManager.ts b/ExerciceChecker/src/managers/DojoBackendManager.ts
index d64a25881c49bf67ddccb315ff2a08ba42033875..c1cb4c6df7f4f4d26023acd14ef1a7fe22245142 100644
--- a/ExerciceChecker/src/managers/DojoBackendManager.ts
+++ b/ExerciceChecker/src/managers/DojoBackendManager.ts
@@ -1,11 +1,38 @@
 import ClientsSharedConfig from '../sharedByClients/config/ClientsSharedConfig';
 import ApiRoutes           from '../sharedByClients/types/ApiRoutes';
+import axios               from 'axios';
+import DojoResponse        from '../shared/types/Dojo/DojoResponse';
+import ExerciceEnonce      from '../sharedByClients/models/ExerciceEnonce';
+import Config              from '../config/Config';
+import ExerciceResultsFile from '../shared/types/Dojo/ExerciceResultsFile';
 
 
 class DojoBackendManager {
     public getApiUrl(route: ApiRoutes): string {
         return `${ ClientsSharedConfig.apiURL }${ route }`;
     }
+
+    public async getExerciceEnonce(): Promise<ExerciceEnonce | undefined> {
+        try {
+            return (await axios.get<DojoResponse<ExerciceEnonce>>(this.getApiUrl(ApiRoutes.EXERCICE_ENONCE).replace('{{id}}', Config.exercice.id))).data.data;
+        } catch ( error ) {
+            return undefined;
+        }
+    }
+
+    public async sendResults(exitCode: number, commit: any, results: ExerciceResultsFile, files: any, archiveBase64: string): Promise<void> {
+        try {
+            await axios.post(this.getApiUrl(ApiRoutes.EXERCICE_RESULTS).replace('{{id}}', Config.exercice.id), {
+                exitCode     : exitCode,
+                commit       : JSON.stringify(commit),
+                results      : JSON.stringify(results),
+                files        : JSON.stringify(files),
+                archiveBase64: archiveBase64
+            });
+        } catch ( error ) {
+            throw error;
+        }
+    }
 }
 
 
diff --git a/ExerciceChecker/src/managers/HttpManager.ts b/ExerciceChecker/src/managers/HttpManager.ts
index 9cf17d86d269c27be5a92a164b68777acf269ac9..432e456dd35231502321f8f4d11b410f3dc1f0ef 100644
--- a/ExerciceChecker/src/managers/HttpManager.ts
+++ b/ExerciceChecker/src/managers/HttpManager.ts
@@ -1,6 +1,7 @@
 import axios, { AxiosRequestHeaders } from 'axios';
 import FormData                       from 'form-data';
 import ClientsSharedConfig            from '../sharedByClients/config/ClientsSharedConfig';
+import Config                         from '../config/Config';
 
 
 class HttpManager {
@@ -18,9 +19,13 @@ class HttpManager {
             }
 
             if ( config.url && (config.url.indexOf(ClientsSharedConfig.apiURL) !== -1) ) {
+                config.headers['Accept-Encoding'] = 'gzip';
+
                 if ( config.data && Object.keys(config.data).length > 0 ) {
                     config.headers['Content-Type'] = 'multipart/form-data';
                 }
+
+                config.headers.Authorization = `ExerciceSecret ${ Config.exercice.secret }`;
             }
 
             return config;
diff --git a/ExerciceChecker/src/shared b/ExerciceChecker/src/shared
index c9154d42dac81311cf1957f0d75f806737849b40..eab5c0a5a32079fcb439a1ad79453611c8605536 160000
--- a/ExerciceChecker/src/shared
+++ b/ExerciceChecker/src/shared
@@ -1 +1 @@
-Subproject commit c9154d42dac81311cf1957f0d75f806737849b40
+Subproject commit eab5c0a5a32079fcb439a1ad79453611c8605536
diff --git a/ExerciceChecker/src/sharedByClients b/ExerciceChecker/src/sharedByClients
index 8fe8e9417a527cf2182a9acc440e68b99024487e..c0f105590a4332ce4d6eff046324e537e769f756 160000
--- a/ExerciceChecker/src/sharedByClients
+++ b/ExerciceChecker/src/sharedByClients
@@ -1 +1 @@
-Subproject commit 8fe8e9417a527cf2182a9acc440e68b99024487e
+Subproject commit c0f105590a4332ce4d6eff046324e537e769f756
diff --git a/ExerciceChecker/src/types/ExerciceCheckerError.ts b/ExerciceChecker/src/types/ExerciceCheckerError.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2bb09d5c99b395c073ee2f7c61727de1ea910ea3
--- /dev/null
+++ b/ExerciceChecker/src/types/ExerciceCheckerError.ts
@@ -0,0 +1,12 @@
+enum ExerciceCheckerError {
+    EXERCICE_ENONCE_GET_ERROR              = 200,
+    DOCKER_COMPOSE_UP_ERROR                = 201,
+    DOCKER_COMPOSE_LOGS_ERROR              = 202,
+    EXERCICE_RESULTS_FOLDER_TOO_BIG        = 203,
+    EXERCICE_RESULTS_FILE_NOT_FOUND        = 204,
+    EXERCICE_RESULTS_FILE_SCHEMA_NOT_VALID = 205,
+    UPLOAD                                 = 206
+}
+
+
+export default ExerciceCheckerError;
\ No newline at end of file
diff --git a/ExerciceChecker/src/types/Icon.ts b/ExerciceChecker/src/types/Icon.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9d5a0ec79d20073891288ac585615e8ead980132
--- /dev/null
+++ b/ExerciceChecker/src/types/Icon.ts
@@ -0,0 +1,9 @@
+enum Icon {
+    INFO    = 'ℹ️',
+    ERROR   = '⛔️',
+    SUCCESS = '✅',
+    FAILURE = '❌'
+}
+
+
+export default Icon;
\ No newline at end of file
diff --git a/ExerciceChecker/src/types/Styles.ts b/ExerciceChecker/src/types/Styles.ts
new file mode 100644
index 0000000000000000000000000000000000000000..64f6bdd5ea6ce4b1481560d600582021de114744
--- /dev/null
+++ b/ExerciceChecker/src/types/Styles.ts
@@ -0,0 +1,13 @@
+import chalk from 'chalk';
+
+
+class Styles {
+    public readonly APP_NAME = chalk.bgBlue.black.bold;
+    public readonly INFO = chalk.blue;
+    public readonly ERROR = chalk.red;
+    public readonly SUCCESS = chalk.green;
+    public readonly FAILURE = chalk.red;
+}
+
+
+export default new Styles();
\ No newline at end of file
diff --git a/ExerciceChecker/tsconfig.json b/ExerciceChecker/tsconfig.json
index d7ed4058faf2c72d3e112f4a0b4378e8a0ee1235..88b6af04266eaeba378778af03b22e9473448127 100644
--- a/ExerciceChecker/tsconfig.json
+++ b/ExerciceChecker/tsconfig.json
@@ -1,16 +1,16 @@
 {
     "compilerOptions": {
-        "rootDir": "src",
-        "outDir": "dist",
-        "strict": true,
-        "target": "es6",
-        "module": "commonjs",
-        "sourceMap": true,
-        "esModuleInterop": true,
+        "rootDir"         : "src",
+        "outDir"          : "dist",
+        "strict"          : true,
+        "target"          : "es6",
+        "module"          : "commonjs",
+        "sourceMap"       : true,
+        "esModuleInterop" : true,
         "moduleResolution": "node",
-        "noImplicitAny": true
+        "noImplicitAny"   : true
     },
-    "exclude": [
+    "exclude"        : [
         "node_modules"
     ]
 }
\ No newline at end of file