diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 74f009c9d234ce68627f5f7f6043d3b993ac249f..9f20e5a234077471feb8aada7442a9a013fbdfd2 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -19,17 +19,72 @@ variables:
 services:
   - docker:dind
 
+stages:
+  - base
+  - first
+  - second
+
 before_script:
   - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
   - docker info
 
-build:
-  stage: build
+.build:
   tags:
     - dind
   script:
-    - docker pull $CI_REGISTRY_IMAGE/fsmpi-base:latest || true
-    - docker build --cache-from $CI_REGISTRY_IMAGE/fsmpi-base:latest --tag $CI_REGISTRY_IMAGE/fsmpi-base:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE/fsmpi-base:stretch --tag $CI_REGISTRY_IMAGE/fsmpi-base:latest fsmpi-base
-    - docker push $CI_REGISTRY_IMAGE/fsmpi-base:$CI_COMMIT_SHA
-    - docker push $CI_REGISTRY_IMAGE/fsmpi-base:stretch
-    - docker push $CI_REGISTRY_IMAGE/fsmpi-base:latest
+    - docker pull $CI_REGISTRY_IMAGE/$IMAGE_NAME:$DEBIAN_RELEASE || true
+    - docker build --cache-from $CI_REGISTRY_IMAGE/$IMAGE_NAME:$DEBIAN_RELEASE --build-arg DEBIAN_RELEASE=$DEBIAN_RELEASE --tag $CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE/$IMAGE_NAME:$DEBIAN_RELEASE $IMAGE_NAME
+    - docker push $CI_REGISTRY_IMAGE/$IMAGE_NAME:$DEBIAN_RELEASE-$CI_COMMIT_SHA
+    - docker push $CI_REGISTRY_IMAGE/$IMAGE_NAME:$DEBIAN_RELEASE
+
+.build-stretch:
+  extends: .build
+  variables:
+    DEBIAN_RELEASE: stretch
+
+.build-buster:
+  extends: .build
+  variables:
+    DEBIAN_RELEASE: buster
+
+base-stretch:
+  extends: .build-stretch
+  stage: base
+  variables:
+    IMAGE_NAME: fsmpi-base
+
+base-buster:
+  extends: .build-buster
+  stage: base
+  variables:
+    IMAGE_NAME: fsmpi-base
+
+packages-stretch:
+  extends: .build-stretch
+  stage: first
+  variables:
+    IMAGE_NAME: fsmpi-packages
+
+packages-buster:
+  extends: .build-buster
+  stage: first
+  variables:
+    IMAGE_NAME: fsmpi-packages
+
+python-stretch:
+  extends: .build-stretch
+  stage: first
+  variables:
+    IMAGE_NAME: fsmpi-python
+
+python-buster:
+  extends: .build-buster
+  stage: first
+  variables:
+    IMAGE_NAME: fsmpi-python
+
+ansible-buster:
+  extends: .build-buster
+  stage: second
+  variables:
+    IMAGE_NAME: fsmpi-ansible
diff --git a/fsmpi-ansible/Dockerfile b/fsmpi-ansible/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..053d3626f26dd90aa4ad01f10ad6505992e9ca3f
--- /dev/null
+++ b/fsmpi-ansible/Dockerfile
@@ -0,0 +1,3 @@
+ARG DEBIAN_RELEASE=buster
+FROM fsmpi-python:buster
+RUN apt-get update && apt-get install -y python3-cffi python3-ply ansible yamllint && rm -rf /var/lib/apt/lists/*
diff --git a/fsmpi-base/Dockerfile b/fsmpi-base/Dockerfile
index 54221da3b4200dbf69d68eab7507b42cef74784b..6a14a754692d74d2319ab639daa0f6eac87d4af4 100644
--- a/fsmpi-base/Dockerfile
+++ b/fsmpi-base/Dockerfile
@@ -1,4 +1,5 @@
-FROM debian:stretch
+ARG DEBIAN_RELEASE=stretch
+FROM debian:${DEBIAN_RELEASE}
 ENV LANG C.UTF-8
 RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/* \
     && for lang in en_US de_DE; do localedef -i $lang -c -f UTF-8 -A /usr/share/locale/locale.alias $lang.UTF-8; done
diff --git a/fsmpi-packages/Dockerfile b/fsmpi-packages/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..d3040698a03d6709e69994883d00906d3e6cefe4
--- /dev/null
+++ b/fsmpi-packages/Dockerfile
@@ -0,0 +1,3 @@
+ARG DEBIAN_RELEASE=stretch
+FROM fsmpi-base:${DEBIAN_RELEASE}
+RUN apt-get update && apt-get install -y build-essential dpkg-dev quilt devscripts git curl && rm -rf /var/lib/apt/lists/*
diff --git a/fsmpi-python/Dockerfile b/fsmpi-python/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..f293f64ac4b133d4318ed393837a564f290e664e
--- /dev/null
+++ b/fsmpi-python/Dockerfile
@@ -0,0 +1,3 @@
+ARG DEBIAN_RELEASE=stretch
+FROM fsmpi-base:${DEBIAN_RELEASE}
+RUN apt-get update && apt-get install -y python3 python3-pip python3-venv flake8 curl && rm -rf /var/lib/apt/lists/*