diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f19aee1c60f62492e832a470e1362a0d2be7e410..4a07e5605ee0dab31125f15a546a913f464d7c72 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,8 +1,15 @@
-image: registry.gitlab.tugraz.at/dbp/esign/signature/main:v1
+image: registry.gitlab.tugraz.at/dbp/cli/main:v1
 
 stages:
+  - test
   - deploy
 
+test-bundle:
+  stage: test
+  script:
+    - ./bin/cli show-bundle-names --vendor=myvendor --category=mycategory --unique-name=greenlight --friendly-name="Electronic Covid Access Permits" --example-entity=Permit
+    - ./bin/cli generate-bundle --vendor=myvendor --category=mycategory --unique-name=greenlight --friendly-name="Electronic Covid Access Permits" --example-entity=Permit
+
 publish:
   stage: deploy
   only:
diff --git a/.gitlab-ci/Dockerfile b/.gitlab-ci/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..fa5db15f810614cd83287d849b36fb8ea72d41db
--- /dev/null
+++ b/.gitlab-ci/Dockerfile
@@ -0,0 +1,36 @@
+FROM debian:bullseye
+
+ENV LANG C.UTF-8
+ENV DEBIAN_FRONTEND noninteractive
+
+RUN apt-get update && apt-get install -y \
+    curl \
+    && rm -rf /var/lib/apt/lists/*
+
+RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \
+    && rm -rf /var/lib/apt/lists/*
+
+# Basics
+RUN apt-get update && apt-get install -y \
+    nodejs \
+    sudo \
+    curl \
+    lsb-release \
+    git \
+    php \
+    php-curl \
+    php-soap \
+    php-xml \
+    php-ldap \
+    php-zip \
+    php-gmp \
+    php-gd \
+    php-mbstring \
+    && rm -rf /var/lib/apt/lists/*
+
+# Add a normal user and enable sudo
+RUN useradd -u 1000 -ms /bin/bash user
+RUN echo 'user ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
+USER user
+
+WORKDIR /home/user
\ No newline at end of file
diff --git a/.gitlab-ci/README.md b/.gitlab-ci/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..2c4ea8f77346c89ce806da42535851916e80476f
--- /dev/null
+++ b/.gitlab-ci/README.md
@@ -0,0 +1,4 @@
+* In case of an incompatible change increase the tag version number in build.sh
+* ./build.sh
+* (first time) sudo docker login registry.gitlab.tugraz.at
+* sudo docker push registry.gitlab.tugraz.at/dbp/cli/main:v1
diff --git a/.gitlab-ci/build.sh b/.gitlab-ci/build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1dedd36a94f91992a142c546147ec9ca98b26af5
--- /dev/null
+++ b/.gitlab-ci/build.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+TAG="registry.gitlab.tugraz.at/dbp/cli/main:v1"
+sudo docker build --tag "${TAG}" --file "Dockerfile" .
+sudo docker run --rm --security-opt label=disable \
+    --volume "$(pwd)/..:/home/user/app" --workdir "/home/user/app" \
+    --tty --interactive "${TAG}" bash
+echo "Now run: sudo docker push '$TAG'"
diff --git a/bin/bundle-generator.php b/bin/bundle-generator
similarity index 100%
rename from bin/bundle-generator.php
rename to bin/bundle-generator
diff --git a/bin/cli.sh b/bin/cli
similarity index 100%
rename from bin/cli.sh
rename to bin/cli
diff --git a/package.json b/package.json
index 602c98bf5ee477ee3805763fe45e87bb40c20724..91c616c502e412bac12b9fc5d23661ab47e109b9 100644
--- a/package.json
+++ b/package.json
@@ -4,8 +4,8 @@
   "description": "CLI to manage DBP frontend applications and Symfony bundles",
   "license": "LGPL-2.1-or-later",
   "bin": {
-    "cli": "bin/cli.sh",
-    "bundle-generator": "bin/bundle-generator.php"
+    "cli": "bin/cli",
+    "bundle-generator": "bin/bundle-generator"
   },
   "repository": {
     "type": "git",