diff --git a/dockerfiles/devenv.Dockerfile b/dockerfiles/devenv.Dockerfile
index 3c6068e18e68216e1d647cd681f8f6408d04a0ba..0ba4e4e575da6545620733ded123dbae966cd742 100644
--- a/dockerfiles/devenv.Dockerfile
+++ b/dockerfiles/devenv.Dockerfile
@@ -7,6 +7,11 @@ RUN echo "Building devenv for ROS" $ROS_DISTRO "with shell" $EXT_SHELL
 # Avoid warnings by switching to noninteractive
 ENV DEBIAN_FRONTEND=noninteractive
 
+# Import the key in order to be able to use the packages from the repository
+# RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 7E72C5B4111A50084C63C9489E7A9B1D990CF897
+# NOV - 2023
+RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 4B63CF8FDE49746E98FA01DDAD19BAB3CBF125EA
+
 # Setup environment
 RUN apt-get update && apt-get install -y apt-utils
 
@@ -68,9 +73,6 @@ RUN if [ "$EXT_SHELL" = "zsh" ]; \
 
 # Configure system to look for debian packages in the Artifactory repository
 COPY auth.conf /etc/apt/auth.conf.d/tecnalia.conf
-
-# Import the key in order to be able to use the packages from the repository
-RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 7E72C5B4111A50084C63C9489E7A9B1D990CF897
 RUN curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | apt-key add -
 
 # Configure rosdep
diff --git a/dotfiles/docker.sh b/dotfiles/docker.sh
index ba018846c924291b58785efccc76215d6c7dee34..21fa0c17ab9ba920e9d3d532ae296e742158d7a8 100644
--- a/dotfiles/docker.sh
+++ b/dotfiles/docker.sh
@@ -1,10 +1,3 @@
-# Define color codes
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
-BLUE='\033[0;34m'
-NC='\033[0m' # No Color
-
 # docker common commands
 export dockerfiles_path=~/srcs/development_environment/dockerfiles;
 
@@ -25,8 +18,7 @@ else
     ext=$(basename ${SHELL});
 fi
 
