diff --git a/ci-templates/auto-rules/no-default.yml b/ci-templates/auto-rules/no-default.yml
index 7db60c85ce87b5d9d5eaff4e31364303e66a15d8..d485c4b54e675217fca03520d1aca8fe59d56aa8 100644
--- a/ci-templates/auto-rules/no-default.yml
+++ b/ci-templates/auto-rules/no-default.yml
@@ -61,25 +61,25 @@ industrial_ci_noetic:
 
 
 industrial_kinetic_deploy:
-  extends:
-    - industrial_ci_kinetic
-    - .industrial_ci_deploy
+  extends: .ddeploy
+  variables:
+    ROS_DISTRO: kinetic
   rules:
     - if: $DEPLOY && $DEFAULT_DISTRO == "kinetic"
     - if: $DEPLOY && $BUILD_KINETIC
 
 industrial_melodic_deploy:
-  extends:
-    - industrial_ci_melodic
-    - .industrial_ci_deploy
+  extends: .ddeploy
+  variables:
+    ROS_DISTRO: melodic
   rules:
     - if: $DEPLOY && $DEFAULT_DISTRO == "melodic"
     - if: $DEPLOY && $BUILD_MELODIC
 
 industrial_noetic_deploy:
-  extends:
-    - industrial_ci_noetic
-    - .industrial_ci_deploy
+  extends: .ddeploy
+  variables:
+    ROS_DISTRO: noetic
   rules:
     - if: $DEPLOY && $DEFAULT_DISTRO == "noetic"
     - if: $DEPLOY && $BUILD_NOETIC
diff --git a/ci-templates/auto-rules/with-rosinstall/no-default.yml b/ci-templates/auto-rules/with-rosinstall/no-default.yml
index 5ffe30c97c3ad39aa849cf1d78ec392a81caeacf..6c72a4f6d8b28031f671eb7ee2b790410797d26f 100644
--- a/ci-templates/auto-rules/with-rosinstall/no-default.yml
+++ b/ci-templates/auto-rules/with-rosinstall/no-default.yml
@@ -4,3 +4,7 @@ include: ci-templates/auto-rules/no-default.yml
 .industrial_ci:
   variables:
     UPSTREAM_WORKSPACE: .rosinstall
+
+.ddeploy:
+  variables:
+    UPSTREAM_WORKSPACE: .rosinstall
diff --git a/ci-templates/industrial-ci-templates.yml b/ci-templates/industrial-ci-templates.yml
index b1c5d84ffcc3ff45a8cc0fb800e1dd7a08a84228..06d2257f79dfb7b86c45d233c83a652bd0653f6d 100644
--- a/ci-templates/industrial-ci-templates.yml
+++ b/ci-templates/industrial-ci-templates.yml
@@ -14,24 +14,56 @@
     CMAKE_ARGS: -DCMAKE_CXX_FLAGS=-Wno-ignored-attributes -Wno-int-in-bool-context
 
 
-.industrial_ci_deploy:
-  extends: .industrial_ci
+.ddeploy:
+  stage: build
   variables:
-    AFTER_SCRIPT: "wget -q -O - https://git.code.tecnalia.com/tecnalia_robotics-public/gitlab_templates/raw/master/scripts/pre-deploy-cleanup.bash | bash"
-    DOCKER_COMMIT: industrial_ci_image
+    DOCKER_BASE_REGISTRY: tecnalia-robotics-docker.artifact.tecnalia.com
+    DOCKER_BASE_USER: ${ARTIFACT_CI_USER}
+    DOCKER_BASE_TOKEN: ${ARTIFACT_CI_TOKEN}
+    DOCKER_BASE_NAME: flexbotics-base-devel
+    DOCKER_BASE_TAG: ${ROS_DISTRO}
+    DOCKER_PUSH_REGISTRY: tecnalia-robotics-docker.artifact.tecnalia.com
+    DOCKER_PUSH_USER: ${ARTIFACT_CI_USER}
+    DOCKER_PUSH_TOKEN: ${ARTIFACT_CI_TOKEN}
+    DOCKER_PUSH_NAME: ${CI_PROJECT_NAME}
+    DOCKER_PUSH_TAG: ${CI_COMMIT_REF_SLUG}
+    DDEPLOY_SOURCE: .
+    DDEPLOY_EXTRA_SOURCE: /tmp/empty.rosinstall
+    DDEPLOY_BEFORE_SCRIPT: ""
+    DDEPLOY_AFTER_SCRIPT: ""
+    DDEPLOY_CMD: "$${SHELL}"
+    DDEPLOY_EXTRA_ARGS: ""
+  before_script:
+    - docker info
+    - apk add --update python3 git py3-pip git-lfs
+    # forward the SSH authentication into the Docker executor
+    - "which ssh-agent || ( apk update && apk add openssh-client )"
+    - eval $(ssh-agent -s)
+    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
+    - mkdir -p ~/.ssh
+    - echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts
+    - chmod 700 ~/.ssh
+    # setup LFS authentication
+    - git lfs install
+    - git config --global credential.helper store
+    - echo https://$ARTIFACT_CI_USER:$ARTIFACT_CI_TOKEN@artifact.tecnalia.com > ~/.git-credentials
+    # install ddeploy
+    - oldpath=$(pwd) && cd /tmp && git clone --quiet --depth 1 git@git.code.tecnalia.com:tecnalia_robotics/flexbotics/flexbotics_utils/ddeploy.git && cd ddeploy && pip install -r requirements.txt && pip install . && cd $oldpath
+    - docker login ${DOCKER_BASE_REGISTRY} -u ${DOCKER_BASE_USER} -p ${DOCKER_BASE_TOKEN}
   script:
-    - .ci_config/gitlab.sh
-    - cd $(mktemp -d)
-    - wget https://git.code.tecnalia.com/tecnalia_robotics-public/gitlab_templates/-/archive/master/gitlab_templates-master.zip
-    - unzip gitlab_templates-master.zip && cd gitlab_templates-master/deploy
-    - cd base
-    - chmod a+x ros_entrypoint.bash
-    - docker build -t ${ARTIFACT_DOCKER_URL}/${CI_PROJECT_NAME}:${CI_COMMIT_REF_NAME} .
-    - docker push ${ARTIFACT_DOCKER_URL}/${CI_PROJECT_NAME}:${CI_COMMIT_REF_NAME}
-    - cd ..
-    - cd dev
-    - docker build --build-arg APPLICATION_IMAGE=${ARTIFACT_DOCKER_URL}/${CI_PROJECT_NAME}:${CI_COMMIT_REF_NAME} -t ${ARTIFACT_DOCKER_URL}/${CI_PROJECT_NAME}:${CI_COMMIT_REF_NAME}-dev .
-    - docker push ${ARTIFACT_DOCKER_URL}/${CI_PROJECT_NAME}:${CI_COMMIT_REF_NAME}-dev
-    - cd ..
-  rules:
-    - if: $DEPLOY
+    - echo "[]" > /tmp/empty.rosinstall
+    - ddeploy \
+      --project-sources ${DDEPLOY_SOURCE} \
+      --project-sources ${DDEPLOY_EXTRA_SOURCE} \
+      --project-name ${DOCKER_PUSH_NAME} \
+      --ros-distro ${ROS_DISTRO} \
+      --image-name ${DOCKER_PUSH_REGISTRY}/${DOCKER_PUSH_NAME}:${DOCKER_PUSH_TAG} \
+      --base-image ${DOCKER_BASE_REGISTRY}/${DOCKER_BASE_NAME}:${DOCKER_BASE_TAG} \
+      --before-script ${DDEPLOY_BEFORE_SCRIPT} \
+      --after-script ${DDEPLOY_AFTER_SCRIPT} \
+      --cmd ${DDEPLOY_CMD} \
+      ${DDEPLOY_EXTRA_ARGS}
+    - docker tag ${DOCKER_PUSH_REGISTRY}/${DOCKER_PUSH_NAME}:${DOCKER_PUSH_TAG} ${DOCKER_PUSH_REGISTRY}/${DOCKER_PUSH_NAME}:latest
+    - docker login ${DOCKER_PUSH_REGISTRY} -u ${DOCKER_PUSH_USER} -p ${DOCKER_PUSH_TOKEN}
+    - docker push ${DOCKER_PUSH_REGISTRY}/${DOCKER_PUSH_NAME}:${DOCKER_PUSH_TAG}
+    - docker push ${DOCKER_PUSH_REGISTRY}/${DOCKER_PUSH_NAME}:latest
diff --git a/deploy/base/Dockerfile b/deploy/base/Dockerfile
deleted file mode 100644
index b5cd8cbeb76c495b15c60802fa7f445519fcbd75..0000000000000000000000000000000000000000
--- a/deploy/base/Dockerfile
+++ /dev/null
@@ -1,12 +0,0 @@
-FROM industrial_ci_image
-
-RUN rm -rf /root/ici /root/src
-
-RUN apt-get update -qq && apt-get install -y -qq --no-install-recommends \
-  ros-kinetic-rosbash \
-  && rm -rf /var/lib/apt/lists/*
-
-COPY ./ros_entrypoint.bash /
-
-ENTRYPOINT ["/ros_entrypoint.bash"]
-CMD ["bash"]
diff --git a/deploy/base/ros_entrypoint.bash b/deploy/base/ros_entrypoint.bash
deleted file mode 100755
index a203d40d375b618aeb87b5e004fde27625a07ab3..0000000000000000000000000000000000000000
--- a/deploy/base/ros_entrypoint.bash
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-set -e
-
-# setup application environment
-# shellcheck disable=SC1091
-source "/root/target_ws/install/setup.bash"
-exec "$@"
diff --git a/deploy/dev/Dockerfile b/deploy/dev/Dockerfile
deleted file mode 100644
index 8d1f938b55b5ef9b06fcedeafcaed4659e98ad5f..0000000000000000000000000000000000000000
--- a/deploy/dev/Dockerfile
+++ /dev/null
@@ -1,28 +0,0 @@
-ARG APPLICATION_IMAGE
-FROM ${APPLICATION_IMAGE}
-
-RUN apt-get update -qq && apt-get install -y -qq --no-install-recommends \
-  apt-transport-https \
-  curl \
-  libasound2 \
-  ca-certificates \
-  && rm -rf /var/lib/apt/lists/*
-
-SHELL ["/bin/bash", "-o", "pipefail", "-c"]
-RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg \
-  && mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg \
-  && sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'
-
-RUN apt-get update -qq && apt-get install -y -qq --no-install-recommends \
-  code \
-  && rm -rf /var/lib/apt/lists/*
-
-RUN echo "alias code='code --user-data-dir /root'" >> /root/.bashrc
-
-RUN code --user-data-dir /root \
-  --install-extension ms-iot.vscode-ros \
-  --install-extension joaompinto.asciidoctor-vscode \
-  --install-extension ms-python.python \
-  --install-extension ms-vscode.cpptools \
-  --install-extension ms-azuretools.vscode-docker \
-  --install-extension twxs.cmake