diff --git a/.github/workflows/ci_edge_interface.yml b/.github/workflows/ci_edge_interface.yml
index a3ccf5ca..806abb54 100644
--- a/.github/workflows/ci_edge_interface.yml
+++ b/.github/workflows/ci_edge_interface.yml
@@ -9,11 +9,10 @@ on:
     paths:
       - 'edge_interface/**'
 
-env:
-  REGISTRY: ghcr.io
 
 jobs:
   lint_and_test_on_edge_interface:
+    name: Run Vue linter
     runs-on: ubuntu-latest
     steps:
       - name: Checkout repository
@@ -33,46 +32,38 @@ jobs:
         working-directory: ./edge_interface
 
   build_and_push_images:
-    name: Push Docker image to multiple registries
     needs: lint_and_test_on_edge_interface
-    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
         include:
-          - dockerfile: ./edge_interface/Dockerfile
+          - context: ./edge_interface
+            dockerfile: ./edge_interface/Dockerfile
             image: ghcr.io/${{ github.repository }}/edge_interface
-            context: ./edge_interface
-    permissions:
-      packages: write
-      contents: read
-    steps:
-      - name: Checkout repository
-        uses: actions/checkout@v3
-
-      - name: Log in to the Container registry
-        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
-        with:
-          registry: ${{ env.REGISTRY }}
-          username: ${{ github.actor }}
-          password: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Extract metadata (tags, labels) for Docker
-        id: meta
-        uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
-        with:
-          images: ${{ matrix.image }}
-          tags: |
-            type=ref,event=branch
-            type=ref,event=pr
-            type=semver,pattern={{major}}.{{minor}}.{{patch}}
-          flavor: latest=auto
+    uses: ./.github/workflows/template_build_and_push_docker_images.yml
+    with:
+      context: ${{ matrix.context }}
+      dockerfile: ${{ matrix.dockerfile }}
+      image: ${{ matrix.image }}
+    secrets:
+      username: ${{ github.actor }}
+      password: ${{ secrets.GITHUB_TOKEN }}
 
-      - name: Build and push Docker images
-        uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
-        with:
-          context: ${{ matrix.context }}
-          file: ${{ matrix.dockerfile }}
-          push: ${{ github.event_name != 'pull_request' }}
-          tags: ${{ steps.meta.outputs.tags }}
-          labels: ${{ steps.meta.outputs.labels }}
+  build_and_push_arm_images:
+    needs: lint_and_test_on_edge_interface
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - context: ./edge_interface
+            dockerfile: ./edge_interface/Dockerfile.raspberrypi
+            image: ghcr.io/${{ github.repository }}/edge_interface.raspberrypi
+    uses: ./.github/workflows/template_build_and_push_docker_images.yml
+    with:
+      context: ${{ matrix.context }}
+      dockerfile: ${{ matrix.dockerfile }}
+      image: ${{ matrix.image }}
+      arm_build: true
+    secrets:
+      username: ${{ github.actor }}
+      password: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/ci_edge_model_serving.yml b/.github/workflows/ci_edge_model_serving.yml
index 0ac0991c..3dc657da 100644
--- a/.github/workflows/ci_edge_model_serving.yml
+++ b/.github/workflows/ci_edge_model_serving.yml
@@ -9,8 +9,6 @@ on:
     paths:
       - 'edge_model_serving/**'
 
-env:
-  REGISTRY: ghcr.io
 
 jobs:
   lint_and_test_on_edge_model_serving:
@@ -49,9 +47,7 @@ jobs:
           reporter: java-junit
 
   build_and_push_images:
-    name: Build and push Docker images to multiple registries
     needs: lint_and_test_on_edge_model_serving
-    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
@@ -62,45 +58,17 @@ jobs:
           - dockerfile: ./edge_model_serving/tf_serving/Dockerfile
             image: ghcr.io/${{ github.repository }}/edge_model_serving
             context: ./edge_model_serving
