diff --git a/docs/conf.py b/docs/conf.py
index 5405a343ed3fbd03f900190b84e3b53a76c6610d..c15af6744a1090516421428df765f140e6671c98 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -107,10 +107,10 @@ html_theme = "alabaster"
 
 html_theme_options = {
     "description": "Invenio module containing some customizations and configuration for TU Wien.",
-    "gitlab_user": "fairdata",
-    "gitlab_repo": "invenio-config-tuw",
-    "gitlab_button": False,
-    "gitlab_banner": True,
+    # NOTE: gitlab variables are not supported
+    # "gitlab_repo": "invenio-config-tuw",
+    # "gitlab_button": False,
+    # "gitlab_banner": True,
     "show_powered_by": False,
     "extra_nav_links": {
         "invenio-config-tuw@GitLab": "https://gitlab.tuwien.ac.at/fairdata/invenio-config-tuw",
diff --git a/run-tests.sh b/run-tests.sh
index 5e6b27fd5cac8170bd171c3a647ab565ac7f583c..fb16fa22ea2f20494b9fd803c77ff379a4c27a88 100755
--- a/run-tests.sh
+++ b/run-tests.sh
@@ -1,13 +1,50 @@
-#!/usr/bin/env sh
+#!/usr/bin/env bash
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2020-2022 TU Wien.
+# Copyright (C) 2020-2024 TU Wien.
 #
-# Invenio-Config-TUW is free software; you can redistribute it and/or modify
+# Invenio-Theme-TUW is free software; you can redistribute it and/or modify
 # it under the terms of the MIT License; see LICENSE file for more details.
 
-pydocstyle invenio_config_tuw tests docs && \
-isort -rc -c -df && \
-check-manifest --ignore ".travis-*" && \
-sphinx-build -qnNW docs docs/_build/html && \
-python setup.py test
+# Quit on errors
+set -o errexit
+
+# Quit on unbound symbols
+set -o nounset
+
+# Define function for bringing down services
+cleanup() {
+  eval "$(docker-services-cli down --env)"
+}
+
+# Check for arguments
+# Note: "-k" would clash with "pytest"
+keep_services=0
+pytest_args=()
+for arg in $@; do
+	# from the CLI args, filter out some known values and forward the rest to "pytest"
+	# note: we don't use "getopts" here b/c of some limitations (e.g. long options),
+	#       which means that we can't combine short options (e.g. "./run-tests -Kk pattern")
+	case ${arg} in
+		-K|--keep-services)
+			keep_services=1
+			;;
+		*)
+			pytest_args+=( "${arg}" )
+			;;
+	esac
+done
+
+if [[ ${keep_services} -eq 0 ]]; then
+	trap cleanup EXIT
+fi
+
+export LC_TIME=en_US.UTF-8
+python -m check_manifest
+python -m sphinx.cmd.build -qnNW docs docs/_build/html
+eval "$(docker-services-cli up --db "${DB:-postgresql}" --search "${SEARCH:-opensearch}" --mq "${MQ:-rabbitmq}" --cache "${CACHE:-redis}" --env)"
+# Note: expansion of pytest_args looks like below to not cause an unbound
+# variable error when 1) "nounset" and 2) the array is empty.
+python -m pytest ${pytest_args[@]+"${pytest_args[@]}"}
+tests_exit_code=$?
+exit "$tests_exit_code"
diff --git a/setup.cfg b/setup.cfg
index 5b9fb396bd6a0a8e9adb6ecc1dc36fee447afbe7..5537cb50029b3a8d0d8caddc4fa6e9b2486bb903 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2020-2022 TU Wien.
+# Copyright (C) 2020-2024 TU Wien.
 #
 # Invenio-Config-TUW is free software; you can redistribute it and/or modify
 # it under the terms of the MIT License; see LICENSE file for more details.
@@ -40,14 +40,8 @@ install_requires =
 
 [options.extras_require]
 tests =
-    pytest-black>=0.3.0,<0.3.10
-    check-manifest>=0.25
-    coverage>=4.0
-    isort>=4.3.3
-    pydocstyle>=2.0.0
-    pytest-cov>=2.5.1
-    pytest-pep8>=1.0.6
-    pytest-invenio>=1.2.1
+    pytest-black>=0.3.0
+    pytest-invenio>=1.4.0
     sphinx>=4.5
 elasticsearch7 =
     invenio-search[elasticsearch7]>=2.1.0,<3.0.0
@@ -127,5 +121,5 @@ ignore =
 
 [tool:pytest]
 pep8ignore = docs/conf.py ALL
-addopts = --black --pep8 --doctest-glob="*.rst" --doctest-modules --cov=invenio_config_tuw --cov-report=term-missing
+addopts = --black --isort --pydocstyle --doctest-glob="*.rst" --doctest-modules --cov=invenio_config_tuw --cov-report=term-missing
 testpaths = docs tests invenio_config_tuw