-# Build docker image
-# usage: dockbuild {noetic, melodic}
+# Build a docker image
 function dockbuild(){
     current_dir=$(pwd)
 
@@ -105,6 +97,7 @@ function dockrun() {
         case $key in
             --ws)
                 workspace="${HOME}/ros/${container_name}/$3"
+                export ROS_WORKSPACE=$workspace
                 shift
                 shift
                 ;;
@@ -222,7 +215,7 @@ function dockexec() {
         echo "shell: ${docker_shell}${NC}"
         # Attach to container
         echo "${GREEN}docker exec -it ${container_name} ${docker_shell}${NC}"
-        docker exec -it ${container_name} ${docker_shell}
+        docker exec -it ${container_name} ${docker_shell} -c "sc"
     else
         # Launch container
         echo "${RED}Container ${1} does not exist${NC}"
diff --git a/dotfiles/ros.sh b/dotfiles/ros.sh
index b1797749f1a1a92543d565d73e0223b6e3683c44..78dee100862083e70974c98e1c0c81e328f4f5c1 100644
--- a/dotfiles/ros.sh
+++ b/dotfiles/ros.sh
@@ -2,84 +2,106 @@
 # ROS aliases and functions
 ###################################################################
 
-# Define ROS_DISTRO before source ROS on native OS
-# if [ -z $ROS_DISTRO ]; then export ROS_DISTRO=noetic; fi
-if [[ -z "${ROS_DISTRO}" ]]; then
-    ROS_DIR=/opt/ros
-    if [ -d "$ROS_DIR" ];
-    then
-        export ROS_DISTRO=$(basename $(find /opt/ros/* -maxdepth 0 -type d | head -1))
-    else
-        unset ROS_DISTRO
-    fi
+if [[ "${ROS_DISTRO}" == "noetic" || "${ROS_DISTRO}" == "melodic" ]]; then
+    export ROS_VERSION=1
+else
+    export ROS_VERSION=2
 fi
 
-# Determine shell extension
-if [ ! -z $EXT_SHELL ]; then
-    if [ -z $SHELL ]; then
-        echo "SHELL not set"
-        export SHELL=/usr/bin/zsh
-        ext=$(basename ${SHELL});
-    else
-        ext=$(basename ${SHELL});
+# Enable colcon tools
+if [[ "${ROS_VERSION}" = 2 ]]; then
+    # Quick directory change
+    if [[ -f "/usr/share/colcon_cd/function/colcon_cd.sh" ]]; then
+        source /usr/share/colcon_cd/function/colcon_cd.sh
+    fi
+    # Completion
+    if [[ -f "/usr/share/colcon_argcomplete/hook/colcon-argcomplete.${ext}" ]]; then
+        source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.${ext}
     fi
 fi
 
 # Source rosmon
 function smon(){
-    if [[ -f "/opt/ros/${ROS_DISTRO}/etc/catkin/profile.d/50-rosmon.${ext}" ]]; then
-        source /opt/ros/${ROS_DISTRO}/etc/catkin/profile.d/50-rosmon.${ext}
+    if [[ ${ROS_VERSION} = 1 ]]; then
+        if [[ -f "/opt/ros/${ROS_DISTRO}/etc/catkin/profile.d/50-rosmon.${ext}" ]]; then
+            source /opt/ros/${ROS_DISTRO}/etc/catkin/profile.d/50-rosmon.${ext}
+        else
+            echo "rosmon not found."
+        fi
     fi
 }
 
 # cd to the root of the workspace
 function roshome(){
-    if command -v roscd &> /dev/null
+    if [ "${ROS_VERSION}" = 1 ]
     then
-        roscd && cd ..
-        ROS_HOME=${PWD}
+        if command -v roscd &> /dev/null
+        then
+            roscd && cd ..
+            export ROS_HOME=$(pwd)
+        else
+            echo "command ** roscd ** not found"
+        fi
     else
-        echo "command ** roscd ** not found"
+        if command -v colcon_cd &> /dev/null
+        then
+            colcon_cd
+        else
+            echo "command ** colcon_cd ** not found"
+        fi
     fi
 }
 
 # Source the current workspace
 function sourcews(){
+    current_dir=$(pwd)
+    cropped=${PWD#${HOME}/ros/${ROS_DISTRO}/}
+    ws_name=${cropped%%/*}
+    ws_path=${HOME}/ros/${ROS_DISTRO}/${ws_name}
+
     if [ "${ROS_VERSION}" = 1 ]
     then
-        source ./devel/setup.${ext} && smon
+        FILE=${ws_path}/devel/setup.${ext}
     else
-        source ./install/setup.${ext}
+        FILE=${ws_path}/install/setup.${ext}
     fi
-}
 
-# Source the current workspace
-function sourceros(){
-    source /opt/ros/${ROS_DISTRO}/setup.${ext} && smon
-    ROS_HOME="/opt/ros/${ROS_DISTRO}/"
+    # if PWD belongs to ROS workspace then source it
+    if [[ -f $FILE ]]; then
+        cd ${ws_path}
+        echo "${GREEN}Sourcing workspace: ${FILE}${NC}"
+        source $FILE && smon
+        cd ${current_dir}
+        export ROS_HOME=${ws_path}
+    else
+        echo "${RED}Workspace not found: ${FILE}${NC}"
+    fi
 }
 
 # Source the current workspace
-function sourcethis(){
-    pwd_st=${PWD}
-    roshome && sourcews
-    echo "Sourcing: ${ROS_HOME}"
-    cd ${pwd_st}
+function sourceros(){
+    source /opt/ros/${ROS_DISTRO}/setup.${ext}
+    export ROS_HOME="/opt/ros/${ROS_DISTRO}/"
+    # In ROS 1 source rosmon
+    if [ "${ROS_VERSION}" = 1 ]
+    then
+        smon
+    fi
 }
 
 # Automatic catkin build
 function cb() {
+    pwd_cb=$(pwd)
     if [ "${ROS_VERSION}" = 1 ]
     then
-        pwd_cb=${PWD}
         roshome
         catkin build --summarize --cmake-args -DCMAKE_BUILD_TYPE=Release -- "$@"
-        sourcethis
-        cd ${pwd_cb}
     else
         colcon build --parallel-workers 6 "$@"
-        source ./install/setup.zsh
     fi
+
+    sourcews
+    cd ${pwd_cb}
 }
 
 # Clean workspace (delete the generated folders, then catkin build)
@@ -109,23 +131,19 @@ function runci(){
     fi
 }
 
-# if a new terminal starts in a ws, auto source it (useful for vscode)
-if [ -z ${ROS_DISTRO+x} ]; then ;
-else
-    pwd_init=${PWD}
-    cropped=${PWD#${HOME}/ros/${ROS_DISTRO}/}
-    WS_name=${cropped%%/*}
-    WS_path=${HOME}/ros/${ROS_DISTRO}/${WS_name}
-    FILE=${WS_path}/devel/setup.${ext}
-    # if PWD belongs to ROS ws then source it
-    if [[ -f $FILE ]]; then
-        cd ${WS_path}
-        source $FILE
-        cd ${pwd_init}
-        ROS_HOME=${WS_path}
+alias sc=sourcews
+
+# Check if ROS_DISTRO is set.
+if [[ -z "${ROS_DISTRO}" ]]; then
+    ROS_DIR=/opt/ros
+    if [ -d "$ROS_DIR" ];
+    then
+        export ROS_DISTRO=$(basename $(find /opt/ros/* -maxdepth 0 -type d | head -1))
+        #echo "ROS_DISTRO set to ${ROS_DISTRO}"
     else
-        sourceros
+        unset ROS_DISTRO
+        #echo "${YELLOW}ROS is not installed.${NC}"
     fi
-fi
-
-#alias sc=sourcethis
\ No newline at end of file
+else
+    sourcews
+fi
\ No newline at end of file
diff --git a/dotfiles/system.sh b/dotfiles/system.sh
index 9f15e630ad285ca69260f49174635655bad90af0..2d38f989a407cdb56c1836898ed6d2916c50b174 100644
--- a/dotfiles/system.sh
+++ b/dotfiles/system.sh
@@ -1,3 +1,10 @@
+# Define color codes
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
 # Override globalalias config
 # space expands all aliases, including global
 bindkey -M emacs "^ " globalias