-    permissions:
-      packages: write
-      contents: read
-    steps:
-      - name: Checkout repository
-        uses: actions/checkout@v3
-
-      - name: Log in to the Container registry
-        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
-        with:
-          registry: ${{ env.REGISTRY }}
-          username: ${{ github.actor }}
-          password: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Extract metadata (tags, labels) for Docker
-        id: meta
-        uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
-        with:
-          images: ${{ matrix.image }}
-          tags: |
-            type=ref,event=branch
-            type=ref,event=pr
-            type=semver,pattern={{major}}.{{minor}}.{{patch}}
-          flavor: latest=auto
-
-      - name: Build and push Docker images
-        uses: docker/build-push-action@v3
-        with:
-          context: ${{ matrix.context }}
-          file: ${{ matrix.dockerfile }}
-          push: ${{ github.event_name != 'pull_request' }}
-          tags: ${{ steps.meta.outputs.tags }}
-          labels: ${{ steps.meta.outputs.labels }}
-
+    uses: ./.github/workflows/template_build_and_push_docker_images.yml
+    with:
+      context: ${{ matrix.context }}
+      dockerfile: ${{ matrix.dockerfile }}
+      image: ${{ matrix.image }}
+    secrets:
+      username: ${{ github.actor }}
+      password: ${{ secrets.GITHUB_TOKEN }}
 
   build_and_push_arm_images:
-    name: Build and push Docker ARM images to multiple registries
     needs: lint_and_test_on_edge_model_serving
-    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
@@ -111,39 +79,12 @@ jobs:
           - dockerfile: ./edge_model_serving/tf_serving/Dockerfile.raspberrypi
             image: ghcr.io/${{ github.repository }}/edge_model_serving.raspberrypi
             context: ./edge_model_serving
-    permissions:
-      packages: write
-      contents: read
-    steps:
-      - name: Checkout repository
-        uses: actions/checkout@v3
-
-      - name: Log in to the Container registry
-        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
-        with:
-          registry: ${{ env.REGISTRY }}
-          username: ${{ github.actor }}
-          password: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Extract metadata (tags, labels) for Docker
-        id: meta
-        uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
-        with:
-          images: ${{ matrix.image }}
-          tags: |
-            type=ref,event=branch
-            type=ref,event=pr
-            type=semver,pattern={{major}}.{{minor}}.{{patch}}
-          flavor: latest=auto
-
-      - name: Set up Docker Buildx (multi-platform build)
-        uses: docker/setup-buildx-action@v2
-
-      - name: Build and push (if not PR)
-        uses: docker/build-push-action@v3
-        with:
-          context: ${{ matrix.context }}
-          file: ${{ matrix.dockerfile }}
-          push: ${{ github.event_name != 'pull_request' }}
-          tags: ${{ steps.meta.outputs.tags }}
-          labels: ${{ steps.meta.outputs.labels }}
+    uses: ./.github/workflows/template_build_and_push_docker_images.yml
+    with:
+      context: ${{ matrix.context }}
+      dockerfile: ${{ matrix.dockerfile }}
+      image: ${{ matrix.image }}
+      arm_build: true
+    secrets:
+      username: ${{ github.actor }}
+      password: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/ci_edge_orchestrator.yml b/.github/workflows/ci_edge_orchestrator.yml
index 89d2f26c..fe00ae27 100644
--- a/.github/workflows/ci_edge_orchestrator.yml
+++ b/.github/workflows/ci_edge_orchestrator.yml
@@ -9,8 +9,6 @@ on:
     paths:
       - 'edge_orchestrator/**'
 
-env:
-  REGISTRY: ghcr.io
 
 jobs:
   lint_and_test_on_edge_orchestrator:
@@ -101,9 +99,7 @@ jobs:
           reporter: java-junit
 
   build_and_push_images:
-    name: Build and push Docker images to multiple registries
     needs: lint_and_test_on_edge_orchestrator
-    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
@@ -111,45 +107,17 @@ jobs:
           - dockerfile: ./edge_orchestrator/Dockerfile
             image: ghcr.io/${{ github.repository }}/edge_orchestrator
             context: ./edge_orchestrator
