diff --git a/ci-wrappers.sh b/ci-wrappers.sh
new file mode 100644
index 0000000000000000000000000000000000000000..021af0eb17cc03b54006b3a6cadd4b2d7506324e
--- /dev/null
+++ b/ci-wrappers.sh
@@ -0,0 +1,245 @@
+#!/bin/bash
+
+_B_TITLE='\033[0;33m'
+_E_TITLE='\033[0;0m'
+
+VAGRANT_VERSION=2.3.3
+TERRAFORM_VERSION=1.3.6
+DOCKER_CLIENT_VERSION=20.10.19
+DOCKER_COMPOSE_VERSION=2.13.0
+
+MAVEN_DEFAULT_IMAGE="brunoe/maven:3.8.6-eclipse-temurin-17"
+JAVA_DEFAULT_ARCHETYPE_GROUPID="fr.univtln.bruno.demos.archetypes"
+JAVA_DEFAULT_ARCHETYPE_ARTIFACTID="demomavenarchetype"
+JAVA_DEFAULT_ARCHETYPE_VERSION="1.1-SNAPSHOT"
+
+ci-wrappers-usage() {
+  echo "install-dockerclient-vagrant-terraform\n\t installs a docker client, vagant and terraform in ${HOME}/bin"
+  echo "new-java-project [projectname]\n\t create a new java+maven project ready for CI"
+  echo "docker-wrapper"
+  echo "docker-wrapper-build"
+  echo "docker-wrapper-build-all"
+  echo "docker-wrapper-run-all"
+  echo "docker-mvn"
+  echo "docker-sonar-analysis"
+}
+
+install-dockerclient-vagrant-terraform() {
+  mkdir -p ${HOME}/bin &&
+    dockerCurrentVersion=$(docker --version|cut -d  " " -f 3|tr -d ',')
+    if [ -f ${HOME}/bin/docker ]; then
+      curl -sL https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_CLIENT_VERSION}.tgz |
+        tar --directory=${HOME}/bin/ --strip-components=1 -zx docker/docker &&
+        chmod +x ${HOME}/bin/docker
+    else
+      echo "docker client already installed"
+    fi
+  if [ -f ${HOME}/.docker/cli-plugins/docker-compose ]; then
+    mkdir -p ${HOME}/.docker/cli-plugins/ &&
+      curl -SL https://github.com/docker/compose/releases/download/v${DOCKER_COMPOSE_VERSION}/docker-compose-linux-x86_64 -o ${HOME}/.docker/cli-plugins/docker-compose &&
+      chmod +x ${HOME}/.docker/cli-plugins/docker-compose
+  else
+    echo "docker compose already installed"
+  fi
+
+  if [ -f ${HOME}/bin/vagrant ]; then
+    export PATH=${HOME}/bin:$PATH &&
+      wget -qO- https://releases.hashicorp.com/vagrant/${vagrant_VAGRANT_VERSION}/${vagrant_VAGRANT_VERSION}_linux_amd64.zip | gunzip - \
+        >${HOME}/bin/vagrant &&
+      chmod +x ${HOME}/bin/vagrant
+  else
+    echo "vagrant already installed"
+  fi
+  if [ -f ${HOME}/bin/terraform ]; then
+    export PATH=${HOME}/bin:$PATH &&
+      wget -qO- https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip | gunzip - \
+        >${HOME}/bin/terraform &&
+      chmod +x ${HOME}/bin/terraform
+  else
+    echo "terraform already installed"
+  fi
+
+}
+
+provision-docker-engine() {
+  _check_variables VAGRANT_HTTP_PROXY VAGRANT_HTTPS_PROXY VAGRANT_NO_PROXY
+}
+
+_moveVBoxDefaultFolder() {
+  targetdirectory=${1:-/scratch/${USER}}
+  VBoxManage list systemproperties | grep "Current default machine folder:" &&
+    mkdir -p ${targetirectory} &&
+    vboxmanage setproperty machinefolder ${targetirectory}/VirtualBox\ VMs &&
+    echo -n "New " && VBoxManage list systemproperties | grep "Default machine folder:"
+}
+
+_check_needed_software() {
+  for c in docker vagrant; do
+    if [ -x "$(command -v ${c})" ]; then
+      echo $c not found
+    else
+      echo $c found
+    fi
+  done
+}
+
+_check_needed_variables() {
+  _check_variables GITHUBLOGIN GITHUBTOKEN GITHUB_ORG SONAR_URL SONAR_TOKEN
+}
+
+_check_variables() {
+  if [ -n "$ZSH_VERSION" ]; then emulate -L bash; fi
+  for varname in "$@"; do
+    v="${!varname}"
+    if [ ! -n "${v-unset}" ]; then
+      echo "$varname is not set: exiting"
+      exit 1
+    fi
+  done
+}
+
+# This utility function computes the image name and tag from the project directory and the git branch.
+_docker_env() {
+  DOCKER_REPO_NAME=${GITHUB_ORG}
+  IMAGE_NAME=$(echo ${PWD##*/} | tr '[:upper:]' '[:lower:]')
+  IMAGE_TAG=$(git rev-parse --abbrev-ref HEAD)
+  DOCKER_TARGET=${DOCKER_TARGET:-finalJLinkAlpine}
+  DOCKER_FULL_IMAGE_NAME="$DOCKER_REPO_NAME/$IMAGE_NAME:$IMAGE_TAG-$DOCKER_TARGET"
+}
+
+# This utility function look for final target in the docker file and compute docker image name and tag (oen by line).
+_docker-wrapper-all-images() (
+  for finalTarget in $(grep -E 'FROM.*final.*' docker/Dockerfile | tr -s ' ' | cut -f 4 -d ' '); do
+    DOCKER_TARGET="$finalTarget" _docker_env
+    echo "$finalTarget#${DOCKER_FULL_IMAGE_NAME}"
+  done
+)
+
+# This function is a wrapper around the docker command to passes the env (credentials, image names, ...)
+docker-wrapper() (
+  _docker_env
+  DOCKER_BUILDKIT=1 \
+    docker "$1" \
+    --file docker/Dockerfile \
+    --build-arg IMAGE_NAME="$IMAGE_NAME" \
+    --build-arg DOCKER_USERNAME="$DOCKER_USERNAME" \
+    --build-arg DOCKER_PASSWORD="$DOCKER_PASSWORD" \
+    --build-arg SONAR_TOKEN="$SONAR_TOKEN" \
+    --build-arg SONAR_URL="$SONAR_URL" \
+    --build-arg GITHUB_LOGIN="$GITHUB_LOGIN" \
+    --build-arg GITHUB_TOKEN="$GITHUB_TOKEN" \
+    --target "${DOCKER_TARGET}" \
+    -t "${DOCKER_FULL_IMAGE_NAME}" \
+    "${@: -1}"
+)
+
+# Build a target image ($DOCKER_TARGET)
+docker-wrapper-build() (
+  docker-wrapper build "$@" .
+)
+
+# Builds images for final targets of the Dockerfile
+docker-wrapper-build-all() (
+  for image in $(_docker-wrapper-all-images); do
+    finalTarget=$(echo "$image" | cut -f1 -d '#' -)
+    DOCKER_TARGET="$finalTarget" docker-wrapper-build "$@"
+  done
+  for image in $(_docker-wrapper-all-images); do
+    imageName=$(echo "$image" | cut -f2 -d '#' -)
+    docker image ls "$imageName" | tail -n+2
+  done
+)
+
+# Runs a target image ($DOCKER_TARGET)
+docker-wrapper-run() (
+  _docker_env
+  echo "Running ${DOCKER_FULL_IMAGE_NAME}"
+  docker run --rm -it "${DOCKER_FULL_IMAGE_NAME}"
+)
+
+#Runs all the final targets
+docker-wrapper-run-all() (
+  for image in $(_docker-wrapper-all-images); do
+    finalTarget=$(echo "$image" | cut -f1 -d '#' -)
+    time (DOCKER_TARGET="$finalTarget" docker-wrapper-run "$@")
+  done
+)
+
+# Runs maven in a container as the user
+# see https://github.com/ebpro/docker-maven
+docker-mvn() (
+  _docker_env
+  docker run \
+    --env IMAGE_NAME="$IMAGE_NAME" \
+    --env GITHUB_LOGIN="$GITHUB_LOGIN" \
+    --env GITHUB_TOKEN="$GITHUB_TOKEN" \
+    --env SONAR_URL="$SONAR_URL" \
+    --env SONAR_TOKEN="$SONAR_TOKEN" \
+    --env SONAR_URL="$SONAR_URL" \
+    --env SONAR_TOKEN="$SONAR_TOKEN" \
+    --env S6_LOGGING=1 \
+    --env S6_BEHAVIOUR_IF_STAGE2_FAILS \
+    --volume ${HOME}/.m2:/home/user/.m2 \
+    --volume ${HOME}/.ssh:/home/user/.ssh \
+    --volume ${HOME}/.gitconfig:/home/user/.gitconfig \
+    --volume "$
+    }(pwd)":/usr/src/mymaven \
+    --workdir /usr/src/mymaven \
+    --rm \
+    --env PUID=$(id -u) -e PGID=$(id -g) \
+    --env MAVEN_CONFIG=/home/user/.m2 \
+    "${MAVEN_IMAGE:-${MAVEN_DEFAULT_IMAGE}}" \
+    runuser --user user \
+    --group user \
+    -- mvn --errors --threads 1C --color always --strict-checksums \
+    -Duser.home=/home/user \
+    --settings /usr/src/mymaven/docker/ci-settings.xml "$@"
+)
+
+docker-sonar-analysis() (
+  docker-mvn -P jacoco,sonar \
+    -Dsonar.branch.name=$(git rev-parse --abbrev-ref HEAD | tr / _) \
+    verify sonar:sonar
+)
+
+new-java-project() (
+  printf "${_B_TITLE}Creating Java project ${_E_TITLE}"
+  if [[ ! $# -eq 2 ]]; then
+    echo "Usage: $0 <projectname> <groupid>"
+    exit 1
+  fi
+  _check_variables GITHUBLOGIN GITHUBORG GITHUBTOKEN
+  printf "${_B_TITLE}$1 with groupId $2${_E_TITLE}\n"
+  printf "${_B_TITLE}  calling maven archetype${_E_TITLE}\n"
+  mvn --quiet --color=always --batch-mode archetype:generate \
+    -DarchetypeGroupId=${JAVA_DEFAULT_ARCHETYPE_GROUPID} \
+    -DarchetypeArtifactId=${JAVA_DEFAULT_ARCHETYPE_ARTIFACTID} \
+    -DarchetypeVersion=${JAVA_DEFAULT_ARCHETYPE_VERSION} \
+    -DgithubAccount=${GITHUBORG} \
+    -DgroupId=${2} \
+    -DartifactId=${1} \
+    -Dversion=1.0-SNAPSHOT &&
+    cd ${1} &&
+    printf "${_B_TITLE}  Gitflow init${_E_TITLE}\n" &&
+    git flow init -d && git add . && git commit -m "sets initial release." &&
+    printf "${_B_TITLE}  gh-pages branch creation${_E_TITLE}\n" &&
+    git checkout --orphan gh-pages &&
+    git rm -rf . && touch index.html &&
+    git add . &&
+    git commit -m "sets initial empty site." &&
+    git checkout develop &&
+    printf "${_B_TITLE}  GitHub reposirory creation${_E_TITLE}\n" &&
+    gh repo create ${GITHUBORG}/${PWD##*/} --disable-wiki --private --source=. &&
+    printf "${_B_TITLE}  Generate a default deploy key${_E_TITLE}\n" &&
+    _generate_and_install_new_deploy_key ${GITHUBORG} ${1} &&
+    git push origin --mirror &&
+    gh repo view --web
+)
+
+_generate_and_install_new_deploy_key() (
+  tmpKeydir=$(mktemp --directory /tmp/ci-wrappers.XXXXXX)
+  ssh-keygen -q -t ed25519 -C "git@github.com:${1}/${2}.git" -N "" -f ${tmpKeydir}/key
+  gh repo deploy-key add --allow-write "${tmpKeydir}/key.pub"
+  gh secret set SSH_PRIVATE_KEY <"${tmpKeydir}/key"
+  rm -rf tmpKeydir
+)