diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..bdfa50b5b8498a9d99d711c54070bf81db238315
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,22 @@
+shellcheck:
+  image: koalaman/shellcheck-alpine
+  script: 'shellcheck deploy/base/ros_entrypoint.bash scripts/*sh'
+
+# The ignored rules in hadolint checks are
+# DL3006 Always tag the version of an image explicitly
+#   One of the Dockerfiles uses a temporary image which isn't important to tag
+#   and the other uses a tagged image through an ARG, which apparently is not
+#   properly recognized.
+# DL3008 Pin versions in apt-get install
+#   A bit overkill
+dockerfiles:
+  image: hadolint/hadolint:latest-debian
+  script:
+    - RET=0
+    - hadolint --ignore DL3006 --ignore DL3008 deploy/base/Dockerfile || RET=1
+    - hadolint --ignore DL3006 --ignore DL3008 deploy/dev/Dockerfile || RET=1
+    - exit $RET
+
+yamllint:
+  image: sdesbure/yamllint
+  script: "yamllint $(find . \\( -name '*.yml' -o -name '*.yaml' \\))"
diff --git a/.yamllint b/.yamllint
new file mode 100644
index 0000000000000000000000000000000000000000..7b7fa1b99dff7499632f7fcf7ef5e34f8f38aa6e
--- /dev/null
+++ b/.yamllint
@@ -0,0 +1,4 @@
+extends: relaxed
+
+rules:
+  line-length: disable
diff --git a/deploy/base/Dockerfile b/deploy/base/Dockerfile
index 0b06faf2efb251c156e517c6d1dcef6de1acd9ec..b5cd8cbeb76c495b15c60802fa7f445519fcbd75 100644
--- a/deploy/base/Dockerfile
+++ b/deploy/base/Dockerfile
@@ -2,7 +2,7 @@ FROM industrial_ci_image
 
 RUN rm -rf /root/ici /root/src
 
-RUN apt-get update -qq && apt-get install -y -qq \
+RUN apt-get update -qq && apt-get install -y -qq --no-install-recommends \
   ros-kinetic-rosbash \
   && rm -rf /var/lib/apt/lists/*
 
diff --git a/deploy/base/ros_entrypoint.bash b/deploy/base/ros_entrypoint.bash
index 01fe41cd7ccee5b782acc9bbc7b1a508f1e00221..0f3ec1f707f5bc2aa116e3ba44e464f20e0b06cd 100755
--- a/deploy/base/ros_entrypoint.bash
+++ b/deploy/base/ros_entrypoint.bash
@@ -2,5 +2,6 @@
 set -e
 
 # setup application environment
+# shellcheck disable=SC1091
 source "/root/catkin_ws/install/setup.bash"
 exec "$@"
diff --git a/deploy/dev/Dockerfile b/deploy/dev/Dockerfile
index 9da3d06b49e3e289e0aafbee5a5141e77326388c..75494d7d842739aeb1b3d69c5ca7f476b68e10bb 100644
--- a/deploy/dev/Dockerfile
+++ b/deploy/dev/Dockerfile
@@ -1,17 +1,20 @@
 ARG APPLICATION_IMAGE
 FROM ${APPLICATION_IMAGE}
 
-RUN apt-get update -qq && apt-get install -y -qq \
+RUN apt-get update -qq && apt-get install -y -qq --no-install-recommends \
   apt-transport-https \
   curl \
-  libasound2
+  libasound2 \
+  && 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 \
-  code
+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
 
diff --git a/rosdistro/rosdep_tecnalia.yaml b/rosdistro/rosdep_tecnalia.yaml
index 9a96e006227fd20d72bac310256f9f2518035bb5..cb40a6b791772a84c3ebf1006120e54cd956b374 100644
--- a/rosdistro/rosdep_tecnalia.yaml
+++ b/rosdistro/rosdep_tecnalia.yaml
@@ -76,10 +76,6 @@ rc_comm_utils:
   ubuntu:
     xenial: [ros-kinetic-rc-comm-utils]
 
-rc_genicam_api:
-  ubuntu:
-    xenial: [ros-kinetic-rc-genicam-api]
-
 rcimage:
   ubuntu:
     xenial: [rcimage]
@@ -112,17 +108,13 @@ rc_dynamics_api:
   ubuntu:
     xenial: [ros-kinetic-rc-dynamics-api]
 
-rc_dynamics_api:
-  ubuntu:
-    xenial: [rc-dynamics-api]
-
 rc_apps_msgs:
   ubuntu:
     xenial: [ros-kinetic-rc-apps-msgs]
 
 rc_genicam_api:
   ubuntu:
-    xenial: [rc-genicam-api]
+    xenial: [ros-kinetic-rc-genicam-api]
 
 rcobjectrendering:
   ubuntu:
diff --git a/scripts/ci_run_entry_points.sh b/scripts/ci_run_entry_points.sh
index b262dd99eb14dccf493e898afe9bc1379b858c6f..87b25d4976367fc74d9c82507b41b2eb66902dbb 100755
--- a/scripts/ci_run_entry_points.sh
+++ b/scripts/ci_run_entry_points.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 
-echo Looking up and executing user entry scripts in: $1
+echo Looking up and executing user entry scripts in: "$1"
 
-find -L $1 -name ci_entry_script.bash -exec bash -c 'echo Running entry script from $(basename $(dirname {})) ; {} ' \;
+find -L "$1" -name ci_entry_script.bash -exec bash -c 'echo Running entry script from $(basename $(dirname $1)) ; $1 ' _ {} \;
 
 echo Finalized running the user entry scripts
diff --git a/scripts/roslaunch_test_generator.sh b/scripts/roslaunch_test_generator.sh
index 8d8f8f14a34e65c2cd941d3e4e3ed500a9899371..f620745fc4d8bd4d280f589273d87e6631de3228 100644
--- a/scripts/roslaunch_test_generator.sh
+++ b/scripts/roslaunch_test_generator.sh
@@ -1,14 +1,15 @@
 #!/usr/bin/env bash
 
-for foo in $(find $(pwd) -name "package.xml") ; do
-  package_name=$(basename $(realpath $(dirname $foo)))
-  echo Entering package: $package_name
-  cd $(realpath $(dirname $foo))
-  if [[ -n $(grep -i "roslaunch_add_file_check" CMakeLists.txt) ]] ; then
-    echo Package $package_name already has roslaunch_add_file_check - skipping
+# shellcheck disable=SC2044
+for foo in $(find "$(pwd)" -name "package.xml") ; do
+  package_name=$(basename "$(realpath "$(dirname "$foo")")")
+  echo Entering package: "$package_name"
+  cd "$(realpath "$(dirname "$foo")")" || exit
+  if grep -q -i "roslaunch_add_file_check" CMakeLists.txt; then
+    echo Package "$package_name" already has roslaunch_add_file_check - skipping
   else
     if [[ -n $(find . -type f -name "*.launch") ]] ; then
-      echo Adding roslaunch_add_file_check to $package_name
+      echo Adding roslaunch_add_file_check to "$package_name"
 cat <<EOT >> CMakeLists.txt
 
 ## WARNING: automatically generated code; can be (and probably is) very buggy