-    permissions:
-      packages: write
-      contents: read
-    steps:
-      - name: Checkout repository
-        uses: actions/checkout@v3
-
-      - name: Log in to the Container registry
-        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
-        with:
-          registry: ${{ env.REGISTRY }}
-          username: ${{ github.actor }}
-          password: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Extract metadata (tags, labels) for Docker
-        id: meta
-        uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
-        with:
-          images: ${{ matrix.image }}
-          tags: |
-            type=ref,event=branch
-            type=ref,event=pr
-            type=semver,pattern={{major}}.{{minor}}.{{patch}}
-          flavor: latest=auto
-
-      - name: Build and push Docker images
-        uses: docker/build-push-action@v3
-        with:
-          context: ${{ matrix.context }}
-          file: ${{ matrix.dockerfile }}
-          push: ${{ github.event_name != 'pull_request' }}
-          tags: ${{ steps.meta.outputs.tags }}
-          labels: ${{ steps.meta.outputs.labels }}
-
+    uses: ./.github/workflows/template_build_and_push_docker_images.yml
+    with:
+      context: ${{ matrix.context }}
+      dockerfile: ${{ matrix.dockerfile }}
+      image: ${{ matrix.image }}
+    secrets:
+      username: ${{ github.actor }}
+      password: ${{ secrets.GITHUB_TOKEN }}
 
   build_and_push_arm_images:
-    name: Build and push Docker ARM images to multiple registries
     needs: lint_and_test_on_edge_orchestrator
-    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
@@ -157,39 +125,12 @@ jobs:
           - dockerfile: ./edge_orchestrator/Dockerfile.raspberrypi
             image: ghcr.io/${{ github.repository }}/edge_orchestrator.raspberrypi
             context: ./edge_orchestrator
-    permissions:
-      packages: write
-      contents: read
-    steps:
-      - name: Checkout repository
-        uses: actions/checkout@v3
-
-      - name: Log in to the Container registry
-        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
-        with:
-          registry: ${{ env.REGISTRY }}
-          username: ${{ github.actor }}
-          password: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Extract metadata (tags, labels) for Docker
-        id: meta
-        uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
-        with:
-          images: ${{ matrix.image }}
-          tags: |
-            type=ref,event=branch
-            type=ref,event=pr
-            type=semver,pattern={{major}}.{{minor}}.{{patch}}
-          flavor: latest=auto
-
-      - name: Set up Docker Buildx (multi-platform build)
-        uses: docker/setup-buildx-action@v2
-
-      - name: Build and push (if not PR)
-        uses: docker/build-push-action@v3
-        with:
-          context: ${{ matrix.context }}
-          file: ${{ matrix.dockerfile }}
-          push: ${{ github.event_name != 'pull_request' }}
-          tags: ${{ steps.meta.outputs.tags }}
-          labels: ${{ steps.meta.outputs.labels }}
+    uses: ./.github/workflows/template_build_and_push_docker_images.yml
+    with:
+      context: ${{ matrix.context }}
+      dockerfile: ${{ matrix.dockerfile }}
+      image: ${{ matrix.image }}
+      arm_build: true
+    secrets:
+      username: ${{ github.actor }}
+      password: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/publication_vio_images.yml b/.github/workflows/publication_vio_images.yml
index a1ca1d09..be989a3d 100644
--- a/.github/workflows/publication_vio_images.yml
+++ b/.github/workflows/publication_vio_images.yml
@@ -7,13 +7,9 @@ on:
       - created
   workflow_dispatch:
 
-env:
-  REGISTRY: ghcr.io
 
 jobs:
   build_and_push_images:
-    name: Push Docker image to multiple registries
-    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
@@ -30,33 +26,11 @@ jobs:
           - dockerfile: ./edge_model_serving/tflite_serving/Dockerfile
             image: ghcr.io/${{ github.repository }}/edge_tflite_serving
             context: ./edge_model_serving
-    permissions:
-      packages: write
-      contents: read
-    steps:
-      - name: Checkout repository
-        uses: actions/checkout@v3
-
-      - name: Log in to the Container registry
-        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
-        with:
-          registry: ${{ env.REGISTRY }}
-          username: ${{ github.actor }}
-          password: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Extract metadata (tags, labels) for Docker
-        id: meta
-        uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
-        with:
-          images: ${{ matrix.image }}
-          tags: type=semver,pattern={{major}}.{{minor}}.{{patch}}
-          flavor: latest=auto
-
-      - name: Build and push Docker images
-        uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
-        with:
-          context: ${{ matrix.context }}
-          file: ${{ matrix.dockerfile }}
-          push: true
-          tags: ${{ steps.meta.outputs.tags }}
-          labels: ${{ steps.meta.outputs.labels }}
+    uses: ./.github/workflows/template_build_and_push_docker_images.yml
+    with:
+      context: ${{ matrix.context }}
+      dockerfile: ${{ matrix.dockerfile }}
+      image: ${{ matrix.image }}
+    secrets:
+      username: ${{ github.actor }}
+      password: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/publication_vio_images_raspberry.yml b/.github/workflows/publication_vio_images_raspberry.yml
index 8188573b..c82a6b8e 100644
--- a/.github/workflows/publication_vio_images_raspberry.yml
+++ b/.github/workflows/publication_vio_images_raspberry.yml
@@ -7,13 +7,9 @@ on:
       - created
   workflow_dispatch:
 
