diff --git a/testserver/docker_uffd/templates/Dockerfile b/testserver/docker_uffd/templates/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..36bcfcdf9da7cbc35a60ac5829af5ff540e3dad1
--- /dev/null
+++ b/testserver/docker_uffd/templates/Dockerfile
@@ -0,0 +1,77 @@
+FROM debian:bookworm AS build-stage
+
+ENV DEBIAN_FRONTEND=noninteractive
+ENV PYBUILD_INSTALL_ARGS="--install-lib=/usr/share/uffd/ --install-scripts=/usr/share/uffd/"
+ENV PACKAGE_VERSION=v2.3.1.r21
+
+RUN set -x && \
+    apt update && \
+    apt install -y --no-install-recommends \
+        lsb-release \
+        curl \
+        ca-certificates \
+        locales-all \
+        git \
+        python3 \
+        python3-venv \
+        python3-coverage \
+        python3-ldap3 \
+        python3-flask \
+        python3-flask-sqlalchemy \
+        python3-flask-migrate \
+        python3-pip \
+        python3-qrcode \
+        python3-fido2 \
+        python3-oauthlib \
+        python3-flask-babel \
+        python3-argon2 \
+        python3-pytest \
+        python3-all \
+        python3-pip \
+        git-buildpackage \
+        debhelper \
+        build-essential \
+        dh-python \
+        python3-mysqldb \
+        python3-requests-oauthlib \
+        python3-git \
+        python3-prometheus-client \
+        libffi-dev \
+        python3-build \
+        twine && \
+    apt -qq clean
+
+RUN git clone https://git.cccv.de/uffd/uffd.git
+WORKDIR /uffd
+RUN git checkout 3f41d2fb7f686c12a1f09577e5b96da89ff46e07
+
+RUN set -x && \
+    ./debian/create_changelog.py uffd > debian/changelog && \
+    dpkg-buildpackage -us -uc && \
+    dpkg-deb -I /*.deb && \
+    dpkg-deb -c /*.deb && \
+    mv /*.deb /uffd/uffd.deb
+
+FROM debian:bookworm as app-stage
+
+COPY --from=build-stage /uffd/uffd.deb /uffd.deb
+
+RUN set -x && \
+    apt update && \
+    apt install -y --no-install-recommends /uffd.deb python3-psycopg2 python3-pymysql && \
+    rm -rf /var/lib/apt/lists/* && \
+    rm /uffd.deb && \
+    cat /etc/uffd/uffd.cfg | grep -v "SECRET_KEY=" > /etc/uffd/uffd.cfg.tmp && \
+    mv /etc/uffd/uffd.cfg.tmp /etc/uffd/uffd.cfg && \
+    mkdir --parents /var/www/uffd && \
+    chown root:uffd /var/www/uffd
+
+COPY entrypoint.sh /entrypoint.sh
+
+USER uffd
+USER root
+
+EXPOSE 3031/tcp
+EXPOSE 9191/tcp
+
+CMD bash /entrypoint.sh
diff --git a/testserver/docker_uffd/templates/docker-compose.yml b/testserver/docker_uffd/templates/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..85d4f46c81e063ebe03d3750fdadc05f8114dce3
--- /dev/null
+++ b/testserver/docker_uffd/templates/docker-compose.yml
@@ -0,0 +1,41 @@
+version: "3"
+
+services:
+  db:
+    image: mariadb:11.2.2
+    restart: always
+    command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_nopad_bin']
+    volumes:
+      - "{{ basedir }}/db/:/var/lib/mysql"
+    environment:
+      MYSQL_ROOT_PASSWORD: "{{ mysql_admin_pass }}"
+      MYSQL_PASSWORD: "{{ mysql_user_pass }}"
+      MYSQL_DATABASE: "uffd"
+      MYSQL_USER: "uffd"
+    networks:
+        - default
+  app:
+    build: .
+    image: uffd:v2.3.1.r21
+    restart: always
+    depends_on:
+      - db
+    volumes:
+      - "{{ basedir }}/uffd.cfg/:/etc/uffd/uffd.cfg"
+    environment:
+      TZ: "Europe/Berlin"
+      UFFD_INITIAL_ADMIN_USER: "uffdadmin"
+      UFFD_INITIAL_ADMIN_PW: "{{ uffd_admin_pass }}"
+      UFFD_INITIAL_ADMIN_MAIL: "uffdadmin@jabertwo.de"
+    labels:
+      - traefik.enable=true
+      - traefik.http.routers.{{ servicename }}.rule=Host(`{{ domain }}`)
+      - traefik.http.routers.{{ servicename }}.entrypoints=websecure
+      - traefik.http.services.{{ servicename }}.loadbalancer.server.port=3031
+    networks:
+        - default
+        - web
+
+networks:
+  web:
+    external: true
diff --git a/testserver/docker_uffd/templates/entrypoint.sh b/testserver/docker_uffd/templates/entrypoint.sh
new file mode 100644
index 0000000000000000000000000000000000000000..81e92a9a3dfe9dc88c6bf999678b0a48bb37b26f
--- /dev/null
+++ b/testserver/docker_uffd/templates/entrypoint.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+# Modded to Dockerfile
+#echo "Copying static files ..."
+#cp -r /usr/share/uffd/uffd/static /var/www/uffd
+
+db_ready="false"
+count=0
+while [ $count -lt 32 ] && [ "$db_ready" != "true" ] ;do
+  if uffd-admin db current >> /dev/null 2>&1 ;then
+    db_ready="true"
+  else
+    echo "Waiting for db to become ready..."
+    ((duration=2**$count))
+    sleep $duration
+    ((count=$count+1))
+  fi
+done
+
+if [ "$db_ready" == "true" ] ;then
+  echo "Running datbase migrations ..."
+  uffd-admin db upgrade
+
+  if [ -n "$UFFD_INITIAL_ADMIN_PW" ] && [ "$(uffd-admin user list)" == "" ]; then
+    echo "Creating groups and roles for initial admin user ..."
+    if ! uffd-admin group show 'uffd_admin' >> /dev/null 2>&1 ;then
+      uffd-admin group create 'uffd_admin' --description 'Admin access to uffd'
+    fi
+    if ! uffd-admin group show 'uffd_access' >> /dev/null 2>&1 ;then
+      uffd-admin group create 'uffd_access' --description 'Access to Single-Sign-On and Selfservice'
+    fi
+    if ! uffd-admin role show 'uffd_admin' >> /dev/null 2>&1 ;then
+      uffd-admin role create 'uffd_admin' --add-group 'uffd_admin' --add-group 'uffd_access'
+    fi
+    if [ -z "$UFFD_INITIAL_ADMIN_USER" ] ;then
+      UFFD_INITIAL_ADMIN_USER='uffd_admin'
+    fi
+    if [ -z "$UFFD_INITIAL_ADMIN_MAIL" ] ;then
+      UFFD_INITIAL_ADMIN_MAIL='uffd_admin@localhost'
+    fi
+    echo "Creating initial admin user ..."
+    uffd-admin user create "$UFFD_INITIAL_ADMIN_USER" --password "$UFFD_INITIAL_ADMIN_PW" --mail "$UFFD_INITIAL_ADMIN_MAIL" --displayname 'uffd Admin' --add-role 'uffd_admin'
+  fi
+else
+  echo "WARNING: Database is not ready yet, skipping migration and initialization"
+fi
+
+echo "Starting server ..."
+runuser --preserve-environment -u uffd -- \
+  uwsgi --ini /etc/uwsgi/apps-enabled/uffd.ini --http-socket 0.0.0.0:3031 --master --stats 0.0.0.0:9191
diff --git a/testserver/docker_uffd/templates/uffd.cfg b/testserver/docker_uffd/templates/uffd.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..6de25a93f469c5b409298f14cac77d15e4f84b8f
--- /dev/null
+++ b/testserver/docker_uffd/templates/uffd.cfg
@@ -0,0 +1,123 @@
+
+LANGUAGES={
+	# Language identifier (see Accept-Language HTTP header) -> Display Name
+	"en": "EN",
+	"de": "DE",
+}
+
+# Uffd Admins Group
+ACL_ADMIN_GROUP="uffd_admin"
+# Group required to access selfservice functions (view selfservice, change profile/password/roles)
+ACL_SELFSERVICE_GROUP="uffd_access"
+# Group required to login
+ACL_ACCESS_GROUP="uffd_access"
+# Members can create invite links for signup
+ACL_SIGNUP_GROUP="uffd_signup"
+
+MAIL_SERVER='mail.test-warpzone.de' 
+MAIL_PORT=587
+MAIL_USERNAME='noreply-uffd@test-warpzone.de' 
+MAIL_PASSWORD='{{ uffd_mail_pass }}'
+MAIL_USE_STARTTLS=True
+MAIL_FROM_ADDRESS='noreply-uffd@test-warpzone.de'
+
+# Do not enable this on a public service! There is no spam protection implemented at the moment.
+SELF_SIGNUP=False
+
+# Max Lifetime for invites
+INVITE_MAX_VALID_DAYS=21
+
+# Blocked Loginnames
+LOGINNAME_BLOCKLIST=['^admin$', '^root$']
+
+#MFA_ICON_URL = 'https://example.com/logo.png'
+#MFA_RP_ID = 'example.com' # If unset, hostname from current request is used
+MFA_RP_NAME = 'Uffd Test Service' # Service name passed to U2F/FIDO2 authenticators
+
+
+FOOTER_LINKS=[{"url": "https://example.com", "title": "example"}]
+
+# The default page after login or clicking the top left home button is the self-service
+# page. If you would like it to be the services list instead, set this to True.
+DEFAULT_PAGE_SERVICES=True
+
+# Service overview page (disabled if empty)
+SERVICES=[
+#	# Title is mandatory, all other fields are optional.
+#	# For permission_levels/groups/infos/links all fields are mandatory aside from required_group.
+#	{
+#		'title': 'Service Title',
+#		'subtitle': 'Service Subtitle',
+#		'description': 'Short description of the service as plain text',
+#		'url': 'https://example.com/',
+#		'logo_url': 'https://example.com/logo.png',
+#		# Basic access group name, service is accessible to everyone if empty
+#		'required_group': 'users',
+#		# Non-basic permission levels, the last matching entry is selected.
+#		# Users with a matching permission level are considered to have
+#		# access to the service (as if they have the basic access group).
+#		'permission_levels': [
+#			{'name': 'Moderator', 'required_group': 'moderators'},
+#			{'name': 'Admin', 'required_group': 'uffd_admin'},
+#		],
+#		# Per default all services are listed publicly (but grayed out for
+#		# guests/users without access). Confidential services are only visible
+#		# to users with access rights to the service.
+#		'confidential': True,
+#		# In-service groups, all matching items are visible
+#		'groups': [
+#			{'name': 'Group "crew_crew"', 'required_group': 'users'},
+#			{'name': 'Group "crew_logistik"', 'required_group': 'uffd_admin'},
+#		],
+#		# Infos are small/medium amounts of information displayed in a modal
+#		# dialog. All matching items are visible.
+#		'infos': [
+#			{
+#				'title': 'uffd',
+#				'button_text': 'Documentation', # Defaults to the title if not set
+#				'html': '<p>Some information about the service as html</p>',
+#				'required_group': 'users',
+#			},
+#		],
+#		# Links to external sites, all matching items are visible
+#		'links': [
+#			{'title': 'Link to an external site', 'url': '#', 'required_group': 'users'},
+#		]
+#	},
+
+    {
+		'title': 'Icinga',
+		'url': 'https://icinga.test-warpzone.de',
+		'logo_url': 'https://icinga.test-warpzone.de/icingaweb2/img/favicon.png'
+    }
+
+]
+
+# A banner text that will be displayed above the services list
+SERVICES_BANNER='Available Services'
+
+# If the banner should be shown to users who are not logged in
+SERVICES_BANNER_PUBLIC=False
+
+# Enable the service overview page for users who are not logged in
+SERVICES_PUBLIC=False
+
+# An optional banner that will be displayed above the login form
+LOGIN_BANNER='Always check the URL. Never enter your SSO password on any other site.'
+
+BRANDING_LOGO_URL='/static/empty.png'
+SITE_TITLE='uffd @ test-warpzone.de'
+
+# Name and contact mail address are displayed to users in a few places (plain text only!)
+ORGANISATION_NAME='test-warpzone.de'
+ORGANISATION_CONTACT='uffd@test-warpzone.de'
+
+# Optional text included in account registration mails (plain text only!)
+WELCOME_TEXT='See https://docs.example.com/ for further information.'
+
+
+# DO set in production
+FLASK_ENV="production"
+SQLALCHEMY_DATABASE_URI="mysql+pymysql://uffd:{{ mysql_user_pass }}@db/uffd?charset=utf8mb4"
+SECRET_KEY="{{ uffd_secret_key }}"
+DEBUG=False