diff --git a/core/Dockerfile b/core/Dockerfile
index 82f58fd..431f0a1 100644
--- a/core/Dockerfile
+++ b/core/Dockerfile
@@ -24,7 +24,9 @@ ENV \
     KOPANO_CORE_REPOSITORY_URL=$KOPANO_CORE_REPOSITORY_URL \
     KOPANO_CORE_VERSION=$KOPANO_CORE_VERSION \
     KOPANO_REPOSITORY_FLAGS=$KOPANO_REPOSITORY_FLAGS \
-    RELEASE_KEY_DOWNLOAD=$RELEASE_KEY_DOWNLOAD
+    LANG=en_US.UTF-8 \
+    RELEASE_KEY_DOWNLOAD=$RELEASE_KEY_DOWNLOAD \
+    SERVICE_TO_START=server
 
 LABEL maintainer=az@zok.xyz \
     org.label-schema.name="Kopano Groupware Core container" \
@@ -66,10 +68,6 @@ RUN \
     (cp /usr/share/doc/kopano/example-config/*.cfg.gz /etc/kopano/ || true) && \
     (gzip -d -f /etc/kopano/*.gz || true)
 
-ENV LANG=en_US.UTF-8
-
-ENV SERVICE_TO_START=server
-
 COPY defaultconfigs/ start-service.sh healthcheck.sh /kopano/
 COPY bin/ /usr/local/bin/
 COPY goss/ /kopano/goss
diff --git a/core/start-service.sh b/core/start-service.sh
index 93d9249..fb6ace5 100755
--- a/core/start-service.sh
+++ b/core/start-service.sh
@@ -74,21 +74,36 @@ fi
 # put specified socket into KOPANO_CON variable to ease checks further down
 case "$SERVICE_TO_START" in
 dagent)
+	EXE="${EXE:-$(command -v kopano-dagent)}"
 	KOPANO_CON="$KCCONF_DAGENT_SERVER_SOCKET"
 	;;
 gateway)
+	EXE="${EXE:-$(command -v kopano-gateway)}"
 	KOPANO_CON="$KCCONF_GATEWAY_SERVER_SOCKET"
 	;;
+grapi)
+	EXE="${EXE:-$(command -v kopano-grapi)}"
+	;;
 ical)
+	EXE="${EXE:-$(command -v kopano-ical)}"
 	KOPANO_CON="$KCCONF_ICAL_SERVER_SOCKET"
 	;;
+kapi)
+	EXE="${EXE:-$(command -v kopano-kapid)}"
+	;;
 monitor)
+	EXE="${EXE:-$(command -v kopano-monitor)}"
 	KOPANO_CON="$KCCONF_MONITOR_SERVER_SOCKET"
 	;;
 search)
+	EXE="${EXE:-$(command -v kopano-search)}"
 	KOPANO_CON="$KCCONF_SEARCH_SERVER_SOCKET"
 	;;
+server)
+	EXE="${EXE:-$(command -v kopano-server)}"
+	;;
 spooler)
+	EXE="${EXE:-$(command -v kopano-spooler)}"
 	KOPANO_CON="$KCCONF_SPOOLER_SERVER_SOCKET"
 	;;
 esac
@@ -123,7 +138,7 @@ server)
 	fi
 	# cleaning up env variables
 	unset "${!KCCONF_@}"
-	exec /usr/sbin/kopano-server -F
+	exec "$EXE" -F
 	;;
 dagent)
 	dockerize \
@@ -131,7 +146,7 @@ dagent)
 		-timeout 360s
 	# cleaning up env variables
 	unset "${!KCCONF_@}"
-	exec /usr/sbin/kopano-dagent -l
+	exec "$EXE" -l
 	;;
 gateway)
 	dockerize \
@@ -139,7 +154,7 @@ gateway)
 		-timeout 360s
 	# cleaning up env variables
 	unset "${!KCCONF_@}"
-	exec /usr/sbin/kopano-gateway -F
+	exec "$EXE" -F
 	;;
 ical)
 	dockerize \
@@ -147,7 +162,7 @@ ical)
 		-timeout 360s
 	# cleaning up env variables
 	unset "${!KCCONF_@}"
-	exec /usr/sbin/kopano-ical -F
+	exec "$EXE" -F
 	;;
 grapi)
 	LC_CTYPE=en_US.UTF-8
@@ -177,9 +192,9 @@ grapi)
 	grapiversion=$(dpkg-query --showformat='${Version}' --show kopano-grapi)
 	echo "Using Kopano Grapi: $grapiversion"
 	if dpkg --compare-versions "$grapiversion" "gt" "10.0.0"; then
-		exec kopano-grapi serve --backend="$GRAPI_BACKEND"
+		exec "$EXE" serve --backend="$GRAPI_BACKEND"
 	else
-		exec kopano-grapi serve
+		exec "$EXE" serve
 	fi
 	;;
 kapi)
@@ -200,10 +215,10 @@ kapi)
 	sed s/\ *=\ */=/g /tmp/kopano/kapid.cfg > /tmp/kapid-env
 	# shellcheck disable=SC2046
 	export $(grep -v '^#' /tmp/kapid-env | xargs -d '\n')
-	kopano-kapid setup
+	"$EXE" setup
 	# cleaning up env variables
 	unset "${!KCCONF_@}"
-	exec kopano-kapid serve --log-timestamp=false
+	exec "$EXE" serve --log-timestamp=false
 	;;
 monitor)
 	dockerize \