-env:
-  REGISTRY: ghcr.io
 
 jobs:
   build_and_push_images:
-    name: Push Docker image to multiple registries
-    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
@@ -30,36 +26,12 @@ jobs:
           - dockerfile: ./edge_model_serving/tflite_serving/Dockerfile.raspberrypi
             image: ghcr.io/${{ github.repository }}/edge_tflite_serving.raspberrypi
             context: ./edge_model_serving
-    permissions:
-      packages: write
-      contents: read
-    steps:
-      - name: Checkout repository
-        uses: actions/checkout@v3
-
-      - name: Log in to the Container registry
-        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
-        with:
-          registry: ${{ env.REGISTRY }}
-          username: ${{ github.actor }}
-          password: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Extract metadata (tags, labels) for Docker
-        id: meta
-        uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
-        with:
-          images: ${{ matrix.image }}
-          tags: type=semver,pattern={{major}}.{{minor}}.{{patch}}
-          flavor: latest=auto
-
-      - name: Set up Docker Buildx (multi-platform build)
-        uses: docker/setup-buildx-action@v2
-
-      - name: Build and push Docker images
-        uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
-        with:
-          context: ${{ matrix.context }}
-          file: ${{ matrix.dockerfile }}
-          push: true
-          tags: ${{ steps.meta.outputs.tags }}
-          labels: ${{ steps.meta.outputs.labels }}
+    uses: ./.github/workflows/template_build_and_push_docker_images.yml
+    with:
+      context: ${{ matrix.context }}
+      dockerfile: ${{ matrix.dockerfile }}
+      image: ${{ matrix.image }}
+      arm_build: true
+    secrets:
+      username: ${{ github.actor }}
+      password: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/template_build_and_push_docker_images.yml b/.github/workflows/template_build_and_push_docker_images.yml
new file mode 100644
index 00000000..73429f41
--- /dev/null
+++ b/.github/workflows/template_build_and_push_docker_images.yml
@@ -0,0 +1,68 @@
+on:
+  workflow_call:
+    inputs:
+      context:
+        required: true
+        type: string
+      dockerfile:
+        required: true
+        type: string
+      image:
+        required: true
+        type: string
+      arm_build:
+        required: false
+        type: boolean
+        default: false
+    secrets:
+      username:
+        required: true
+      password:
+        required: true
+
+
+env:
+  REGISTRY: ghcr.io
+
+
+jobs:
+  build_and_push_images:
+    name: Build and push Docker images to multiple registries
+    runs-on: ubuntu-latest
+    permissions:
+      packages: write
+      contents: read
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v3
+
+      - name: Log in to the Container registry
+        uses: docker/login-action@v2.1.0
+        with:
+          registry: ${{ env.REGISTRY }}
+          username: ${{ secrets.username }}
+          password: ${{ secrets.password }}
+
+      - name: Extract metadata (tags, labels) for Docker
+        id: meta
+        uses: docker/metadata-action@v4
+        with:
+          images: ${{ inputs.image }}
+          tags: |
+            type=ref,event=branch
+            type=ref,event=pr
+            type=semver,pattern={{major}}.{{minor}}.{{patch}}
+          flavor: latest=auto
+
+      - name: Set up Docker Buildx (multi-platform build)
+        uses: docker/setup-buildx-action@v2
+        if: ${{ inputs.arm_build }}
+
+      - name: Build and push Docker images
+        uses: docker/build-push-action@v4
+        with:
+          context: ${{ inputs.context }}
+          file: ${{ inputs.dockerfile }}
+          push: ${{ github.event_name != 'pull_request' }}
+          tags: ${{ steps.meta.outputs.tags }}
+          labels: ${{ steps.meta.outputs.labels }}