diff --git a/docker/Dockerfile.vlkb b/docker/Dockerfile.vlkb
new file mode 100644
index 0000000000000000000000000000000000000000..8bfab4432aea13862dbf8f7b793127e24a258963
--- /dev/null
+++ b/docker/Dockerfile.vlkb
@@ -0,0 +1,68 @@
+FROM debian:bullseye-slim
+LABEL Description="vlkb tomcat9"
+
+WORKDIR /root
+ENV HOME /root
+
+
+RUN apt -y update \
+ && apt -y install sudo procps psmisc tree wget curl vim make build-essential checkinstall git \
+                   libcfitsio-dev libpqxx-dev librabbitmq-dev libcsv-dev gfortran \
+                   openjdk-17-jre-headless unzip \
+                   rabbitmq-server openjdk-17-jre openjdk-17-jdk tomcat9 tomcat9-admin \
+                   postgresql-client
+
+COPY ast_9.2.9-1_amd64.deb ./
+RUN dpkg -i /root/ast_9.2.9-1_amd64.deb && ldconfig \
+ && mkdir -p /webapps/vlkb-search && mkdir -p /webapps/vlkb-cutout && mkdir /config \
+ && mkdir -p /srv/surveys && mkdir -p /srv/cutouts
+
+ARG VLKB_VERSION
+
+COPY vlkb-${VLKB_VERSION}.deb vlkb-obscore-${VLKB_VERSION}.deb vlkbd-${VLKB_VERSION}.deb ./
+COPY vlkb-search-${VLKB_VERSION}.war /webapps/vlkb-search/
+COPY vlkb-cutout-${VLKB_VERSION}.war /webapps/vlkb-cutout/
+RUN dpkg -i vlkb-${VLKB_VERSION}.deb vlkb-obscore-${VLKB_VERSION}.deb vlkbd-${VLKB_VERSION}.deb \
+ && cd /webapps/vlkb-search && jar -xf vlkb-search-${VLKB_VERSION}.war \
+ && cd /webapps/vlkb-cutout && jar -xf vlkb-cutout-${VLKB_VERSION}.war \
+ && mv /webapps/vlkb-search/WEB-INF/lib/postgresql-*.jar /var/lib/tomcat9/lib \
+ && rm /webapps/vlkb-cutout/WEB-INF/lib/postgresql-*.jar
+
+# Lines with postgresql_*.jar: provide DB-driver so Tomcat loads it
+# vlkb-search vlkb-cutout do not explicitely load DB-drivers
+
+
+
+# configure instance
+
+ENV INST_DIR=/usr/local
+
+COPY vlkbd_exec.sh ${INST_DIR}/bin
+
+RUN mkdir -p ${INST_DIR}/etc/vlkb-obscore \
+ && mkdir -p ${INST_DIR}/etc/vlkbd \
+ && echo "${INST_DIR}/lib" > /etc/ld.so.conf.d/ast.conf \
+ && ldconfig
+
+# configure during docker build-time
+
+COPY config-vlkb/vlkb-obscore.datasets.conf ${INST_DIR}/etc/vlkb-obscore/datasets.conf
+COPY config-vlkb/vlkbd.datasets.conf ${INST_DIR}/etc/vlkbd/datasets.conf
+
+# created in entrypoint.sh COPY config-vlkb/servlet.datasets.conf /webapps/vlkb-cutout/WEB-INF/classes/datasets.conf
+
+COPY config-vlkb/auth.properties config-vlkb/neatoken.properties config-vlkb/iamtoken.properties /webapps/vlkb-cutout/WEB-INF/classes/
+COPY config-vlkb/auth.properties config-vlkb/neatoken.properties config-vlkb/iamtoken.properties config-vlkb/formatresponsefilter.properties /webapps/vlkb-search/WEB-INF/classes/
+
+#COPY ssl/keystore.jks /root/
+COPY ssl/server.xml ssl/server-connector-8080.xml ssl/server-connector-8443.xml /etc/tomcat9/
+
+# configure during docker run-time
+
+COPY entrypoint.sh /root
+
+# run
+
+RUN pwd && chmod +x /root/entrypoint.sh
+CMD ["sh", "-c", "/root/entrypoint.sh"]
+
diff --git a/docker/Makefile b/docker/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e120ae7415db33ae2755a9d7b8e27cc9b6b7fb31
--- /dev/null
+++ b/docker/Makefile
@@ -0,0 +1,72 @@
+
+VERSION ?= $(shell git describe)
+
+
+all:
+
+
+download-all: vlkb-search vlkb-cutout vlkbd vlkb-obscore vlkb
+
+vlkb-search vlkb-cutout:
+	make download PACK_FILE=$@-$(VERSION).war
+
+vlkbd vlkb-obscore vlkb:
+	make download PACK_FILE=$@-$(VERSION).rpm
+	make download PACK_FILE=$@-$(VERSION).deb
+
+
+.PHONY: download
+download: GITLAB_PROJ_ID := 79
+download: GITLAB_PROJ_NAME := $(shell basename -s .git `git config --get remote.origin.url`)
+download: VER_MAJOR := $(shell echo $(VERSION) | cut -f1 -d.)
+download: VER_MINOR := $(shell echo $(VERSION) | cut -f2 -d.)
+download: PACK_URL := "https://ict.inaf.it/gitlab/api/v4/projects/$(GITLAB_PROJ_ID)/packages/generic/$(GITLAB_PROJ_NAME)/$(VER_MAJOR).$(VER_MINOR)/$(PACK_FILE)"
+download:
+	curl -O --header "PRIVATE-TOKEN: glpat-CJZDcks7bYqE__ePn4J6" $(PACK_URL)
+
+
+ast-9.2.9.tar.gz:
+	wget https://github.com/Starlink/ast/files/8843897/ast-9.2.9.tar.gz
+
+
+
+.PHONY: build
+build:
+	docker build --build-arg VLKB_VERSION=$(VERSION) -t soda -f Dockerfile.vlkb .
+
+# the docker-login below needed a ca-cert(?) which in the middle of the certificate-chain,
+# but was not automatically downloaded and also local cert/ket pair(?) ->
+# -> see: /etc/docker/certs.d/git.ia2.ianf.it:5050/*
+#
+# docker login git.ia2.inaf.it:5050 (robert.butora C-tol szokasos-hossu)
+# to download: use image: ... in compose.yaml or
+# docker run ... git.ia2.inaf.it:5050/butora/vlkb-datasets/vlkb
+
+publish-locally-soda:
+	docker tag soda git.ia2.inaf.it:5050/butora/vlkb-datasets-docker/soda:$(VERSION)
+	docker push     git.ia2.inaf.it:5050/butora/vlkb-datasets-docker/soda:$(VERSION)
+	docker image rm git.ia2.inaf.it:5050/butora/vlkb-datasets-docker/soda:$(VERSION)
+
+
+##docker login registry.gitlab.com --> robert.butora xC*n
+publish-remotely-to-ska:
+	docker tag soda registry.gitlab.com/ska-telescope/src/visivo-vlkb-soda:$(VERSION)
+	docker push     registry.gitlab.com/ska-telescope/src/visivo-vlkb-soda:$(VERSION)
+	docker image rm registry.gitlab.com/ska-telescope/src/visivo-vlkb-soda:$(VERSION)
+
+###############################################################################
+#TAG ?= $(VERSION)
+#REMOTE_SODA_IMAGE_NAME = registry.gitlab.com/ska-telescope/src/visivo-vlkb-soda:$(TAG)
+#SODA_IMAGE_NAME = soda:$(TAG)
+# https://gitlab.com/ska-telescope/src/visivo-vlkb-soda/container_registry/3917365
+###############################################################################
+#.PHONY: publish
+#publish:
+#	docker tag $(SODA_IMAGE_NAME) $(REMOTE_SODA_IMAGE_NAME)
+#	docker push $(REMOTE_SODA_IMAGE_NAME)
+#	docker image rm $(REMOTE_SODA_IMAGE_NAME)
+#	@echo "SODA_IMAGE_NAME        : "$(SODA_IMAGE_NAME)
+#	@echo "REMOTE_SODA_IMAGE_NAME : "$(REMOTE_SODA_IMAGE_NAME)
+###############################################################################
+
+
diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8f769fabe3bb54e361d9eea767a120280095f0ea
--- /dev/null
+++ b/docker/entrypoint.sh
@@ -0,0 +1,178 @@
+#!/bin/bash
+
+set +e
+LOG_FILE=/tmp/entrypoint.log
+
+{
+date
+whoami
+env
+#########################################################################
+#INST_DIR="/usr/local"
+WEBAPP_DIR=/webapps
+#CONFIG_DIR=/config
+QUEUE_NAME=dockervlkb$ACCESS_CONTEXT_ROOT
+
+echo "SECURITY   : "$SECURITY
+echo "DISCOVERY_CONTEXT_ROOT : "$DISCOVERY_CONTEXT_ROOT
+echo "DISCOVERY_DB_URI       : "$DISCOVERY_DB_URI
+echo "VLKBOBSCORE_PG_URI     : "$VLKBOBSCORE_PG_URI
+echo "ACCESS_CONTEXT_ROOT    : "$ACCESS_CONTEXT_ROOT
+echo "RESPONSE_FORMAT        : "$RESPONSE_FORMAT
+echo "URL_CUTOUTS            : "$URL_CUTOUTS
+echo "INST_DIR   : "$INST_DIR
+echo "WEBAPP_DIR : "$WEBAPP_DIR
+#echo "CONFIG_DIR : "$CONFIG_DIR
+echo "QUEUE_NAME : "$QUEUE_NAME
+#########################################################################
+
+
+
+## configure vlkb-tools
+#mkdir -p $INST_DIR/etc/vlkb-obscore
+#cp $CONFIG_DIR/vlkb-obscore.datasets.conf $INST_DIR/etc/vlkb-obscore/datasets.conf
+if test -n "$VLKBOBSCORE_PG_URI"
+then
+   echo "pg_uri=$VLKBOBSCORE_PG_URI" >> $INST_DIR/etc/vlkb-obscore/datasets.conf
+   echo "pg_schema=datasets"         >> $INST_DIR/etc/vlkb-obscore/datasets.conf
+fi
+
+
+
+## configure VLKB discovery
+if test -n "$DISCOVERY_CONTEXT_ROOT" && test -n "$DISCOVERY_DB_URI"
+then
+
+   if test -n "$SECURITY"
+   then
+     cd $WEBAPP_DIR/vlkb-search/WEB-INF/ && rm -f web.xml && cp web-search-$SECURITY.xml web.xml && cd -
+   fi
+
+#   cp $CONFIG_DIR/{auth.properties,neatoken.properties} $WEBAPP_DIR/vlkb-search/WEB-INF/classes/
+   echo "<Context docBase=\"$WEBAPP_DIR/vlkb-search\"/>" > /var/lib/tomcat9/conf/Catalina/localhost/$DISCOVERY_CONTEXT_ROOT.xml
+   echo "db_uri=$DISCOVERY_DB_URI"  >  $WEBAPP_DIR/vlkb-search/WEB-INF/classes/discovery.properties
+   echo "db_schema=datasets"        >> $WEBAPP_DIR/vlkb-search/WEB-INF/classes/discovery.properties
+   echo "db_user_name=$DB_USERNAME" >> $WEBAPP_DIR/vlkb-search/WEB-INF/classes/discovery.properties
+   echo "db_password=$DB_PASSWORD"  >> $WEBAPP_DIR/vlkb-search/WEB-INF/classes/discovery.properties
+   # use the same DB for authz permissions (ObsCore with extensions)
+   cp $WEBAPP_DIR/vlkb-search/WEB-INF/classes/discovery.properties $WEBAPP_DIR/vlkb-search/WEB-INF/classes/authpolicy.properties
+fi
+
+
+
+## configure VLKB access
+if test -n "$ACCESS_CONTEXT_ROOT"
+then
+
+   if test -n "$SECURITY"
+   then
+      cd $WEBAPP_DIR/vlkb-cutout/WEB-INF/ && rm -f web.xml && cp web-cutout-$SECURITY.xml web.xml && cd -
+   fi
+
+#   cp $CONFIG_DIR/{auth.properties,neatoken.properties} $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/
+   #echo "<Context docBase=\"$WEBAPP_DIR/vlkb-cutout\"/>" > /var/lib/tomcat9/conf/Catalina/localhost/$ACCESS_CONTEXT_ROOT.xml
+   cp $WEBAPP_DIR/vlkb-cutout/META-INF/context.xml /var/lib/tomcat9/conf/Catalina/localhost/$ACCESS_CONTEXT_ROOT.xml
+   echo "db_uri=$DISCOVERY_DB_URI"  >  $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/authpolicy.properties
+   echo "db_schema=datasets"        >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/authpolicy.properties
+   echo "db_user_name=$DB_USERNAME" >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/authpolicy.properties
+   echo "db_password=$DB_PASSWORD"  >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/authpolicy.properties
+
+
+   echo "fits_path_surveys=/srv/surveys" > $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+   echo "fits_path_cutouts=/srv/cutouts" >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+   if test -f /srv/surveys/survey_populate.csv
+   then
+      echo "surveys_metadata_abs_pathname=/srv/surveys/survey_populate.csv" >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+      echo "fits_url_cutouts=$URL_CUTOUTS" >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+   fi
+   if test -n "$RESPONSE_FORMAT"
+   then
+      echo "default_response_format=$RESPONSE_FORMAT" >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+   fi
+
+   case $RESPONSE_FORMAT in application/vlkb*)
+      echo "default_sky_system=GALACTIC"   >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+      echo "default_spec_system=VELO_LSRK" >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+      echo "show_duration=yes"             >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+   esac
+
+   # for resolver (id & extraCards)
+   echo "db_uri=$DISCOVERY_DB_URI"  >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+   echo "db_schema=datasets"        >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+   echo "db_user_name=$DB_USERNAME" >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+   echo "db_password=$DB_PASSWORD"  >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+
+   echo "amqp_host_name=localhost"     >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+   echo "amqp_port=5672"               >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+   echo "amqp_routing_key=$QUEUE_NAME" >> $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/datasets.conf
+
+   case $RESPONSE_FORMAT in application/vlkb*)
+      service rabbitmq-server start
+      $INST_DIR/bin/vlkbd_exec.sh localhost $QUEUE_NAME $INST_DIR/etc/vlkbd/datasets.conf
+   esac
+fi
+
+
+
+# configure port/SSL connector: (path is relative to the dir where compose.yaml is
+# - web.xml to run filters set above
+# * ssl: set tomcat connector with certificates (ia2 needs SECTIGO, iam needs self-signed keystore.jks)
+# * keep right jjwt*.jar libs (ia2 authlib needs v0.11, iam needs v0.12)
+# assume all files in ssl sub-dir relative to where compose.yaml is
+# set volume mapping in compose.yaml: ssl/ -> /etc/pki/tls/
+case $SECURITY in
+   ia2token)
+      #cp ssl/server-connector-8443.xml-SECTIGO-vlkb_ia2_inaf_it  /etc/tomcat9/server-connector-8443.xml
+      cp /root/ssl/server-connector-8443.xml /etc/tomcat9/server-connector-8443.xml
+      # map volume instead of this: cp -r ssl/SECTIGO /etc/pki/tls/
+      rm /webapps/vlkb-search/WEB-INF/lib/jjwt-*0.12*.jar
+      rm /webapps/vlkb-cutout/WEB-INF/lib/jjwt-*0.12*.jar
+      ;;
+   iamtoken)
+      #cp ssl/server-connector-8443.xml-keystore-self-signed  /etc/tomcat9/server-connector-8443.xml
+      cp /root/ssl/server-connector-8443.xml  /etc/tomcat9/server-connector-8443.xml
+      # map volume somedir:/etc/pki/tls with somedir/{keystore.jks,SECTIGO/*} XXX cp ssl/keystore.jks /etc/pki/tls/
+      rm /webapps/vlkb-search/WEB-INF/lib/jjwt-*0.11*.jar
+      rm /webapps/vlkb-cutout/WEB-INF/lib/jjwt-*0.11*.jar
+      ;;
+   *)
+      echo "Security not configured, runs open."
+      ;;
+esac
+
+
+
+#if test -f /srv/surveys/keystore.jks
+#then
+#   cp /srv/surveys/keystore.jks /root/
+#fi
+#if test -f /srv/surveys/server-connector-8443.xml /etc/tomcat9/
+#then
+#   cp /srv/surveys/server-connector-8443.xml /etc/tomcat9/
+#fi
+#
+if test -n "$SECURITY"
+then
+   cd /etc/tomcat9/ && ln -s server-connector-8443.xml server-connector.xml && cd -
+else
+   cd /etc/tomcat9/ && ln -s server-connector-8080.xml server-connector.xml && cd -
+fi
+
+# configure access-token validation
+if test -f /srv/surveys/iamtoken.properties
+then
+   cp /srv/surveys/iamtoken.properties $WEBAPP_DIR/vlkb-cutout/WEB-INF/classes/
+   cp /srv/surveys/iamtoken.properties $WEBAPP_DIR/vlkb-search/WEB-INF/classes/
+fi
+
+
+#########################################################################
+
+date
+
+} 1> $LOG_FILE 2>&1
+
+JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 CATALINA_BASE=/var/lib/tomcat9 CATALINA_HOME=/usr/share/tomcat9 CATALINA_TMPDIR=/tmp /usr/libexec/tomcat9/tomcat-start.sh &
+
+wait -n
+