@@ -211,7 +226,7 @@ monitor)
 		-timeout 360s
 	# cleaning up env variables
 	unset "${!KCCONF_@}"
-	exec /usr/sbin/kopano-monitor -F
+	exec "$EXE" -F
 	;;
 search)
 	dockerize \
@@ -224,9 +239,9 @@ search)
 	# with commit 702bb3fccb3 search does not need -F any longer
 	searchversion=$(dpkg-query --showformat='${Version}' --show kopano-search)
 	if dpkg --compare-versions "$searchversion" "gt" "8.7.82.165"; then
-		exec /usr/sbin/kopano-search --config /tmp/kopano/search.cfg
+		exec "$EXE" --config /tmp/kopano/search.cfg
 	else
-		exec /usr/bin/python3 /usr/sbin/kopano-search -F
+		exec /usr/bin/python3 "$EXE" -F
 	fi
 	;;
 spooler)
@@ -236,7 +251,7 @@ spooler)
 		-timeout 1080s
 	# cleaning up env variables
 	unset "${!KCCONF_@}"
-	exec /usr/sbin/kopano-spooler -F
+	exec "$EXE" -F
 	;;
 *)
 	echo "Failed to start: Unknown service name: '$SERVICE_TO_START'" | ts
diff --git a/konnect/wrapper.sh b/konnect/wrapper.sh
index df6d75c..3a50f98 100755
--- a/konnect/wrapper.sh
+++ b/konnect/wrapper.sh
@@ -84,7 +84,7 @@ if [ "${allow_client_guests:-}" = "yes" ]; then
 		fi
 
 		echo "Entrypoint: Patching identifier registration for use of the Meet guest mode"
-		/usr/local/bin/konnectd utils jwk-from-pem --use sig "$eckey" > /tmp/jwk-meet.json
+		"$EXE" utils jwk-from-pem --use sig "$eckey" > /tmp/jwk-meet.json
 		#yq -y ".clients += [{\"id\": \"grapi-explorer.js\", \"name\": \"Grapi Explorer\", \"application_type\": \"web\", \"trusted\": true, \"insecure\": true, \"redirect_uris\": [\"http://$FQDNCLEANED:3000/\"]}]" $CONFIG_JSON | sponge $CONFIG_JSON
 		yq -y ".clients += [{\"id\": \"kpop-https://${FQDN%/*}/meet/\", \"name\": \"Kopano Meet\", \"application_type\": \"web\", \"trusted\": true, \"redirect_uris\": [\"https://${FQDN%/*}/meet/\"], \"trusted_scopes\": [\"konnect/guestok\", \"kopano/kwm\"], \"jwks\": {\"keys\": [{\"kty\": $(jq .kty /tmp/jwk-meet.json), \"use\": $(jq .use /tmp/jwk-meet.json), \"crv\": $(jq .crv /tmp/jwk-meet.json), \"d\": $(jq .d /tmp/jwk-meet.json), \"kid\": $(jq .kid /tmp/jwk-meet.json), \"x\": $(jq .x /tmp/jwk-meet.json), \"y\": $(jq .y /tmp/jwk-meet.json)}]},\"request_object_signing_alg\": \"ES256\"}]" $CONFIG_JSON >> /tmp/guest-mode.yml
 		yq -y -s '.[0] + .[1]' $CONFIG_JSON /tmp/guest-mode.yml | sponge "$identifier_registration_conf"
@@ -174,7 +174,7 @@ dockerize \
 	-wait file:///etc/machine-id \
 	-wait file:///var/lib/dbus/machine-id \
 	-timeout "$DOCKERIZE_TIMEOUT"
-exec konnectd serve \
+exec "$EXE" serve \
 	--signing-private-key="$signing_private_key" \
 	--encryption-secret="$encryption_secret_key" \
 	--identifier-registration-conf "${identifier_registration_conf:?}" \
diff --git a/web/wrapper.sh b/web/wrapper.sh
index d48d5d7..678435d 100755
--- a/web/wrapper.sh
+++ b/web/wrapper.sh
@@ -2,6 +2,12 @@
 
 set -e
 
+# allow helper commands given by "docker-compose run"
+if [ $# -gt 0 ]; then
+	exec "$@"
+	exit
+fi
+
 # services need to be aware of the machine-id
 if [ "$AUTOCONFIG" = "yes" ]; then
 	dockerize \
@@ -9,4 +15,4 @@ if [ "$AUTOCONFIG" = "yes" ]; then
 		-wait file:///var/lib/dbus/machine-id
 fi
 
-exec kwebd caddy -conf /etc/kweb.cfg -agree
+exec "$EXE" caddy -conf /etc/kweb.cfg -agree