diff --git a/docker/Makefile b/docker/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..aa41ed2331e0816b65213d97745d8cf8ece28b21
--- /dev/null
+++ b/docker/Makefile
@@ -0,0 +1,27 @@
+DIRS = tango
+BUILDDIRS = $(DIRS:%=build-%)
+TESTDIRS = $(DIRS:%=test-%)
+PUSHDIRS = $(DIRS:%=push-%)
+
+.DEFAULT_GOAL := help
+
+build: $(DIRS)  ## build all images
+$(DIRS): $(BUILDDIRS)
+$(BUILDDIRS):
+	$(MAKE) -C $(@:build-%=%) build
+
+test: $(TESTDIRS)
+$(TESTDIRS):
+	$(MAKE) -C $(@:test-%=%) test
+
+push: $(PUSHDIRS)  ## push images to Docker hub
+$(PUSHDIRS):
+	$(MAKE) -C $(@:push-%=%) push
+
+help:  ## show this help.
+	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+
+.PHONY: subdirs $(DIRS)
+.PHONY: subdirs $(BUILDDIRS)
+.PHONY: subdirs $(PUSHDIRS)
+.PHONY: build test push help
diff --git a/docker/deploy/.release b/docker/deploy/.release
new file mode 100644
index 0000000000000000000000000000000000000000..88399d0d0939bc3caa1f9c01f46df613bd9a6c70
--- /dev/null
+++ b/docker/deploy/.release
@@ -0,0 +1,2 @@
+release=0.4.2
+tag=deploy-0.4.2
diff --git a/docker/deploy/Dockerfile b/docker/deploy/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..cf098ca4fdaa9799ed73a4f24b5aa352e4e5b321
--- /dev/null
+++ b/docker/deploy/Dockerfile
@@ -0,0 +1,44 @@
+FROM ubuntu:18.04
+
+ENV KUBE_LATEST_VERSION="v1.16.2"
+ENV HELM_VERSION="v3.3.1"
+ENV DEBIAN_FRONTEND="noninteractive"
+ENV RUNLEVEL="1"
+ENV PYTEST_REQUIREMENTS="https://gitlab.com/ska-telescope/skampi/raw/8204ac53ef67941bf22e9f259be1910b2a9636a5/test-requirements.txt"
+
+RUN apt-get update
+RUN apt-get install -y make bash git curl apt-transport-https ca-certificates wget software-properties-common
+RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
+RUN apt-key fingerprint 0EBFCD88
+RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
+RUN apt-get update
+RUN apt-get install -y docker-ce
+RUN export LC_ALL=C
+# pip
+RUN apt-get install -yq python3-distutils \
+    && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
+    && python3 get-pip.py
+COPY pip.conf /etc/pip.conf
+# /pip
+
+RUN python3 -m pip install docker-compose
+RUN python3 -m pip install yamllint yamale
+
+RUN wget -q https://storage.googleapis.com/kubernetes-release/release/${KUBE_LATEST_VERSION}/bin/linux/amd64/kubectl -O /usr/local/bin/kubectl \
+    && chmod +x /usr/local/bin/kubectl \
+    && wget -q https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz -O - | tar -xzO linux-amd64/helm > /usr/local/bin/helm \
+    && chmod +x /usr/local/bin/helm
+
+RUN wget -q https://github.com/helm/chart-testing/releases/download/v3.0.0-beta.1/chart-testing_3.0.0-beta.1_linux_amd64.tar.gz -O /tmp/ct.tar.gz \
+    && cd /tmp \
+    && tar -xf ct.tar.gz \
+    && mv ct /usr/local/bin/ct
+
+RUN python3 -m pip install -r ${PYTEST_REQUIREMENTS}
+RUN python3 -m pip install pytest
+
+RUN apt-get update
+RUN apt-get install -y python software-properties-common net-tools
+RUN apt-add-repository --yes --update ppa:ansible/ansible
+RUN printf "#!/bin/sh\nexit 0" > /usr/sbin/policy-rc.d
+RUN apt-get -y install ansible ssh python-apt
diff --git a/docker/deploy/Makefile b/docker/deploy/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..df37dbb1286343b13b64bfa8abef9b87adf9cd23
--- /dev/null
+++ b/docker/deploy/Makefile
@@ -0,0 +1,7 @@
+include ../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/deploy/pip.conf b/docker/deploy/pip.conf
new file mode 100644
index 0000000000000000000000000000000000000000..41d1dce5e2cce9176483b21e87ebf2c1cf5f1f6c
--- /dev/null
+++ b/docker/deploy/pip.conf
@@ -0,0 +1,4 @@
+[global]
+index-url = https://nexus.engageska-portugal.pt/repository/pypi/simple
+extra-index-url = https://pypi.org/simple
+disable-pip-version-check = True
diff --git a/docker/make/.make-release-support b/docker/make/.make-release-support
new file mode 100644
index 0000000000000000000000000000000000000000..00473f1f9ed7e3d04729261f13e733575748fce7
--- /dev/null
+++ b/docker/make/.make-release-support
@@ -0,0 +1,107 @@
+#!/bin/bash
+#
+#   Copyright 2015  Xebia Nederland B.V.
+#   Modifications copyright (c) 2019 SKA Organisation
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+function hasChanges() {
+	test -n "$(git status -s .)"
+}
+
+function getRelease() {
+	awk -F= '/^release=/{print $2}' .release
+}
+
+function getBaseTag() {
+		sed -n -e "s/^tag=\(.*\)$(getRelease)\$/\1/p" .release
+}
+
+function getTag() {
+	if [ -z "$1" ] ; then
+		awk -F= '/^tag/{print $2}' .release
+	else
+		echo "$(getBaseTag)$1"
+	fi
+}
+
+function setRelease() {
+	if [ -n "$1" ] ; then
+		sed -i.x -e "s/^tag=.*/tag=$(getTag $1)/" .release
+		sed -i.x -e "s/^release=.*/release=$1/g" .release
+		rm -f .release.x
+		runPreTagCommand "$1"
+	else
+		echo "ERROR: missing release version parameter " >&2
+		return 1
+	fi
+}
+
+function runPreTagCommand() {
+	if [ -n "$1" ] ; then
+		COMMAND=$(sed -n -e "s/@@RELEASE@@/$1/g" -e 's/^pre_tag_command=\(.*\)/\1/p' .release)
+		if [ -n "$COMMAND" ] ; then
+			if ! OUTPUT=$(bash -c "$COMMAND" 2>&1) ; then echo $OUTPUT >&2 && exit 1 ; fi
+		fi
+	else
+		echo "ERROR: missing release version parameter " >&2
+		return 1
+	fi
+}
+
+function tagExists() {
+	tag=${1:-$(getTag)}
+	test -n "$tag" && test -n "$(git tag | grep "^$tag\$")"
+}
+
+function differsFromRelease() {
+	tag=$(getTag)
+	! tagExists $tag || test -n "$(git diff --shortstat -r $tag .)"
+}
+
+function getVersion() {
+	result=$(getRelease)
+
+	#MDC 14092019 the release support must be reviewed
+	#if differsFromRelease; then
+	#	result="$result-$(git log -n 1 --format=%h .)"
+	#fi
+
+	if hasChanges ; then
+		result="$result-dirty"
+	fi
+	echo $result
+}
+
+function nextPatchLevel() {
+	version=${1:-$(getRelease)}
+	major_and_minor=$(echo $version | cut -d. -f1,2)
+	patch=$(echo $version | cut -d. -f3)
+	version=$(printf "%s.%d" $major_and_minor $(($patch + 1)))
+	echo $version
+}
+
+function nextMinorLevel() {
+	version=${1:-$(getRelease)}
+	major=$(echo $version | cut -d. -f1);
+	minor=$(echo $version | cut -d. -f2);
+	version=$(printf "%d.%d.0" $major $(($minor + 1))) ;
+	echo $version
+}
+
+function nextMajorLevel() {
+	version=${1:-$(getRelease)}
+	major=$(echo $version | cut -d. -f1);
+	version=$(printf "%d.0.0" $(($major + 1)))
+	echo $version
+}
diff --git a/docker/make/Makefile b/docker/make/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e0e5607b868dedfb873266a58c69ed451f12ea6b
--- /dev/null
+++ b/docker/make/Makefile
@@ -0,0 +1,2 @@
+SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
+include $(SELF_DIR)/Makefile.mk
diff --git a/docker/make/Makefile.mk b/docker/make/Makefile.mk
new file mode 100644
index 0000000000000000000000000000000000000000..dde32cc947bc1770acc2fcddbb6524d00c8a6049
--- /dev/null
+++ b/docker/make/Makefile.mk
@@ -0,0 +1,122 @@
+#
+#   Copyright 2015  Xebia Nederland B.V.
+#   Modifications copyright (c) 2019 SKA Organisation
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+NAME=$(shell basename $(CURDIR))
+
+RELEASE_SUPPORT := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))/.make-release-support
+
+ifeq ($(strip $(DOCKER_REGISTRY_HOST)),)
+  DOCKER_REGISTRY_HOST = nexus.engageska-portugal.pt
+endif
+
+ifeq ($(strip $(DOCKER_REGISTRY_USER)),)
+  DOCKER_REGISTRY_USER = ska-docker
+endif
+
+IMAGE=$(DOCKER_REGISTRY_HOST)/$(DOCKER_REGISTRY_USER)/$(NAME)
+
+VERSION=$(shell . $(RELEASE_SUPPORT) ; getVersion)
+TAG=$(shell . $(RELEASE_SUPPORT); getTag)
+
+SHELL=/bin/bash
+
+DOCKER_BUILD_CONTEXT=.
+DOCKER_FILE_PATH=Dockerfile
+
+.PHONY: pre-build docker-build post-build build release patch-release minor-release major-release tag check-status check-release showver \
+	push pre-push do-push post-push
+
+build: pre-build docker-build post-build
+
+pre-build:
+
+post-build:
+
+pre-push:
+
+post-push:
+
+docker-build: .release
+	docker build $(DOCKER_BUILD_ARGS) -t $(IMAGE):$(VERSION) $(DOCKER_BUILD_CONTEXT) -f $(DOCKER_FILE_PATH) --build-arg DOCKER_REGISTRY_HOST=$(DOCKER_REGISTRY_HOST) --build-arg DOCKER_REGISTRY_USER=$(DOCKER_REGISTRY_USER) --build-arg http_proxy --build-arg https_proxy
+	@DOCKER_MAJOR=$(shell docker -v | sed -e 's/.*version //' -e 's/,.*//' | cut -d\. -f1) ; \
+	DOCKER_MINOR=$(shell docker -v | sed -e 's/.*version //' -e 's/,.*//' | cut -d\. -f2) ; \
+	if [ $$DOCKER_MAJOR -eq 1 ] && [ $$DOCKER_MINOR -lt 10 ] ; then \
+		echo docker tag -f $(IMAGE):$(VERSION) $(IMAGE):latest ;\
+		docker tag -f $(IMAGE):$(VERSION) $(IMAGE):latest ;\
+	else \
+		echo docker tag $(IMAGE):$(VERSION) $(IMAGE):latest ;\
+		docker tag $(IMAGE):$(VERSION) $(IMAGE):latest ; \
+	fi
+
+.release:
+	@echo "release=0.0.0" > .release
+	@echo "tag=$(NAME)-0.0.0" >> .release
+	@echo INFO: .release created
+	@cat .release
+
+release: check-status check-release build push
+
+push: pre-push do-push post-push
+
+do-push:
+	@curl --output /dev/null --silent --head --fail -r 0-0 "https://$(DOCKER_REGISTRY_HOST)/repository/docker/v2/$(DOCKER_REGISTRY_USER)/$(NAME)/manifests/$(VERSION)"; \
+	result=$$?; \
+	if [ $$result -eq 0 ] ; then \
+		echo "Version $(VERSION) of image $(IMAGE) already exists"; \
+	else \
+		echo "Version $(VERSION) of image $(IMAGE) does not exist"; \
+		docker push $(IMAGE):$(VERSION); \
+		docker push $(IMAGE):latest; \
+	fi;
+
+snapshot: build push
+
+showver: .release
+	@. $(RELEASE_SUPPORT); getVersion
+
+tag-patch-release: VERSION := $(shell . $(RELEASE_SUPPORT); nextPatchLevel)
+tag-patch-release: .release tag
+
+tag-minor-release: VERSION := $(shell . $(RELEASE_SUPPORT); nextMinorLevel)
+tag-minor-release: .release tag
+
+tag-major-release: VERSION := $(shell . $(RELEASE_SUPPORT); nextMajorLevel)
+tag-major-release: .release tag
+
+patch-release: tag-patch-release release
+	@echo $(VERSION)
+
+minor-release: tag-minor-release release
+	@echo $(VERSION)
+
+major-release: tag-major-release release
+	@echo $(VERSION)
+
+tag: TAG=$(shell . $(RELEASE_SUPPORT); getTag $(VERSION))
+tag: check-status
+#	@. $(RELEASE_SUPPORT) ; ! tagExists $(TAG) || (echo "ERROR: tag $(TAG) for version $(VERSION) already tagged in git" >&2 && exit 1) ;
+	@. $(RELEASE_SUPPORT) ; setRelease $(VERSION)
+#	git add .
+#	git commit -m "bumped to version $(VERSION)" ;
+#	git tag $(TAG) ;
+#	@ if [ -n "$(shell git remote -v)" ] ; then git push --tags ; else echo 'no remote to push tags to' ; fi
+
+check-status:
+	@. $(RELEASE_SUPPORT) ; ! hasChanges || (echo "ERROR: there are still outstanding changes" >&2 && exit 1) ;
+
+check-release: .release
+	@. $(RELEASE_SUPPORT) ; tagExists $(TAG) || (echo "ERROR: version not yet tagged in git. make [minor,major,patch]-release." >&2 && exit 1) ;
+	@. $(RELEASE_SUPPORT) ; ! differsFromRelease $(TAG) || (echo "ERROR: current directory differs from tagged $(TAG). make [minor,major,patch]-release." ; exit 1)
diff --git a/docker/tango/Makefile b/docker/tango/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..71ba876d1b19d5a52077be6a30390c46b5042b6b
--- /dev/null
+++ b/docker/tango/Makefile
@@ -0,0 +1,41 @@
+DIRS = tango-builder tango-dependencies tango-db tango-cpp tango-java tango-rest tango-dsconfig ska-python-buildenv tango-pogo tango-starter tango-libtango tango-jive ska-python-runtime tango-admin tango-databaseds tango-test tango-itango tango-vscode tango-vnc tango-pytango mariadb_hdbpp tango-archiver hdbpp_viewer
+TEST = ska-python-buildenv tango-itango tango-rest tango-db tango-cpp tango-archiver
+BUILDDIRS = $(DIRS:%=build-%)
+TESTDIRS = $(TEST:%=test-%)
+CHECKSTATUSDIRS = $(DIRS:%=checkstatus-%)
+SHOWVERDIRS = $(DIRS:%=showver-%)
+PUSHDIRS = $(DIRS:%=push-%)
+
+.DEFAULT_GOAL := help
+
+build: $(DIRS)  ## build all images
+$(DIRS): $(BUILDDIRS)
+$(BUILDDIRS):
+	$(MAKE) -C $(@:build-%=%) build
+
+test: $(TESTDIRS)
+$(TESTDIRS):
+	$(MAKE) -C $(@:test-%=%) test
+
+check-status: $(CHECKSTATUSDIRS) ## check whether subdirectories have uncommitted changes
+$(CHECKSTATUSDIRS):
+	$(MAKE) -C $(@:checkstatus-%=%) check-status
+
+showver: $(SHOWVERDIRS)  ## show image versions
+$(SHOWVERDIRS):
+	$(MAKE) -C $(@:showver-%=%) showver
+
+push: $(PUSHDIRS)  ## push images to Docker hub
+$(PUSHDIRS):
+	$(MAKE) -C $(@:push-%=%) push
+
+help:  ## show this help.
+	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+
+.PHONY: subdirs $(DIRS)
+.PHONY: subdirs $(BUILDDIRS)
+.PHONY: subdirs $(CHECKSTATUSDIRS)
+.PHONY: subdirs $(PUSHDIRS)
+.PHONY: subdirs $(SHOWVERDIRS)
+.PHONY: build check-status showver push help
+
diff --git a/docker/tango/hdbpp_viewer/.release b/docker/tango/hdbpp_viewer/.release
new file mode 100644
index 0000000000000000000000000000000000000000..ad95a885299761ab3b43426015710622f8468062
--- /dev/null
+++ b/docker/tango/hdbpp_viewer/.release
@@ -0,0 +1,2 @@
+release=1.10.1
+tag=hdbpp_viewer-1.10.1
diff --git a/docker/tango/hdbpp_viewer/Dockerfile b/docker/tango/hdbpp_viewer/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..d007e8c56a5311d02cc863576ee76220bfe91412
--- /dev/null
+++ b/docker/tango/hdbpp_viewer/Dockerfile
@@ -0,0 +1,24 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-java:latest
+
+USER root
+
+ENV DEBIAN_FRONTEND="noninteractive"
+ENV HDBPP_DOWNLOAD_URL="https://nexus.engageska-portugal.pt/repository/raw/tango-cs/hdbpp_viewer/hdbpp_viewer_resources_20200527.tgz"
+
+RUN apt-get update \
+    && apt-get install -y wget
+
+# Untarring this will create the `hdbpp_viewer` folder.
+# Inside the tarball is a README detailing the source files.
+RUN wget "$HDBPP_DOWNLOAD_URL" -O hdbpp_viewer_resources.tgz \
+    && tar zxvf hdbpp_viewer_resources.tgz \
+    && rm hdbpp_viewer_resources.tgz
+
+ADD hdbpp_viewer_script hdbpp_viewer
+
+RUN find . -iname HDBPP.jar
+RUN find . -iname ATKCore.jar
+
+USER tango
diff --git a/docker/tango/hdbpp_viewer/Makefile b/docker/tango/hdbpp_viewer/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/hdbpp_viewer/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/hdbpp_viewer/README.md b/docker/tango/hdbpp_viewer/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..dcd1a2f2163741059510b91bf0d165b39becd500
--- /dev/null
+++ b/docker/tango/hdbpp_viewer/README.md
@@ -0,0 +1,55 @@
+# HDB++ Viewer Docker Container
+
+[![Documentation Status](https://readthedocs.org/projects/ska-docker/badge/?version=latest)](https://developer.skatelescope.org/projects/ska-docker/en/latest/?badge=latest)
+
+
+# 1: Introduction
+The HdbViewer GUI visualizes the data stored in the Historical database(HDB). This Java framework, allows 
+retrieving the data from Maria database(HDB). It has been written using Swing and needs a JVM higher than 1.7.0. 
+[Link to the documentation](https://github.com/tango-controls-hdbpp/hdbpp-viewer) 
+
+# 2: Prerequisites - Installation 
+  [Link to hdb++ github repository](https://github.com/tango-controls-hdbpp/hdbpp-viewer)
+  
+# 3: HDB++ Viewer dockerfile
+* Image Location
+  * nexus.engageska-portugal.pt/ska-docker/tango-java:latest
+* Dependencies
+  * TANGO=$BASEDIR/JTango.jar
+  * TANGOATK=$BASEDIR/ATKCore.jar:$BASEDIR/ATKWidget.jar
+  * HDBVIEWER=$BASEDIR/jhdbviewer.jar
+  * HDBPP=$BASEDIR/HDBPP.jar
+  * JYTHON=$BASEDIR/jython.jar
+  * JCALENDAR=$BASEDIR/jcalendar.jar
+* Environment Variables
+  * HDB_TYPE=mysql                           //type of database
+  * HDB_MYSQL_HOST=archiver-maria-db         //database host (In this case, host is container name) 
+  * HDB_MYSQL_PORT=3306                      //database port 
+  * HDB_USER=tango                           //database user
+  * HDB_PASSWORD=tango                       //user password
+  * HDB_NAME=hdbpp                           //database name
+* Command line to set the environment variables
+  * export HDB_TYPE
+  * export HDB_MYSQL_HOST
+  * export HDB_USER
+  * export HDB_PASSWORD
+  * export HDB_NAME
+  * export HDB_MYSQL_PORT
+  * CLASSPATH=$TANGO:$TANGOATK:$HDBVIEWER:$HDBPP:$JYTHON:$JCALENDAR
+  * export CLASSPATH
+  
+# 4: Container Creation for HDB++ Viewer
+nexus.engageska-portugal.pt/ska-docker/hdbpp_viewer image with tag 'latest' is used in the hdbpp-viewer container. 
+Databaseds, mariadb, hdbpp-es and hdbpp-cm containers should be up and running to access HDB++ viewer device.
+Following are the environment variables set at the time of container creation: XAUTHORITY=${XAUTHORITY}, DISPLAY=${DISPLAY},
+TANGO_HOST=${TANGO_HOST}, HDB_TYPE, HDB_MYSQL_HOST, HDB_MYSQL_PORT, HDB_USER, HDB_PASSWORD and HDB_NAME.
+Refer the link 
+[docker-compose.yaml](https://gitlab.com/ska-telescope/ska-docker/blob/master/docker/tango/tango-archiver/docker-compose.yml)
+
+# 5: Running HDB++ viewer inside docker containers
+
+ HDB++ viewer can run on dockers using following command inside the ./tango-archiver
+
+In order to launch the viewer, execute:
+
+`make test`
diff --git a/docker/tango/hdbpp_viewer/hdbpp_viewer_script b/docker/tango/hdbpp_viewer/hdbpp_viewer_script
new file mode 100755
index 0000000000000000000000000000000000000000..66688fbedf2b880881d8b02fcda1bae274465031
--- /dev/null
+++ b/docker/tango/hdbpp_viewer/hdbpp_viewer_script
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+if [ ! $TANGO_HOST ] && [ -f /etc/tangorc ]; then
+   . /etc/tangorc
+fi
+
+#
+# Define the CLASSPATH
+#
+LOGBACK=${TANGO_LOGBACK:-/usr/local/share/tango/logback.xml}
+
+BASEDIR=/hdbpp_viewer
+TANGO=$BASEDIR/JTango.jar
+TANGOATK=$BASEDIR/ATKCore.jar:$BASEDIR/ATKWidget.jar
+HDBVIEWER=$BASEDIR/jhdbviewer.jar
+HDBPP=$BASEDIR/HDBPP.jar
+JYTHON=$BASEDIR/jython.jar
+JCALENDAR=$BASEDIR/jcalendar.jar
+CLASSPATH=$TANGO:$TANGOATK:$HDBVIEWER:$HDBPP:$JYTHON:$JCALENDAR
+
+echo "************************************************"
+env
+echo "************************************************"
+
+echo "/usr/bin/java -Dlogback.configurationFile="$LOGBACK" -DTANGO_HOST=$TANGO_HOST HDBViewer.MainPanel $@"
+
+/usr/bin/java -Dlogback.configurationFile="$LOGBACK" -DTANGO_HOST=$TANGO_HOST HDBViewer.MainPanel $@
diff --git a/docker/tango/mariadb_hdbpp/.release b/docker/tango/mariadb_hdbpp/.release
new file mode 100644
index 0000000000000000000000000000000000000000..f8f5c25601490a7033c91add51d547aa40e10980
--- /dev/null
+++ b/docker/tango/mariadb_hdbpp/.release
@@ -0,0 +1,2 @@
+release=1.1.0
+tag=mariadb_hdbpp-1.1.0
diff --git a/docker/tango/mariadb_hdbpp/Dockerfile b/docker/tango/mariadb_hdbpp/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..f3b652ec2dd537ff1dfcace3bf5ce7803b24404b
--- /dev/null
+++ b/docker/tango/mariadb_hdbpp/Dockerfile
@@ -0,0 +1,7 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-db:latest
+
+COPY resources/create_hdb++_mysql.sql docker-entrypoint-initdb.d/create_db.sql
+COPY resources/my.cnf /etc/mysql/conf.d
+
diff --git a/docker/tango/mariadb_hdbpp/Makefile b/docker/tango/mariadb_hdbpp/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/mariadb_hdbpp/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/mariadb_hdbpp/README.md b/docker/tango/mariadb_hdbpp/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..aee69033e1da0897d8df2b2f37ac65579cde50ab
--- /dev/null
+++ b/docker/tango/mariadb_hdbpp/README.md
@@ -0,0 +1,21 @@
+# Mariadb Docker Container
+
+[![Documentation Status](https://readthedocs.org/projects/ska-docker/badge/?version=latest)](https://developer.skatelescope.org/projects/ska-docker/en/latest/?badge=latest)
+
+# 1: Introduction
+The archiver database provides the repository of historical values of attributes, observation states, alarms and data associated 
+with other events generated during the control and monitoring of Telescope. 
+Mariadb is the database name, which stores the archived data. It is a separate database, other than the tango database. 
+The Tango events are subscribed by the hdbpp-es (hdbpp event subscriber) and written to the archive database. 
+Mariadb uses the default schema of HDB++ (refer to 'create_hdb++_mysql.sql' file), for storing archived data. 
+
+# 2: Creating Mariadb docker containers
+ nexus.engageska-portugal.pt/ska-docker/mariadb_hdbpp image with 'latest' tag is used to create Mariadb container. 
+ MYSQL_DATABASE=hdbpp,  MYSQL_USER=tango, MYSQL_PASSWORD=tango, TANGO_HOST=${TANGO_HOST} are the environment variables set 
+ at the time of mariadb container creation. 'archiverdb' is the permanent volume required for storing the database file.
+
+# 3: Running Mariadb inside docker containers
+
+The archiver database is brought up and running on dockers using the following command inside the ./tango-archiver
+
+`make test`
diff --git a/docker/tango/mariadb_hdbpp/resources/create_hdb++_mysql.sql b/docker/tango/mariadb_hdbpp/resources/create_hdb++_mysql.sql
new file mode 100644
index 0000000000000000000000000000000000000000..3769a6d74523ff0cc8a942dc8976fa184e4b93f1
--- /dev/null
+++ b/docker/tango/mariadb_hdbpp/resources/create_hdb++_mysql.sql
@@ -0,0 +1,919 @@
+CREATE DATABASE IF NOT EXISTS hdbpp;
+USE hdbpp;
+
+----------------------------------------------------------------
+------------------ create_hdb++_mysql.sql ----------------------
+----------------------------------------------------------------
+GRANT ALL PRIVILEGES  ON hdbpp.* TO 'root'@'localhost' identified by 'secret' WITH GRANT OPTION;
+
+GRANT ALL ON hdbpp.* TO 'hdbpprw'@'%' IDENTIFIED BY "hdbpprw";
+
+CREATE USER IF NOT EXISTS 'tango'@'%' identified by 'tango';
+GRANT ALL PRIVILEGES ON hdbpp.* To 'tango'@'%' IDENTIFIED BY 'tango' WITH GRANT OPTION;
+FLUSH PRIVILEGES;
+
+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
+
+SET time_zone = "+00:00";
+
+ALTER DATABASE hdbpp CHARACTER SET latin1 COLLATE latin1_swedish_ci;
+
+SET SESSION SQL_MODE='ALLOW_INVALID_DATES';
+
+-- ---------------------------------------------------------------
+-- --------------CONCRETE TABLE INHERITANCE-----------------------
+-- ---------------------------------------------------------------
+
+CREATE TABLE IF NOT EXISTS att_conf
+(
+att_conf_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+att_name VARCHAR(255) UNIQUE NOT NULL,
+att_conf_data_type_id INT UNSIGNED NOT NULL,
+att_ttl INT UNSIGNED NULL DEFAULT NULL,
+facility VARCHAR(255) NOT NULL DEFAULT '',
+domain VARCHAR(255) NOT NULL DEFAULT '',
+family VARCHAR(255) NOT NULL DEFAULT '',
+member VARCHAR(255) NOT NULL DEFAULT '',
+name VARCHAR(255) NOT NULL DEFAULT '',
+INDEX(att_conf_data_type_id)
+) ENGINE=MyISAM COMMENT='Attribute Configuration Table';
+
+DROP TABLE IF EXISTS att_conf_data_type;
+CREATE TABLE IF NOT EXISTS att_conf_data_type
+(
+att_conf_data_type_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+data_type VARCHAR(255) NOT NULL,
+tango_data_type TINYINT(1) NOT NULL
+) ENGINE=MyISAM COMMENT='Attribute types description';
+
+INSERT INTO att_conf_data_type (data_type, tango_data_type) VALUES
+('scalar_devboolean_ro', 1),('scalar_devboolean_rw', 1),('array_devboolean_ro', 1),('array_devboolean_rw', 1),
+('scalar_devuchar_ro', 22),('scalar_devuchar_rw', 22),('array_devuchar_ro', 22),('array_devuchar_rw', 22),
+('scalar_devshort_ro', 2),('scalar_devshort_rw', 2),('array_devshort_ro', 2),('array_devshort_rw', 2),
+('scalar_devushort_ro', 6),('scalar_devushort_rw', 6),('array_devushort_ro', 6),('array_devushort_rw', 6),
+('scalar_devlong_ro', 3),('scalar_devlong_rw', 3),('array_devlong_ro', 3),('array_devlong_rw', 3),
+('scalar_devulong_ro', 7),('scalar_devulong_rw', 7),('array_devulong_ro', 7),('array_devulong_rw', 7),
+('scalar_devlong64_ro', 23),('scalar_devlong64_rw', 23),('array_devlong64_ro', 23),('array_devlong64_rw', 23),
+('scalar_devulong64_ro', 24),('scalar_devulong64_rw', 24),('array_devulong64_ro', 24),('array_devulong64_rw', 24),
+('scalar_devfloat_ro', 4),('scalar_devfloat_rw', 4),('array_devfloat_ro', 4),('array_devfloat_rw', 4),
+('scalar_devdouble_ro', 5),('scalar_devdouble_rw', 5),('array_devdouble_ro', 5),('array_devdouble_rw', 5),
+('scalar_devstring_ro', 8),('scalar_devstring_rw', 8),('array_devstring_ro', 8),('array_devstring_rw', 8),
+('scalar_devstate_ro', 19),('scalar_devstate_rw', 19),('array_devstate_ro', 19),('array_devstate_rw', 19),
+('scalar_devencoded_ro', 28),('scalar_devencoded_rw', 28),('array_devencoded_ro', 28),('array_devencoded_rw', 28),
+('scalar_devenum_ro', 29),('scalar_devenum_rw', 29),('array_devenum_ro', 29),('array_devenum_rw', 29);
+
+CREATE TABLE IF NOT EXISTS att_history
+(
+att_conf_id INT UNSIGNED NOT NULL,
+time TIMESTAMP(6) DEFAULT 0,
+att_history_event_id INT UNSIGNED NOT NULL,
+INDEX(att_conf_id),
+INDEX(att_history_event_id)
+) ENGINE=MyISAM COMMENT='Attribute Configuration Events History Table';
+
+DROP TABLE IF EXISTS att_history_event;
+CREATE TABLE IF NOT EXISTS att_history_event
+(	
+att_history_event_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+event VARCHAR(255) NOT NULL
+) ENGINE=MyISAM COMMENT='Attribute history events description';
+
+INSERT INTO att_history_event (event) VALUES
+('add'),('remove'),('start'),('stop'),('crash'),('pause');
+
+CREATE TABLE IF NOT EXISTS att_parameter
+(
+att_conf_id INT UNSIGNED NOT NULL,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+label VARCHAR(255) NOT NULL DEFAULT '',
+unit VARCHAR(64) NOT NULL DEFAULT '',
+standard_unit VARCHAR(64) NOT NULL DEFAULT '1',
+display_unit VARCHAR(64) NOT NULL DEFAULT '',
+format VARCHAR(64) NOT NULL DEFAULT '',
+archive_rel_change VARCHAR(64) NOT NULL DEFAULT '',
+archive_abs_change VARCHAR(64) NOT NULL DEFAULT '',
+archive_period VARCHAR(64) NOT NULL DEFAULT '',
+description VARCHAR(1024) NOT NULL DEFAULT '',
+INDEX(recv_time),
+INDEX(att_conf_id)
+) ENGINE=MyISAM COMMENT='Attribute configuration parameters';
+
+CREATE TABLE IF NOT EXISTS att_error_desc
+(
+att_error_desc_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+error_desc VARCHAR(255) UNIQUE NOT NULL
+) ENGINE=MyISAM COMMENT='Error Description Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devboolean_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r TINYINT(1) UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Boolean ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devboolean_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r TINYINT(1) UNSIGNED DEFAULT NULL,
+value_w TINYINT(1) UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Boolean ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devboolean_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r TINYINT(1) UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Boolean ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devboolean_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r TINYINT(1) UNSIGNED DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w TINYINT(1) UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Boolean ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devuchar_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r TINYINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar UChar ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devuchar_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r TINYINT UNSIGNED DEFAULT NULL,
+value_w TINYINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar UChar ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devuchar_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r TINYINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array UChar ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devuchar_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r TINYINT UNSIGNED DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w TINYINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array UChar ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devshort_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r SMALLINT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Short ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devshort_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r SMALLINT DEFAULT NULL,
+value_w SMALLINT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Short ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devshort_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r SMALLINT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Short ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devshort_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r SMALLINT DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w SMALLINT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Short ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devushort_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r SMALLINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar UShort ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devushort_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r SMALLINT UNSIGNED DEFAULT NULL,
+value_w SMALLINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar UShort ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devushort_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r SMALLINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array UShort ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devushort_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r SMALLINT UNSIGNED DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w SMALLINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array UShort ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devlong_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r INT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Long ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devlong_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r INT DEFAULT NULL,
+value_w INT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Long ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devlong_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r INT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Long ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devlong_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r INT DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w INT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Long ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devulong_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r INT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar ULong ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devulong_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r INT UNSIGNED DEFAULT NULL,
+value_w INT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar ULong ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devulong_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r INT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array ULong ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devulong_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r INT UNSIGNED DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w INT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array ULong ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devlong64_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r BIGINT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Long64 ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devlong64_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r BIGINT DEFAULT NULL,
+value_w BIGINT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Long64 ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devlong64_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r BIGINT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Long64 ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devlong64_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r BIGINT DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w BIGINT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Long64 ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devulong64_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r BIGINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar ULong64 ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devulong64_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r BIGINT UNSIGNED DEFAULT NULL,
+value_w BIGINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar ULong64 ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devulong64_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r BIGINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array ULong64 ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devulong64_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r BIGINT UNSIGNED DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w BIGINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array ULong64 ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devfloat_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r FLOAT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Float ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devfloat_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r FLOAT DEFAULT NULL,
+value_w FLOAT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Float ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devfloat_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r FLOAT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Float ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devfloat_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r FLOAT DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w FLOAT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Float ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devdouble_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r DOUBLE DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Double ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devdouble_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r DOUBLE DEFAULT NULL,
+value_w DOUBLE DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Double ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devdouble_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r DOUBLE DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Double ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devdouble_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r DOUBLE DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w DOUBLE DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Double ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devstring_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r VARCHAR(16384) DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar String ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devstring_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r VARCHAR(16384) DEFAULT NULL,
+value_w VARCHAR(16384) DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar String ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devstring_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r VARCHAR(16384) DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array String ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devstring_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r VARCHAR(16384) DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w VARCHAR(16384) DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array String ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devstate_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r TINYINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar State ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devstate_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r TINYINT UNSIGNED DEFAULT NULL,
+value_w TINYINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar State ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devstate_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r TINYINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array State ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devstate_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r TINYINT UNSIGNED DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w TINYINT UNSIGNED DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array State ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devencoded_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r BLOB DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Encoded ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devencoded_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r BLOB DEFAULT NULL,
+value_w BLOB DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Encoded ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devencoded_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r BLOB DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Encoded ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devencoded_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r BLOB DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w BLOB DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Encoded ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devenum_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r SMALLINT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Enum ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_scalar_devenum_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+value_r SMALLINT DEFAULT NULL,
+value_w SMALLINT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Scalar Enum ReadWrite Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devenum_ro
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r SMALLINT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Enum ReadOnly Values Table';
+
+CREATE TABLE IF NOT EXISTS att_array_devenum_rw
+(
+att_conf_id INT UNSIGNED NOT NULL,
+data_time TIMESTAMP(6) DEFAULT 0,
+recv_time TIMESTAMP(6) DEFAULT 0,
+insert_time TIMESTAMP(6) DEFAULT 0,
+idx INT UNSIGNED NOT NULL,
+dim_x_r INT UNSIGNED NOT NULL,
+dim_y_r INT UNSIGNED NOT NULL DEFAULT 0,
+value_r SMALLINT DEFAULT NULL,
+dim_x_w INT UNSIGNED NOT NULL,
+dim_y_w INT UNSIGNED NOT NULL DEFAULT 0,
+value_w SMALLINT DEFAULT NULL,
+quality TINYINT(1) DEFAULT NULL,
+att_error_desc_id INT UNSIGNED NULL DEFAULT NULL,
+INDEX att_conf_id_data_time (att_conf_id,data_time)
+) ENGINE=MyISAM COMMENT='Array Enum ReadWrite Values Table';
+
diff --git a/docker/tango/mariadb_hdbpp/resources/my.cnf b/docker/tango/mariadb_hdbpp/resources/my.cnf
new file mode 100644
index 0000000000000000000000000000000000000000..17db69caed53bebbd8b0caf7213aa8d7dd177033
--- /dev/null
+++ b/docker/tango/mariadb_hdbpp/resources/my.cnf
@@ -0,0 +1,9 @@
+# The MariaDB configuration file
+
+[mysqld]
+sql-mode=""
+innodb=OFF
+default_storage_engine=MyISAM
+log_error=/var/lib/mysql/error.log
+general_log_file=/var/lib/mysql/mysql.log
+general_log=1
\ No newline at end of file
diff --git a/docker/tango/ska-python-buildenv/.release b/docker/tango/ska-python-buildenv/.release
new file mode 100644
index 0000000000000000000000000000000000000000..8d32013e0320128441ab507cbf10f8e0a535af64
--- /dev/null
+++ b/docker/tango/ska-python-buildenv/.release
@@ -0,0 +1,2 @@
+release=9.3.2.1
+tag=ska-python-buildenv-9.3.2.1
diff --git a/docker/tango/ska-python-buildenv/Dockerfile b/docker/tango/ska-python-buildenv/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..71d06eb8854e9b14780db6f594ace6db82ee387e
--- /dev/null
+++ b/docker/tango/ska-python-buildenv/Dockerfile
@@ -0,0 +1,54 @@
+#
+# This Dockerfile creates a Docker image containing a build environment for SKA
+# python projects. This image is intended to be used as an intermediate layer,
+# where it can be used to compile C extensions to be copied into a final
+# release image.
+#
+# This image caches a compilation of PyTango bindings so that child images
+# need not recompile it.
+#
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-cpp:latest
+
+USER root
+
+# Speed up image builds by adding apt proxy if detected on host
+RUN DOCKERHOST=`awk '/^[a-z]+[0-9]+\t00000000/ { printf("%d.%d.%d.%d", "0x" substr($3, 7, 2), "0x" substr($3, 5, 2), "0x" substr($3, 3, 2), "0x" substr($3, 1, 2)) }' < /proc/net/route` \
+    && /usr/local/bin/wait-for-it.sh --host=$DOCKERHOST --port=3142 --timeout=3 --strict --quiet -- echo "Acquire::http::Proxy \"http://$DOCKERHOST:3142\";" > /etc/apt/apt.conf.d/30proxy \
+    && echo "Proxy detected on docker host - using for this build" || echo "No proxy detected on docker host"
+
+# Install build dependencies:
+#
+# * build-essential installs C/C++ compilers and build tools
+# * libboost-python-dev is required to bind PyTango to the C++ Tango libs
+# * pkg-config is used to locate required libraries
+# * git is required for Python packages using katversion for release info
+#
+RUN buildDeps='build-essential \
+               libboost-python-dev \
+               pkg-config \
+               python3-distutils \
+               python3-pip \
+               zlib1g-dev \
+               curl \
+               git' \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && apt-get -y install --no-install-recommends $buildDeps
+
+RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python3 get-pip.py
+COPY pip.conf /etc/pip.conf
+
+RUN python3 -m pip install setuptools \
+    wheel
+
+WORKDIR /app
+
+# Install numpy manually before PyTango and other requirements to ensure we
+# build PyTango with numpy support.
+RUN python3 -m pip install numpy==1.17.2
+
+COPY requirements.txt /requirements.txt
+RUN python3 -m pip install -r /requirements.txt
+
+RUN mkdir /venv && ln -s /usr/* /venv/  && ln -s /usr/local/bin/itango3 /venv/bin/itango3
diff --git a/docker/tango/ska-python-buildenv/Makefile b/docker/tango/ska-python-buildenv/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..20b277ec456a7565ad8e46c1f0bb20d17a4cd0dd
--- /dev/null
+++ b/docker/tango/ska-python-buildenv/Makefile
@@ -0,0 +1,64 @@
+include ../../make/Makefile
+
+# name of the Docker volume used to cache eggs and wheels
+CACHE_VOLUME = ska-python-buildenv-test-cache
+
+# optional docker run-time arguments
+DOCKER_RUN_ARGS =
+
+# defines the image to test
+IMAGE_TO_TEST = $(DOCKER_REGISTRY_HOST)/$(DOCKER_REGISTRY_USER)/ska-python-buildenv:latest
+
+# docker-compose commmand for a composition of services for the tango database,
+# databaseds device, and tangotest devices
+DOCKER_COMPOSE_COMMAND = PWD=$(CURDIR) \
+						 DOCKER_REGISTRY_HOST=$(DOCKER_REGISTRY_HOST) \
+						 DOCKER_REGISTRY_USER=$(DOCKER_REGISTRY_USER) \
+						 docker-compose \
+						 -f docker-compose.yml
+
+# defines a function to copy the ./test directory into the container and
+# then runs the requested make target in the container. The container is:
+#   1. attached to the network of the docker-compose test system
+#   2. uses a persistent volume to cache Python eggs and wheels so that fewer
+#      downloads are required
+#   3. uses a transient volume as a working directory, in which untarred files
+#      and test output can be written in the container and subsequently copied
+#      to the host
+make = tar -c test/ | \
+	   docker run -i --rm --network=$(notdir $(CURDIR))_default \
+	   -v $(CACHE_VOLUME):/home/tango/.cache \
+	   -v /build -w /build $(DOCKER_RUN_ARGS) $(IMAGE_TO_TEST) \
+	   bash -c "sudo chown tango /build /home/tango/.cache && \
+	   tar x --strip-components 1 --warning=all && \
+	   make TANGO_HOST=databaseds:10000 $1"
+
+all: test
+
+test: DOCKER_RUN_ARGS = --volumes-from=$(BUILD)
+test:
+	$(INIT_CACHE)
+	$(DOCKER_COMPOSE_COMMAND) up -d
+	$(call make,test); \
+	  status=$$?; \
+	  docker rm -f -v $(BUILD); \
+	  $(DOCKER_COMPOSE_COMMAND) down; \
+	  exit $$status
+
+piplock: ## overwrite Pipfile.lock with the image version
+	docker run $(IMAGE_TO_TEST) cat /app/Pipfile.lock > $(CURDIR)/Pipfile.lock
+
+# insert the line below after 'status=$$?;' to copy output from the test run
+# inside the container into ./build on the host.
+#	  docker cp $(BUILD):/build .; \
+
+.PHONY: all test
+
+# Creates Docker volume for use as a cache, if it doesn't exist already
+INIT_CACHE = \
+	docker volume ls | grep $(CACHE_VOLUME) || \
+	docker create --name $(CACHE_VOLUME) -v $(CACHE_VOLUME):/cache $(IMAGE_TO_TEST)
+
+# http://cakoose.com/wiki/gnu_make_thunks
+BUILD_GEN = $(shell docker create -v /build $(IMAGE_TO_TEST))
+BUILD = $(eval BUILD := $(BUILD_GEN))$(BUILD)
\ No newline at end of file
diff --git a/docker/tango/ska-python-buildenv/docker-compose.yml b/docker/tango/ska-python-buildenv/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..815f0352200ec77036d8b425de23d367a6c8dcd8
--- /dev/null
+++ b/docker/tango/ska-python-buildenv/docker-compose.yml
@@ -0,0 +1,56 @@
+#
+# Docker compose file for TANGO database and database device server
+#
+# Defines:
+#   - tangodb: MariaDB database with TANGO schema
+#   - databaseds: TANGO database device server
+#
+# Requires:
+#   - None
+#
+version: '2'
+
+services:
+  tangodb:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-db:latest
+    environment:
+    - MYSQL_ROOT_PASSWORD=secret
+    - MYSQL_DATABASE=tango
+    - MYSQL_USER=tango
+    - MYSQL_PASSWORD=tango
+
+  databaseds:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-cpp:latest
+    depends_on:
+    - tangodb
+    environment:
+    - MYSQL_HOST=tangodb:3306
+    - MYSQL_DATABASE=tango
+    - MYSQL_USER=tango
+    - MYSQL_PASSWORD=tango
+    - TANGO_HOST=databaseds:10000
+    entrypoint:
+    - /usr/local/bin/wait-for-it.sh
+    - tangodb:3306
+    - --timeout=30
+    - --strict
+    - --
+    - /usr/local/bin/DataBaseds
+    - "2"
+    - -ORBendPoint
+    - giop:tcp::10000
+
+  tangotest:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-java:latest
+    depends_on:
+    - databaseds
+    environment:
+    - TANGO_HOST=databaseds:10000
+    entrypoint:
+    - /usr/local/bin/wait-for-it.sh
+    - databaseds:10000
+    - --timeout=30
+    - --strict
+    - --
+    - /usr/local/bin/TangoTest
+    - test
diff --git a/docker/tango/ska-python-buildenv/pip.conf b/docker/tango/ska-python-buildenv/pip.conf
new file mode 100644
index 0000000000000000000000000000000000000000..41d1dce5e2cce9176483b21e87ebf2c1cf5f1f6c
--- /dev/null
+++ b/docker/tango/ska-python-buildenv/pip.conf
@@ -0,0 +1,4 @@
+[global]
+index-url = https://nexus.engageska-portugal.pt/repository/pypi/simple
+extra-index-url = https://pypi.org/simple
+disable-pip-version-check = True
diff --git a/docker/tango/ska-python-buildenv/requirements.txt b/docker/tango/ska-python-buildenv/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c37044961f3fda500d476ca768aac90713a64a77
--- /dev/null
+++ b/docker/tango/ska-python-buildenv/requirements.txt
@@ -0,0 +1,29 @@
+numpy==1.17.2
+pytango==9.3.2
+flake8
+flake8_formatter_junit_xml
+itango
+coverage
+docutils
+MarkupSafe
+Pygments
+pylint
+pytest
+pytest-bdd
+pytest-cov
+pytest-forked
+pytest-json-report
+pytest-mock
+pytest-pycodestyle
+pytest-pydocstyle
+pytest-pylint
+pytest-runner
+python-dotenv>=0.5.1
+ptvsd
+Sphinx
+sphinx_rtd_theme
+sphinx-autobuild
+sphinxcontrib-websupport
+requests
+tox
+transitions
diff --git a/docker/tango/ska-python-buildenv/test.sh b/docker/tango/ska-python-buildenv/test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d3cd68c4c8faac4c2a2dfd31cf8fe53dad1e654c
--- /dev/null
+++ b/docker/tango/ska-python-buildenv/test.sh
@@ -0,0 +1,118 @@
+#!/bin/bash
+#
+#   Copyright 2015  Xebia Nederland B.V.
+#   Modifications copyright (c) 2019 SKA Organisation
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+function hasChanges() {
+	test -n "$(git status -s .)"
+}
+
+function getRelease() {
+	awk -F= '/^release=/{print $2}' .release
+}
+
+function getBaseTag() {
+		sed -n -e "s/^tag=\(.*\)$(getRelease)\$/\1/p" .release
+}
+
+function getTag() {
+	if [ -z "$1" ] ; then
+		awk -F= '/^tag/{print $2}' .release
+	else
+		echo "$(getBaseTag)$1"
+	fi
+}
+
+function setRelease() {
+	if [ -n "$1" ] ; then
+		sed -i.x -e "s/^tag=.*/tag=$(getTag $1)/" .release
+		sed -i.x -e "s/^release=.*/release=$1/g" .release
+		rm -f .release.x
+		runPreTagCommand "$1"
+	else
+		echo "ERROR: missing release version parameter " >&2
+		return 1
+	fi
+}
+
+function runPreTagCommand() {
+	if [ -n "$1" ] ; then
+		COMMAND=$(sed -n -e "s/@@RELEASE@@/$1/g" -e 's/^pre_tag_command=\(.*\)/\1/p' .release)
+		if [ -n "$COMMAND" ] ; then
+			if ! OUTPUT=$(bash -c "$COMMAND" 2>&1) ; then echo $OUTPUT >&2 && exit 1 ; fi
+		fi
+	else
+		echo "ERROR: missing release version parameter " >&2
+		return 1
+	fi
+}
+
+
+function tagExists() {
+	tag=${1:-$(getTag)}
+	test -n "$tag" && test -n "$(git tag | grep "^$tag\$")"
+}
+
+# option -n True if string is not empty.
+function differsFromRelease() {
+	tag=$(getTag)
+	! tagExists $tag || test -n "$(git diff --shortstat -r $tag .)"
+}
+
+function getVersion() {
+	result=$(getRelease)
+
+	if differsFromRelease; then
+		result="$result-$(git log -n 1 --format=%h .)"
+	fi
+
+	if hasChanges ; then
+		result="$result-dirty"
+	fi
+	echo $result
+}
+
+function nextPatchLevel() {
+	version=${1:-$(getRelease)}
+	major_and_minor=$(echo $version | cut -d. -f1,2)
+	patch=$(echo $version | cut -d. -f3)
+	version=$(printf "%s.%d" $major_and_minor $(($patch + 1)))
+	echo $version
+}
+
+function nextMinorLevel() {
+	version=${1:-$(getRelease)}
+	major=$(echo $version | cut -d. -f1);
+	minor=$(echo $version | cut -d. -f2);
+	version=$(printf "%d.%d.0" $major $(($minor + 1))) ;
+	echo $version
+}
+
+function nextMajorLevel() {
+	version=${1:-$(getRelease)}
+	major=$(echo $version | cut -d. -f1);
+	version=$(printf "%d.0.0" $(($major + 1)))
+	echo $version
+}
+
+
+echo getVersion=$(getVersion)
+echo getTag=$(getTag)
+echo differsFromRelease=$(differsFromRelease)
+echo tagExists=$(tagExists)
+echo test=$(test -n "$(git diff --shortstat -r $getTag .)")
+echo "$(getBaseTag)$1"
+
+echo $(git diff --shortstat -r $tag .)
\ No newline at end of file
diff --git a/docker/tango/ska-python-buildenv/test/Makefile b/docker/tango/ska-python-buildenv/test/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..3e8a2bbc0d987fb95e21676d1fcfe37eee01184e
--- /dev/null
+++ b/docker/tango/ska-python-buildenv/test/Makefile
@@ -0,0 +1,11 @@
+all: test
+
+test:
+    # It takes several seconds for the Tango database to be populated from
+    # scratch, so pause until DB is created and the device we test against is
+    # responsive. If the Tango DB volume already exists, there'll be no delay
+    # at all and the test will run immediately.
+	retry -- tango_admin --check-device sys/tg_test/1
+	pytest SimpleTest.py
+
+.PHONY: all test
diff --git a/docker/tango/ska-python-buildenv/test/SimpleTest.py b/docker/tango/ska-python-buildenv/test/SimpleTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..821f23b6443d18b0d9ad4ff0ca4b746b86858d37
--- /dev/null
+++ b/docker/tango/ska-python-buildenv/test/SimpleTest.py
@@ -0,0 +1,6 @@
+import tango
+
+
+def test_test_device_is_running():
+    tango_test = tango.DeviceProxy("sys/tg_test/1")
+    assert tango_test.state() == tango.DevState.RUNNING
diff --git a/docker/tango/ska-python-runtime/.release b/docker/tango/ska-python-runtime/.release
new file mode 100644
index 0000000000000000000000000000000000000000..2c9e0cc2552ba51cb740c684a27ee53dd76f6614
--- /dev/null
+++ b/docker/tango/ska-python-runtime/.release
@@ -0,0 +1,2 @@
+release=9.3.2.1
+tag=ska-python-runtime-9.3.2.1
diff --git a/docker/tango/ska-python-runtime/Dockerfile b/docker/tango/ska-python-runtime/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..dbc9186f0fdd432654fe386f7db1bb1f2024c28a
--- /dev/null
+++ b/docker/tango/ska-python-runtime/Dockerfile
@@ -0,0 +1,47 @@
+#
+# This Dockerfile creates a Docker image intended to be a base runtime for SKA
+# python projects. This image should be used as an intermediate layer
+# alongside the ska-python-buildenv image.
+#
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/ska-python-buildenv:latest as buildenv
+
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-cpp:latest
+USER root
+
+# Permanently install Python and PyTango runtime dependencies:
+#
+# * libboost-python is required by PyTango;
+# * make is required to manage execution of the tests inside the container
+# * python3 is required as this image is intended for running Python Tango
+#   devices.
+#
+RUN runtimeDeps='libboost-python1.67.0 \
+		ca-certificates \
+		make \
+		curl \
+		python3 \
+		python3-distutils' \
+    && DOCKERHOST=`awk '/^[a-z]+[0-9]+\t00000000/ { printf("%d.%d.%d.%d", "0x" substr($3, 7, 2), "0x" substr($3, 5, 2), "0x" substr($3, 3, 2), "0x" substr($3, 1, 2)) }' < /proc/net/route` \
+    && /usr/local/bin/wait-for-it.sh --host=$DOCKERHOST --port=3142 --timeout=3 --strict --quiet -- echo "Acquire::http::Proxy \"http://$DOCKERHOST:3142\";" > /etc/apt/apt.conf.d/30proxy \
+    && echo "Proxy detected on docker host - using for this build" || echo "No proxy detected on docker host" \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && apt-get -y install --no-install-recommends $runtimeDeps \
+    && rm -rf /var/lib/apt/lists/* /etc/apt/apt.conf.d/30proxy
+
+
+COPY --from=buildenv /usr/local/lib/python3.7 /usr/local/lib/python3.7
+
+RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python3 get-pip.py
+COPY pip.conf /etc/pip.conf
+
+RUN mkdir /venv && ln -s /usr/* /venv/ && ln -s /usr/bin/python3 /venv/bin/python && ln -s /usr/local/bin/itango3 /venv/bin/itango3
+
+USER tango
+
+ENV PATH="/home/tango/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH}"
+
+ONBUILD COPY --chown=tango:tango . /app
+ONBUILD COPY --from=buildenv /usr/local/bin/ /usr/local/bin/
+ONBUILD WORKDIR /app
diff --git a/docker/tango/ska-python-runtime/Makefile b/docker/tango/ska-python-runtime/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/ska-python-runtime/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/ska-python-runtime/pip.conf b/docker/tango/ska-python-runtime/pip.conf
new file mode 100644
index 0000000000000000000000000000000000000000..41d1dce5e2cce9176483b21e87ebf2c1cf5f1f6c
--- /dev/null
+++ b/docker/tango/ska-python-runtime/pip.conf
@@ -0,0 +1,4 @@
+[global]
+index-url = https://nexus.engageska-portugal.pt/repository/pypi/simple
+extra-index-url = https://pypi.org/simple
+disable-pip-version-check = True
diff --git a/docker/tango/tango-admin/.release b/docker/tango/tango-admin/.release
new file mode 100644
index 0000000000000000000000000000000000000000..961459685995eddf0c4747930e798b6c69339686
--- /dev/null
+++ b/docker/tango/tango-admin/.release
@@ -0,0 +1,2 @@
+release=1.15.0.1
+tag=tango-admin-1.15.0.1
diff --git a/docker/tango/tango-admin/Dockerfile b/docker/tango/tango-admin/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..493e7c1a3e5071280f8707a1969bf0cb534c37d6
--- /dev/null
+++ b/docker/tango/tango-admin/Dockerfile
@@ -0,0 +1,7 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-libtango:latest
+
+ENTRYPOINT ["/usr/local/bin/tango_admin"]
+
+
diff --git a/docker/tango/tango-admin/Makefile b/docker/tango/tango-admin/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-admin/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-archiver/.release b/docker/tango/tango-archiver/.release
new file mode 100644
index 0000000000000000000000000000000000000000..b022c1dce3b03ffb12f3c709a12b161c73aee8e4
--- /dev/null
+++ b/docker/tango/tango-archiver/.release
@@ -0,0 +1,2 @@
+release=1.0.0.2
+tag=tango-archiver-1.0.0.2
diff --git a/docker/tango/tango-archiver/Dockerfile b/docker/tango/tango-archiver/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..1a71c9a49affdb3784c1ba6dd3d8742d82906345
--- /dev/null
+++ b/docker/tango/tango-archiver/Dockerfile
@@ -0,0 +1,147 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-cpp:latest
+
+USER root
+
+RUN apt-get update && \
+    apt-get install -y ca-certificates
+
+RUN echo "deb http://deb.debian.org/debian buster-backports main contrib non-free" >> /etc/apt/sources.list && \
+    more /etc/apt/sources.list && \
+    apt-get update && \
+    apt-get install -y \
+        checkinstall \
+        git \
+        cmake \
+        make \
+        g++ \
+        libomniorb4-dev \
+        libzmq3-dev \
+        libcos4-dev \
+        mariadb-server \
+        libmariadb-dev-compat libmariadb-dev \
+        libmariadbclient-dev 
+
+RUN git clone -b v1.0.0 --depth 1 https://github.com/tango-controls-hdbpp/libhdbpp.git
+
+RUN cd libhdbpp \
+ && mkdir build \
+ && cd build \
+ && cmake .. -DHDBPP_DEV_INSTALL=ON -DCMAKE_INCLUDE_PATH=/usr/local/include/tango \
+ && make -j4
+
+RUN cd libhdbpp/build \
+ && checkinstall \
+    --install=yes \
+    --fstrans=no \
+    --showinstall=no \
+    --backup=no \
+    --type=debian \
+    --pkgsource="https://github.com/tango-controls-hdbpp/libhdbpp" \
+    --pkglicense="LGPLv3" \
+    --deldesc=no \
+    --nodoc \
+    --strip \
+    --stripso \
+    --maintainer="tango" \
+    --pkgarch=$(dpkg --print-architecture) \
+    --pkgversion="1.0.0" \
+    --pkgrelease="SNAPSHOT" \
+    --pkgname="libhdbpp" \
+    --requires="libzmq5,libomniorb4-2,libcos4-2,libomnithread4" \
+    make install
+
+RUN git clone -b v1.1.0 --depth 1 https://github.com/tango-controls-hdbpp/libhdbpp-mysql.git
+
+RUN cd libhdbpp-mysql \
+ && make TANGO_INC=/usr/local/include/tango
+
+RUN cd libhdbpp-mysql \
+ && checkinstall \
+    --install=yes \
+    --fstrans=no \
+    --showinstall=no \
+    --backup=no \
+    --type=debian \
+    --pkgsource="https://github.com/tango-controls-hdbpp/libhdbpp-mysql" \
+    --pkglicense="LGPLv3" \
+    --deldesc=no \
+    --nodoc \
+    --strip \
+    --stripso \
+    --maintainer="tango" \
+    --pkgarch=$(dpkg --print-architecture) \
+    --pkgversion="1.1.0" \
+    --pkgrelease="SNAPSHOT" \
+    --pkgname="libhdbpp-mysql" \
+    --requires="libmariadbclient-dev" \
+    make install
+
+RUN git clone -b v1.0.1 --depth 1 https://github.com/tango-controls-hdbpp/hdbpp-es.git
+
+RUN cd hdbpp-es \
+ && make TANGO_INC=/usr/local/include/tango
+
+RUN cd hdbpp-es \
+ && checkinstall \
+    --install=yes \
+    --fstrans=no \
+    --showinstall=no \
+    --backup=no \
+    --type=debian \
+    --pkgsource="https://github.com/tango-controls-hdbpp/hdbpp-es" \
+    --pkglicense="GPLv3" \
+    --deldesc=no \
+    --nodoc \
+    --strip \
+    --stripso \
+    --maintainer="tango" \
+    --pkgarch=$(dpkg --print-architecture) \
+    --pkgversion="1.0.1" \
+    --pkgrelease="SNAPSHOT" \
+    --pkgname="hdbpp-es" \
+    --requires="libzmq5,libomniorb4-2,libcos4-2,libomnithread4" \
+    make install
+
+RUN git clone -b v1.0.0 --depth 1 https://github.com/tango-controls-hdbpp/hdbpp-cm.git
+
+RUN cd hdbpp-cm \
+ && make TANGO_INC=/usr/local/include/tango
+
+RUN cd hdbpp-cm \
+ && checkinstall \
+    --install=yes \
+    --fstrans=no \
+    --showinstall=no \
+    --backup=no \
+    --type=debian \
+    --pkgsource="https://github.com/tango-controls-hdbpp/hdbpp-cm" \
+    --pkglicense="GPLv3" \
+    --deldesc=no \
+    --nodoc \
+    --strip \
+    --stripso \
+    --maintainer="tango" \
+    --pkgarch=$(dpkg --print-architecture) \
+    --pkgversion="1.0.0" \
+    --pkgrelease="SNAPSHOT" \
+    --pkgname="hdbpp-cm" \
+    --requires="libzmq5,libomniorb4-2,libcos4-2,libomnithread4" \
+    make install
+
+
+RUN apt-get update && \
+    apt-get install -y \
+    build-essential && \
+    apt-get clean
+
+RUN dpkg -i /libhdbpp/build/libhdbpp_1.0.0-SNAPSHOT_amd64.deb
+RUN dpkg -i /libhdbpp-mysql/libhdbpp-mysql_1.1.0-SNAPSHOT_amd64.deb
+RUN dpkg -i /hdbpp-es/hdbpp-es_1.0.1-SNAPSHOT_amd64.deb
+RUN dpkg -i /hdbpp-cm/hdbpp-cm_1.0.0-SNAPSHOT_amd64.deb
+
+RUN ldconfig
+
+RUN mv /usr/local/bin/hdb++cm-srv /usr/local/bin/hdbppcm-srv
+RUN mv /usr/local/bin/hdb++es-srv /usr/local/bin/hdbppes-srv
diff --git a/docker/tango/tango-archiver/Makefile b/docker/tango/tango-archiver/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..4b329d951b639e1619b6c5c5857c82a14f3358b8
--- /dev/null
+++ b/docker/tango/tango-archiver/Makefile
@@ -0,0 +1,85 @@
+include ../../make/Makefile
+
+# name of the Docker volume used to cache eggs and wheels
+CACHE_VOLUME = tango-archiver-test-cache
+
+# defines the image to test
+IMAGE_TO_TEST = $(DOCKER_REGISTRY_HOST)/$(DOCKER_REGISTRY_USER)/tango-itango:latest
+
+THIS_HOST := $(shell ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' | head -n1)
+
+ifneq ($(CI_JOB_ID),)
+NETWORK_MODE := tangonet-$(CI_JOB_ID)
+CONTAINER_NAME_PREFIX := $(CI_JOB_ID)-
+else
+# ********
+# Patch Matteo 20/02/2020 network mode cannot be host in this case. 
+# For enabling the host network, it is necessary to template the archiver-devices.json configuration file.
+NETWORK_MODE := tangonet-local
+CONTAINER_NAME_PREFIX := local-
+# ********
+endif
+
+#
+# When running in network=host mode, point devices at a port on the host
+# machine rather than at the container.
+#
+ifeq ($(OS),Windows_NT)
+    $(error Sorry, Windows is not supported yet)
+else
+	UNAME_S := $(shell uname -s)
+	ifeq ($(UNAME_S),Linux)
+		DISPLAY ?= :0.0
+		NETWORK_MODE ?= host
+		XAUTHORITY_MOUNT := /tmp/.X11-unix:/tmp/.X11-unix
+		XAUTHORITY ?= /hosthome/.Xauthority
+		# /bin/sh (=dash) does not evaluate 'docker network' conditionals correctly
+		SHELL := /bin/bash
+	endif
+	ifeq ($(UNAME_S),Darwin)
+		IF_INTERFACE := $(shell scutil --nwi | grep 'Network interfaces:' | cut -d' ' -f3)
+		DISPLAY := $(shell scutil --nwi | grep 'address' | cut -d':' -f2 | tr -d ' ' | head -n1):0
+		# network_mode = host doesn't work on MacOS, so fix to the internal network
+		NETWORK_MODE ?= tangonet
+		XAUTHORITY_MOUNT := $(HOME)/.Xauthority:/hosthome/.Xauthority:ro
+		XAUTHORITY := /hosthome/.Xauthority
+	endif
+endif
+
+#
+# When running in network=host mode, point devices at a port on the host
+# machine rather than at the container.
+#
+ifeq ($(NETWORK_MODE),host)
+	TANGO_HOST := $(shell hostname):10000
+	MYSQL_HOST := $(shell hostname):3306
+else
+	TANGO_HOST := $(CONTAINER_NAME_PREFIX)databaseds:10000
+	MYSQL_HOST := $(CONTAINER_NAME_PREFIX)tangodb:3306
+endif
+
+DOCKER_COMPOSE_ARGS := PWD=$(CURDIR) DOCKER_REGISTRY_HOST=$(DOCKER_REGISTRY_HOST) \
+		DOCKER_REGISTRY_USER=$(DOCKER_REGISTRY_USER) DISPLAY=$(DISPLAY) XAUTHORITY=$(XAUTHORITY) TANGO_HOST=$(TANGO_HOST) \
+		NETWORK_MODE=$(NETWORK_MODE) XAUTHORITY_MOUNT=$(XAUTHORITY_MOUNT) MYSQL_HOST=$(MYSQL_HOST) \
+		CONTAINER_NAME_PREFIX=$(CONTAINER_NAME_PREFIX) COMPOSE_IGNORE_ORPHANS=true
+
+make = tar -c test/ | \
+	   docker run -i --rm --network=$(NETWORK_MODE) \
+	   $(DOCKER_RUN_ARGS) $(IMAGE_TO_TEST) \
+	   bash -c "tar x --strip-components 1 --warning=all && \
+	   make TANGO_HOST=$(TANGO_HOST) $1"
+
+all: test
+
+test:
+ifneq ($(NETWORK_MODE),host)
+	docker network inspect $(NETWORK_MODE) &> /dev/null || ([ $$? -ne 0 ] && docker network create $(NETWORK_MODE))
+endif
+	$(DOCKER_COMPOSE_ARGS) docker-compose up -d
+	$(call make,test); \
+	  status=$$?; \
+	  docker-compose logs; \
+	  $(DOCKER_COMPOSE_ARGS) docker-compose down; \
+	  exit $$status
+
+.PHONY: all test
diff --git a/docker/tango/tango-archiver/README.md b/docker/tango/tango-archiver/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..21fd143aa0c9f9c680e5a4c17a2ae315abd2382b
--- /dev/null
+++ b/docker/tango/tango-archiver/README.md
@@ -0,0 +1,50 @@
+# Tango-archiver Docker Containers
+
+[![Documentation Status](https://readthedocs.org/projects/ska-docker/badge/?version=latest)](https://developer.skatelescope.org/projects/ska-docker/en/latest/?badge=latest)
+
+
+# 1: Introduction
+The EventSubscriber TANGO device server, or Archiver, is the archiving system engine. It contains mainly two components 
+Event Subscriber and Configuration Manager. It subscribes to archive events on request by the Configuration Manager 
+device and stores the configuration into the TANGO database. The EventSubscriber is designed to start archiving all 
+the already configured attributes, even if the Configuration Manager is not running. Moreover, being a TANGO device, the
+EventSubscriber configuration can be managed with Jive.
+
+Note: the version of the present docker image comes from the libhdbpp installed (1.0.0)
+
+# 2: Prerequisites - Installation
+* HDB++ library: libhdbpp
+* HDB++ mysql library: libhdbpp-mysql
+* HDB++ configuration manager: hdbpp-cm
+* HDB++ event subscriber: hdbpp-es
+* HDB++ viewer: hdbpp-viewer
+* [HDB++ Installation Manual](https://docs.google.com/document/d/1QP3pU62j1v7RWvHeX72JG3s8FqgsCg-bD74xDLP2bSY/edit#heading=h.pqr2e1svlqll) 
+* [Link to HDB++ github repository](https://github.com/tango-controls-hdbpp)
+
+# 3: Creating docker containers for archiver
+## 3.1: hdbpp-es (v1.0.1)
+hdbpp-es is a Event Suscriber device server container.
+[Link to hdbpp-es github repository](https://github.com/tango-controls-hdbpp/hdbpp-es)
+nexus.engageska-portugal.pt/ska-docker/tango-archiver image with tag 'latest' is used for creating hdbpp-es container.
+TANGO_HOST=${TANGO_HOST}, HdbManager=archiving/hdbpp/confmanager01 are the environment variables set at the time of 
+creating this container. The containers such as databaseds, archiver-dsconfig and maria-db should be up and running, 
+for the hdbpp-es container to start.
+ 
+## 3.2: hdbpp-cm (v1.0.0)
+hdbpp-cm is a Configuration manager device server container.
+[Link to hdbpp-cm github repository](https://github.com/tango-controls-hdbpp/hdbpp-cm)
+nexus.engageska-portugal.pt/ska-docker/tango-archiver image with tag 'latest' is used to create hdbpp-cm container. 
+TANGO_HOST=${TANGO_HOST}, HdbManager=archiving/hdbpp/confmanager01 are the environment variables set at the time of 
+creating this container. The containers such as databaseds, archiver-dsconfig and maria-db should be up and running,
+for the hdbpp-cm container to start.
+
+## 3.3: dsconfig
+The data file, 'archiver-devices.json' runs in this container to configure all the TMC devices properties. 
+nexus.engageska-portugal.pt/ska-docker/tango-dsconfig image with tag 'latest' is used in this container.
+TANGO_HOST=${TANGO_HOST} is the environment variable set inside this container at the time of creation.
+
+# 4: Running tango-archiver inside docker containers
+
+The tango-archiver is tested on dockers using the following command inside the ./tango-archiver
+
+`make test`
diff --git a/docker/tango/tango-archiver/data/archiver-devices.json b/docker/tango/tango-archiver/data/archiver-devices.json
new file mode 100644
index 0000000000000000000000000000000000000000..22311da6620f2b725b133f85344c3d38a615db8f
--- /dev/null
+++ b/docker/tango/tango-archiver/data/archiver-devices.json
@@ -0,0 +1,34 @@
+{
+    "servers": {
+        "hdbppes-srv": {
+            "01": {
+                "HdbEventSubscriber": {
+                    "archiving/hdbpp/eventsubscriber01": {
+                        "attribute_properties": {},
+                        "properties": {
+                            "CheckPeriodicTimeoutDelay": ["5"],
+                            "PollingThreadPeriod": ["3"],
+                            "LibConfiguration": ["host=archiver-maria-db","libname=libhdb++mysql.so.6","dbname=hdbpp","port=3306", "user=tango", "password=tango"],
+                            "polled_attr": []
+                        }
+                    }
+                }
+            }
+        },
+        "hdbppcm-srv": {
+            "01": {
+                "HdbConfigurationManager": {
+                    "archiving/hdbpp/confmanager01": {
+                        "attribute_properties": {},
+                        "properties": {
+                            "ArchiverList": ["archiving/hdbpp/eventsubscriber01"],
+                            "MaxSearchSize": ["1000"],
+                            "LibConfiguration": ["host=archiver-maria-db","libname=libhdb++mysql.so.6","dbname=hdbpp","port=3306", "user=tango", "password=tango"],
+                            "polled_attr": []
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/docker/tango/tango-archiver/docker-compose.yml b/docker/tango/tango-archiver/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3ab6f69dff0dd7d940f1e82b8f462b0bc994a58f
--- /dev/null
+++ b/docker/tango/tango-archiver/docker-compose.yml
@@ -0,0 +1,120 @@
+
+version: '2'
+
+services:
+  tangodb:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-db:latest
+    container_name: ${CONTAINER_NAME_PREFIX}tangodb
+    network_mode: ${NETWORK_MODE}
+    environment:
+    - MYSQL_ROOT_PASSWORD=secret
+    - MYSQL_DATABASE=tango
+    - MYSQL_USER=tango
+    - MYSQL_PASSWORD=tango
+    restart: on-failure
+
+  databaseds:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-cpp:latest
+    container_name: ${CONTAINER_NAME_PREFIX}databaseds
+    network_mode: ${NETWORK_MODE}
+    depends_on:
+    - tangodb
+    environment:
+    - MYSQL_HOST=${MYSQL_HOST}
+    - MYSQL_DATABASE=tango
+    - MYSQL_USER=tango
+    - MYSQL_PASSWORD=tango
+    - TANGO_HOST=${TANGO_HOST}
+    entrypoint:
+    - /usr/local/bin/wait-for-it.sh
+    - ${MYSQL_HOST}:3306
+    - --timeout=30
+    - --strict
+    - --
+    - /usr/local/bin/DataBaseds
+    - "2"
+    - -ORBendPoint
+    - giop:tcp::10000
+    restart: on-failure
+
+  maria-db:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/mariadb_hdbpp:latest
+    container_name: archiver-maria-db
+    network_mode: ${NETWORK_MODE}
+    depends_on:
+      - databaseds
+    environment:
+      - MYSQL_ROOT_PASSWORD=secret
+      - MYSQL_DATABASE=hdbpp
+      - MYSQL_HOST=archiver-maria-db:3306
+      - MYSQL_USER=tango
+      - MYSQL_PASSWORD=tango
+    restart: on-failure
+
+  hdbpp-es:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-archiver:latest
+    network_mode: ${NETWORK_MODE}
+    container_name: ${CONTAINER_NAME_PREFIX}hdbpp-es
+    depends_on:
+      - databaseds
+      - dsconfig
+      - maria-db
+    environment:
+      - TANGO_HOST=${TANGO_HOST}
+      - HdbManager=archiving/hdbpp/confmanager01
+    command: >
+      /bin/bash -c "
+        wait-for-it.sh archiver-maria-db:3306 --timeout=30 --strict --
+        wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict --
+             hdbppes-srv 01"
+    restart: on-failure
+
+  hdbpp-cm:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-archiver:latest
+    network_mode: ${NETWORK_MODE}
+    container_name: ${CONTAINER_NAME_PREFIX}hdbpp-cm
+    depends_on:
+      - databaseds
+      - dsconfig
+      - maria-db
+    environment:
+      - TANGO_HOST=${TANGO_HOST}
+      - HdbManager=archiving/hdbpp/confmanager01
+    command: >
+      /bin/bash -c "
+        wait-for-it.sh archiver-maria-db:3306 --timeout=30 --strict --
+        wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict --
+             hdbppcm-srv 01"
+    restart: on-failure
+
+  dsconfig:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-dsconfig:latest
+    container_name: ${CONTAINER_NAME_PREFIX}dsconfig
+    network_mode: ${NETWORK_MODE}
+    depends_on:
+      - databaseds
+    environment:
+      - TANGO_HOST=${TANGO_HOST}
+    command: >
+      sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict --
+             json2tango -w -a -u /tango-archiver/data/archiver-devices.json &&
+             sleep infinity"
+    volumes:
+      - .:/tango-archiver
+    restart: on-failure
+
+  tangotest:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-java:latest
+    container_name: ${CONTAINER_NAME_PREFIX}tangotest
+    network_mode: ${NETWORK_MODE}
+    environment:
+      - TANGO_HOST=${TANGO_HOST}
+    entrypoint:
+      - /usr/local/bin/wait-for-it.sh
+      - ${TANGO_HOST}
+      - --timeout=30
+      - --strict
+      - --
+      - /usr/local/bin/TangoTest
+      - test
+    restart: on-failure
diff --git a/docker/tango/tango-archiver/test/Makefile b/docker/tango/tango-archiver/test/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9c29d6a1762c0ae9aa8d9e1ac32caf4c46bba1b1
--- /dev/null
+++ b/docker/tango/tango-archiver/test/Makefile
@@ -0,0 +1,10 @@
+SHELL = /bin/bash
+.SHELLFLAGS = -o pipefail -c
+
+all: test
+
+test:
+	retry --max=10 -- tango_admin --ping-device archiving/hdbpp/eventsubscriber01 && \
+	pytest SimpleTest.py
+
+.PHONY: all test
diff --git a/docker/tango/tango-archiver/test/SimpleTest.py b/docker/tango/tango-archiver/test/SimpleTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b58a985496b03af0867bc716101841febb027a0
--- /dev/null
+++ b/docker/tango/tango-archiver/test/SimpleTest.py
@@ -0,0 +1,71 @@
+import tango
+from tango import DevFailed, DeviceProxy, GreenMode, AttributeProxy
+import time
+from time import sleep
+import pytest
+import logging
+
+def test_cm_device_is_ON():
+    tango_test = tango.DeviceProxy("archiving/hdbpp/confmanager01")
+    time.sleep(2)
+    assert tango_test.state() == tango.DevState.ON
+
+def test_es_device_is_ON():
+    tango_test = tango.DeviceProxy("archiving/hdbpp/eventsubscriber01")
+    time.sleep(2)
+    assert tango_test.state() == tango.DevState.ON
+
+def test_archiving():
+  evt_subscriber_device_fqdn = "archiving/hdbpp/eventsubscriber01"
+  config_manager_device_fqdn = "archiving/hdbpp/confmanager01"
+  conf_manager_proxy = DeviceProxy(config_manager_device_fqdn)
+  evt_subscriber_device_proxy = DeviceProxy(evt_subscriber_device_fqdn)
+
+  conf_manager_proxy.set_timeout_millis(5000)
+  evt_subscriber_device_proxy.set_timeout_millis(5000)
+
+  attribute = "sys/tg_test/1/double_scalar"
+
+  # wait for the attribute to be online. 
+  max_retries = 10
+  sleep_time = 30
+  for x in range(0, max_retries):
+      try:
+        att = AttributeProxy(attribute)
+        att.read()
+        break
+      except DevFailed as df:
+        if(x == (max_retries -1)):
+          raise df
+        logging.info("DevFailed exception: " + str(df.args[0].reason) + ". Sleeping for " + str(sleep_time) + "ss")
+        sleep(sleep_time)
+
+  conf_manager_proxy.write_attribute("SetAttributeName", attribute)
+  conf_manager_proxy.write_attribute("SetArchiver", evt_subscriber_device_fqdn)
+  conf_manager_proxy.write_attribute("SetStrategy", "ALWAYS")
+  conf_manager_proxy.write_attribute("SetPollingPeriod", 1000)
+  conf_manager_proxy.write_attribute("SetPeriodEvent", 3000)
+
+  try:
+    conf_manager_proxy.command_inout("AttributeAdd")
+  except DevFailed as df:
+    if not str(df.args[0].reason) == 'Already archived':    
+      logging.info("DevFailed exception: " + str(df.args[0].reason))
+
+  evt_subscriber_device_proxy.Start()
+
+  max_retries = 10
+  sleep_time = 1
+  for x in range(0, max_retries):
+    try:
+      # Check status of Attribute Archiving in Configuration Manager
+      result_config_manager = conf_manager_proxy.command_inout("AttributeStatus", attribute)
+      # Check status of Attribute Archiving in Event Subscriber
+      result_evt_subscriber = evt_subscriber_device_proxy.command_inout("AttributeStatus", attribute)
+      assert "Archiving          : Started" in result_config_manager
+      assert "Archiving          : Started" in result_evt_subscriber
+    except DevFailed as df:
+      if(x == (max_retries -1)):
+        raise df
+      logging.info("DevFailed exception: " + str(df.args[0].reason) + ". Sleeping for " + str(sleep_time) + "ss")
+      sleep(sleep_time)
diff --git a/docker/tango/tango-builder/.release b/docker/tango/tango-builder/.release
new file mode 100644
index 0000000000000000000000000000000000000000..69450113351ba3bf24cd67e3afa17c071b6c8742
--- /dev/null
+++ b/docker/tango/tango-builder/.release
@@ -0,0 +1,2 @@
+release=0.2.3
+tag=tango-builder-0.2.3
diff --git a/docker/tango/tango-builder/Dockerfile b/docker/tango/tango-builder/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..c10f83f422f114d5d5721b964b7d89acc20254b7
--- /dev/null
+++ b/docker/tango/tango-builder/Dockerfile
@@ -0,0 +1,17 @@
+FROM ubuntu:18.04
+
+ENV DEBIAN_FRONTEND="noninteractive"
+RUN apt-get update && apt-get install -y make bash git curl apt-transport-https ca-certificates curl software-properties-common
+RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
+RUN apt-key fingerprint 0EBFCD88
+RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
+RUN apt-get update && apt-get install -y docker-ce
+RUN export LC_ALL=C
+# pip
+RUN apt-get update && apt-get install -yq python3-distutils \
+    && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
+    && python3 get-pip.py
+COPY pip.conf /etc/pip.conf
+# /pip
+RUN python3 -m pip install docker-compose
+RUN python3 -m pip install pytest
diff --git a/docker/tango/tango-builder/Makefile b/docker/tango/tango-builder/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-builder/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-builder/pip.conf b/docker/tango/tango-builder/pip.conf
new file mode 100644
index 0000000000000000000000000000000000000000..41d1dce5e2cce9176483b21e87ebf2c1cf5f1f6c
--- /dev/null
+++ b/docker/tango/tango-builder/pip.conf
@@ -0,0 +1,4 @@
+[global]
+index-url = https://nexus.engageska-portugal.pt/repository/pypi/simple
+extra-index-url = https://pypi.org/simple
+disable-pip-version-check = True
diff --git a/docker/tango/tango-cpp/.release b/docker/tango/tango-cpp/.release
new file mode 100644
index 0000000000000000000000000000000000000000..ec7016a52056edd68b985232ea39502c367b1350
--- /dev/null
+++ b/docker/tango/tango-cpp/.release
@@ -0,0 +1,2 @@
+release=9.3.4-rc7
+tag=tango-cpp-9.3.4-rc7
diff --git a/docker/tango/tango-cpp/Dockerfile b/docker/tango/tango-cpp/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..ef07fc9c4bba0d205d85e2a11683fdd5a377d6fa
--- /dev/null
+++ b/docker/tango/tango-cpp/Dockerfile
@@ -0,0 +1,47 @@
+#
+# This Dockerfile builds base Tango (C++ only, no Java or Python) in an
+# intermediate image, then creates a release image containing the compiled
+# binaries.
+#
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-dependencies:latest as buildenv
+
+RUN TANGO_DOWNLOAD_URL=https://nexus.engageska-portugal.pt/repository/raw/tango-cs/tango-9.3.4-rc7.tar.gz \
+    # Speed up image builds by adding apt proxy if detected on host
+    && DOCKERHOST=`awk '/^[a-z]+[0-9]+\t00000000/ { printf("%d.%d.%d.%d", "0x" substr($3, 7, 2), "0x" substr($3, 5, 2), "0x" substr($3, 3, 2), "0x" substr($3, 1, 2)) }' < /proc/net/route` \
+    && /usr/local/bin/wait-for-it.sh --host=$DOCKERHOST --port=3142 --timeout=3 --strict --quiet -- echo "Acquire::http::Proxy \"http://$DOCKERHOST:3142\";" > /etc/apt/apt.conf.d/30proxy \
+    && echo "Proxy detected on docker host - using for this build" || echo "No proxy detected on docker host" \
+    && buildDeps='build-essential ca-certificates curl file libmariadbclient-dev libmariadbclient-dev-compat pkg-config python' \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends $buildDeps \
+    && rm -rf /var/lib/apt/lists/* \
+    && mkdir -p /usr/src/tango \
+    && cd /usr/src/tango \
+    && curl -fsSL "$TANGO_DOWNLOAD_URL" -o tango.tar.gz \
+    && tar xf tango.tar.gz -C /usr/src/tango --strip-components=1 \
+    && ./configure --with-zmq=/usr/local --with-omni=/usr/local --with-mysqlclient-prefix=/usr --enable-static=no \
+    && make -C /usr/src/tango -j$(nproc) \
+    && make -C /usr/src/tango install \
+    && ldconfig \
+    && apt-get purge -y --auto-remove $buildDeps \
+    && rm -r /usr/src/tango
+
+FROM debian:buster-slim
+COPY --from=buildenv /usr/local /usr/local
+
+RUN runtimeDeps='libmariadb3 sudo' \
+    && DOCKERHOST=`awk '/^[a-z]+[0-9]+\t00000000/ { printf("%d.%d.%d.%d", "0x" substr($3, 7, 2), "0x" substr($3, 5, 2), "0x" substr($3, 3, 2), "0x" substr($3, 1, 2)) }' < /proc/net/route` \
+    && /usr/local/bin/wait-for-it.sh --host=$DOCKERHOST --port=3142 --timeout=3 --strict --quiet -- echo "Acquire::http::Proxy \"http://$DOCKERHOST:3142\";" > /etc/apt/apt.conf.d/30proxy \
+    && echo "Proxy detected on docker host - using for this build" || echo "No proxy detected on docker host" \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends $runtimeDeps \
+    && rm -rf /var/lib/apt/lists/* \
+    && rm -f /etc/apt/apt.conf.d/30proxy
+
+RUN useradd --create-home --home-dir /home/tango tango
+
+RUN echo "tango ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/tango \
+    && chmod 0440 /etc/sudoers.d/tango
+
+USER tango
diff --git a/docker/tango/tango-cpp/Makefile b/docker/tango/tango-cpp/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..00c5b51376efa8657f89e4853a0f3c7cf9fd49f0
--- /dev/null
+++ b/docker/tango/tango-cpp/Makefile
@@ -0,0 +1,50 @@
+include ../../make/Makefile
+
+CACHE_VOLUME = tango-cpp-test-cache
+
+IMAGE_TO_TEST = $(DOCKER_REGISTRY_HOST)/$(DOCKER_REGISTRY_USER)/tango-cpp:latest
+
+DOCKER_COMPOSE_COMMAND = PWD=$(CURDIR) \
+						 DOCKER_REGISTRY_HOST=$(DOCKER_REGISTRY_HOST) \
+						 DOCKER_REGISTRY_USER=$(DOCKER_REGISTRY_USER) \
+						 docker-compose \
+						 -f docker-compose.yml
+
+make = tar -c test/ | \
+	   ./test/wait-for-it.sh -t 30 `docker inspect -f \
+	   '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(notdir $(CURDIR))_tangodb_1`:3306 --\
+	   docker run -i --rm --network=$(notdir $(CURDIR))_default \
+	   -v `pwd`/test/:/test \
+	   -v $(CACHE_VOLUME):/home/tango/.cache \
+	   -v /build -w /build $(DOCKER_RUN_ARGS) $(IMAGE_TO_TEST) \
+	   /test/test.sh $(notdir $(CURDIR))_tangodb_1 \
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
+
+all: test
+
+test: DOCKER_RUN_ARGS = --volumes-from=$(BUILD)
+test:
+	$(INIT_CACHE)
+	$(DOCKER_COMPOSE_COMMAND) up -d
+	$(call make,test); \
+	  status=$$?; \
+	  docker rm -f -v $(BUILD); \
+	  $(DOCKER_COMPOSE_COMMAND) down; \
+	  exit $$status
+
+.PHONY: all test
+
+
+# Creates Docker volume for use as a cache, if it doesn't exist already
+INIT_CACHE = \
+	docker volume ls | grep $(CACHE_VOLUME) || \
+	docker create --name $(CACHE_VOLUME) -v $(CACHE_VOLUME):/cache $(IMAGE_TO_TEST)
+
+# http://cakoose.com/wiki/gnu_make_thunks
+BUILD_GEN = $(shell docker create -v /build $(IMAGE_TO_TEST))
+BUILD = $(eval BUILD := $(BUILD_GEN))$(BUILD)
diff --git a/docker/tango/tango-cpp/docker-compose.yml b/docker/tango/tango-cpp/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ecd08ed6df836a35da0bcadd0ce46e689ce8fd6a
--- /dev/null
+++ b/docker/tango/tango-cpp/docker-compose.yml
@@ -0,0 +1,43 @@
+#
+# Docker compose file for TANGO database and database device server
+#
+# Defines:
+#   - tangodb: MariaDB database with TANGO schema
+#
+# Requires:
+#   - None
+#
+version: '2'
+
+services:
+  tangodb:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-db:latest
+    environment:
+    - MYSQL_ROOT_PASSWORD=secret
+    - MYSQL_DATABASE=tango
+    - MYSQL_USER=tango
+    - MYSQL_PASSWORD=tango
+    restart: on-failure
+
+  databaseds:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-cpp:latest
+    depends_on:
+    - tangodb
+    environment:
+    - MYSQL_HOST=tangodb:3306
+    - MYSQL_DATABASE=tango
+    - MYSQL_USER=tango
+    - MYSQL_PASSWORD=tango
+    - TANGO_HOST=databaseds:10000
+    entrypoint:
+    - /usr/local/bin/wait-for-it.sh
+    - tangodb:3306
+    - --timeout=30
+    - --strict
+    - --
+    - /usr/local/bin/DataBaseds
+    - "2"
+    - -ORBendPoint
+    - giop:tcp::10000
+    restart: on-failure
+
diff --git a/docker/tango/tango-cpp/test/test.sh b/docker/tango/tango-cpp/test/test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..70a29a6bbdcf7b739798f0beb00a1be82532986c
--- /dev/null
+++ b/docker/tango/tango-cpp/test/test.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+export TANGO_HOST=databaseds:10000
+
+tango_admin --ping-database 20
+result=$?
+
+if [ $result -eq 0 ]
+then
+	echo "PASSED ping database"
+else
+	echo "ERROR ping database"
+	exit 1
+fi
+
+
+tango_admin --check-device sys/tg_test/1
+result=$?
+
+if [ $result -eq 0 ]
+then
+	echo "PASSED check device tg_test"
+else
+	echo "ERROR check device tg_test"
+	exit 1
+fi
+
+tango_admin --check-device sys/database/2
+result=$?
+
+if [ $result -eq 0 ]
+then
+	echo "PASSED check device database"
+else
+	echo "ERROR check device database"
+	exit 1
+fi
diff --git a/docker/tango/tango-cpp/test/wait-for-it.sh b/docker/tango/tango-cpp/test/wait-for-it.sh
new file mode 100755
index 0000000000000000000000000000000000000000..eca6c3b9c8c61aa6ce889c185c700ad094988cc2
--- /dev/null
+++ b/docker/tango/tango-cpp/test/wait-for-it.sh
@@ -0,0 +1,161 @@
+#!/usr/bin/env bash
+#   Use this script to test if a given TCP host/port are available
+
+cmdname=$(basename $0)
+
+echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
+
+usage()
+{
+    cat << USAGE >&2
+Usage:
+    $cmdname host:port [-s] [-t timeout] [-- command args]
+    -h HOST | --host=HOST       Host or IP under test
+    -p PORT | --port=PORT       TCP port under test
+                                Alternatively, you specify the host and port as host:port
+    -s | --strict               Only execute subcommand if the test succeeds
+    -q | --quiet                Don't output any status messages
+    -t TIMEOUT | --timeout=TIMEOUT
+                                Timeout in seconds, zero for no timeout
+    -- COMMAND ARGS             Execute command with args after the test finishes
+USAGE
+    exit 1
+}
+
+wait_for()
+{
+    if [[ $TIMEOUT -gt 0 ]]; then
+        echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT"
+    else
+        echoerr "$cmdname: waiting for $HOST:$PORT without a timeout"
+    fi
+    start_ts=$(date +%s)
+    while :
+    do
+        (echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1
+        result=$?
+        if [[ $result -eq 0 ]]; then
+            end_ts=$(date +%s)
+            echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds"
+            break
+        fi
+        sleep 1
+    done
+    return $result
+}
+
+wait_for_wrapper()
+{
+    # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
+    if [[ $QUIET -eq 1 ]]; then
+        timeout $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
+    else
+        timeout $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
+    fi
+    PID=$!
+    trap "kill -INT -$PID" INT
+    wait $PID
+    RESULT=$?
+    if [[ $RESULT -ne 0 ]]; then
+        echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT"
+    fi
+    return $RESULT
+}
+
+# process arguments
+while [[ $# -gt 0 ]]
+do
+    case "$1" in
+        *:* )
+        hostport=(${1//:/ })
+        HOST=${hostport[0]}
+        PORT=${hostport[1]}
+        shift 1
+        ;;
+        --child)
+        CHILD=1
+        shift 1
+        ;;
+        -q | --quiet)
+        QUIET=1
+        shift 1
+        ;;
+        -s | --strict)
+        STRICT=1
+        shift 1
+        ;;
+        -h)
+        HOST="$2"
+        if [[ $HOST == "" ]]; then break; fi
+        shift 2
+        ;;
+        --host=*)
+        HOST="${1#*=}"
+        shift 1
+        ;;
+        -p)
+        PORT="$2"
+        if [[ $PORT == "" ]]; then break; fi
+        shift 2
+        ;;
+        --port=*)
+        PORT="${1#*=}"
+        shift 1
+        ;;
+        -t)
+        TIMEOUT="$2"
+        if [[ $TIMEOUT == "" ]]; then break; fi
+        shift 2
+        ;;
+        --timeout=*)
+        TIMEOUT="${1#*=}"
+        shift 1
+        ;;
+        --)
+        shift
+        CLI="$@"
+        break
+        ;;
+        --help)
+        usage
+        ;;
+        *)
+        echoerr "Unknown argument: $1"
+        usage
+        ;;
+    esac
+done
+
+if [[ "$HOST" == "" || "$PORT" == "" ]]; then
+    echoerr "Error: you need to provide a host and port to test."
+    usage
+fi
+
+TIMEOUT=${TIMEOUT:-15}
+STRICT=${STRICT:-0}
+CHILD=${CHILD:-0}
+QUIET=${QUIET:-0}
+
+if [[ $CHILD -gt 0 ]]; then
+    wait_for
+    RESULT=$?
+    exit $RESULT
+else
+    if [[ $TIMEOUT -gt 0 ]]; then
+        wait_for_wrapper
+        RESULT=$?
+    else
+        wait_for
+        RESULT=$?
+    fi
+fi
+
+if [[ $CLI != "" ]]; then
+    if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then
+        echoerr "$cmdname: strict mode, refusing to execute subprocess"
+        exit $RESULT
+    fi
+    exec $CLI
+else
+    exit $RESULT
+fi
diff --git a/docker/tango/tango-databaseds/.release b/docker/tango/tango-databaseds/.release
new file mode 100644
index 0000000000000000000000000000000000000000..401b782cc25e48a22d17d7deddb3095d15c891fb
--- /dev/null
+++ b/docker/tango/tango-databaseds/.release
@@ -0,0 +1,2 @@
+release=5.16
+tag=tango-databaseds-5.16
diff --git a/docker/tango/tango-databaseds/Dockerfile b/docker/tango/tango-databaseds/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..c247368238e24e6ef1620e2a9918ab837c933ce6
--- /dev/null
+++ b/docker/tango/tango-databaseds/Dockerfile
@@ -0,0 +1,8 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-libtango:latest
+
+ENTRYPOINT ["/usr/local/bin/DataBaseds"]
+
+CMD ["2", "-ORBendPoint", "giop:tcp::10000"]
+
diff --git a/docker/tango/tango-databaseds/Makefile b/docker/tango/tango-databaseds/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-databaseds/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-db/.release b/docker/tango/tango-db/.release
new file mode 100644
index 0000000000000000000000000000000000000000..103994f363e5bedb3db37dbf2bee9d6558bb5b6c
--- /dev/null
+++ b/docker/tango/tango-db/.release
@@ -0,0 +1,2 @@
+release=10.4.10
+tag=tango-db-10.4.10
diff --git a/docker/tango/tango-db/Dockerfile b/docker/tango/tango-db/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..cf86046230198b4b1b3cc61357a46713b78f799d
--- /dev/null
+++ b/docker/tango/tango-db/Dockerfile
@@ -0,0 +1,27 @@
+FROM mariadb:10
+
+ENV TANGO_DOWNLOAD_URL=https://nexus.engageska-portugal.pt/repository/raw/tango-cs/tango-9.3.3-rc2.tar.gz                                                               
+
+RUN buildDeps='curl ca-certificates' \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && apt-get -y install --no-install-recommends $buildDeps \
+    && rm -rf /var/lib/apt/lists/* \
+    && mkdir -p /usr/src/tango \
+    && cd /usr/src/tango \
+    && curl -fsSL "$TANGO_DOWNLOAD_URL" -o tango.tar.gz \
+    && tar xf tango.tar.gz -C /usr/src/tango --strip-components=1 \
+    && mkdir -p dbinit/include \
+    && cp cppserver/database/create_db.sql.in dbinit/create_db.sql \
+    && cp cppserver/database/create_db_tables.sql.in dbinit/include/create_db_tables.sql \
+    && cp cppserver/database/stored_proc.sql.in dbinit/include/stored_proc.sql \
+    && sed -i "s|@TANGO_DB_NAME@|tango|g" dbinit/create_db.sql \
+    && sed -i "s|@TANGO_DB_NAME@|tango|g" dbinit/include/create_db_tables.sql \
+    && sed -i "s|@TANGO_DB_NAME@|tango|g" dbinit/include/stored_proc.sql \
+    && sed -i "s|^source create_db_tables.sql$|source /docker-entrypoint-initdb.d/include/create_db_tables.sql|g" dbinit/create_db.sql \
+    && sed -i "s|^source stored_proc.sql$|source /docker-entrypoint-initdb.d/include/stored_proc.sql|g" dbinit/create_db.sql \
+    && sed -i "/CREATE DATABASE tango;/d" dbinit/create_db.sql \
+    && cp -r dbinit/* /docker-entrypoint-initdb.d \
+    && apt-get purge -y --auto-remove $buildDeps \
+    && rm -r /usr/src/tango
+
+COPY sql_mode.cnf /etc/mysql/conf.d
diff --git a/docker/tango/tango-db/Makefile b/docker/tango/tango-db/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..7ff0e72caeecafad8c527f807b11ee6fcb1a76a0
--- /dev/null
+++ b/docker/tango/tango-db/Makefile
@@ -0,0 +1,50 @@
+include ../../make/Makefile
+
+CACHE_VOLUME = tango-db-test-cache
+
+IMAGE_TO_TEST = $(DOCKER_REGISTRY_HOST)/$(DOCKER_REGISTRY_USER)/tango-db:latest
+
+DOCKER_COMPOSE_COMMAND = PWD=$(CURDIR) \
+						 DOCKER_REGISTRY_HOST=$(DOCKER_REGISTRY_HOST) \
+						 DOCKER_REGISTRY_USER=$(DOCKER_REGISTRY_USER) \
+						 docker-compose \
+						 -f docker-compose.yml
+
+make = tar -c test/ | \
+	   ./test/wait-for-it.sh -t 30 `docker inspect -f \
+	   '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(notdir $(CURDIR))_tangodb_1`:3306 --\
+	   docker run -i --rm --network=$(notdir $(CURDIR))_default \
+	   -v `pwd`/test/:/test \
+	   -v $(CACHE_VOLUME):/home/tango/.cache \
+	   -v /build -w /build $(DOCKER_RUN_ARGS) $(IMAGE_TO_TEST) \
+	   /test/test.sh $(notdir $(CURDIR))_tangodb_1 \
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
+
+all: test
+
+test: DOCKER_RUN_ARGS = --volumes-from=$(BUILD)
+test:
+	$(INIT_CACHE)
+	$(DOCKER_COMPOSE_COMMAND) up -d
+	$(call make,test); \
+	  status=$$?; \
+	  docker rm -f -v $(BUILD); \
+	  $(DOCKER_COMPOSE_COMMAND) down; \
+	  exit $$status
+
+.PHONY: all test
+
+
+# Creates Docker volume for use as a cache, if it doesn't exist already
+INIT_CACHE = \
+	docker volume ls | grep $(CACHE_VOLUME) || \
+	docker create --name $(CACHE_VOLUME) -v $(CACHE_VOLUME):/cache $(IMAGE_TO_TEST)
+
+# http://cakoose.com/wiki/gnu_make_thunks
+BUILD_GEN = $(shell docker create -v /build $(IMAGE_TO_TEST))
+BUILD = $(eval BUILD := $(BUILD_GEN))$(BUILD)
diff --git a/docker/tango/tango-db/docker-compose.yml b/docker/tango/tango-db/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..08c73ac2413f764b6355b597b9cefa2e6d4ef2ca
--- /dev/null
+++ b/docker/tango/tango-db/docker-compose.yml
@@ -0,0 +1,21 @@
+#
+# Docker compose file for TANGO database and database device server
+#
+# Defines:
+#   - tangodb: MariaDB database with TANGO schema
+#
+# Requires:
+#   - None
+#
+version: '2'
+
+services:
+  tangodb:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-db:latest
+    environment:
+    - MYSQL_ROOT_PASSWORD=secret
+    - MYSQL_DATABASE=tango
+    - MYSQL_USER=tango
+    - MYSQL_PASSWORD=tango
+    restart: on-failure
+
diff --git a/docker/tango/tango-db/sql_mode.cnf b/docker/tango/tango-db/sql_mode.cnf
new file mode 100644
index 0000000000000000000000000000000000000000..43da6b690b0033905dae22fad8dec245a7a616a3
--- /dev/null
+++ b/docker/tango/tango-db/sql_mode.cnf
@@ -0,0 +1,4 @@
+[mysqld]
+sql-mode=""
+innodb=OFF
+default_storage_engine=MyISAM
diff --git a/docker/tango/tango-db/test/test.sh b/docker/tango/tango-db/test/test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6e8dfc397ada99a33f7baaf0476dc3a427cc7bb0
--- /dev/null
+++ b/docker/tango/tango-db/test/test.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+result=$(mysql -h $1 -u tango -ptango <<< 'show databases')
+
+if [[ $result =~ "tango" ]]
+then
+	echo "PASSED"
+else
+	echo "ERROR"
+	exit 1
+fi
diff --git a/docker/tango/tango-db/test/wait-for-it.sh b/docker/tango/tango-db/test/wait-for-it.sh
new file mode 100755
index 0000000000000000000000000000000000000000..eca6c3b9c8c61aa6ce889c185c700ad094988cc2
--- /dev/null
+++ b/docker/tango/tango-db/test/wait-for-it.sh
@@ -0,0 +1,161 @@
+#!/usr/bin/env bash
+#   Use this script to test if a given TCP host/port are available
+
+cmdname=$(basename $0)
+
+echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
+
+usage()
+{
+    cat << USAGE >&2
+Usage:
+    $cmdname host:port [-s] [-t timeout] [-- command args]
+    -h HOST | --host=HOST       Host or IP under test
+    -p PORT | --port=PORT       TCP port under test
+                                Alternatively, you specify the host and port as host:port
+    -s | --strict               Only execute subcommand if the test succeeds
+    -q | --quiet                Don't output any status messages
+    -t TIMEOUT | --timeout=TIMEOUT
+                                Timeout in seconds, zero for no timeout
+    -- COMMAND ARGS             Execute command with args after the test finishes
+USAGE
+    exit 1
+}
+
+wait_for()
+{
+    if [[ $TIMEOUT -gt 0 ]]; then
+        echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT"
+    else
+        echoerr "$cmdname: waiting for $HOST:$PORT without a timeout"
+    fi
+    start_ts=$(date +%s)
+    while :
+    do
+        (echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1
+        result=$?
+        if [[ $result -eq 0 ]]; then
+            end_ts=$(date +%s)
+            echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds"
+            break
+        fi
+        sleep 1
+    done
+    return $result
+}
+
+wait_for_wrapper()
+{
+    # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
+    if [[ $QUIET -eq 1 ]]; then
+        timeout $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
+    else
+        timeout $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
+    fi
+    PID=$!
+    trap "kill -INT -$PID" INT
+    wait $PID
+    RESULT=$?
+    if [[ $RESULT -ne 0 ]]; then
+        echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT"
+    fi
+    return $RESULT
+}
+
+# process arguments
+while [[ $# -gt 0 ]]
+do
+    case "$1" in
+        *:* )
+        hostport=(${1//:/ })
+        HOST=${hostport[0]}
+        PORT=${hostport[1]}
+        shift 1
+        ;;
+        --child)
+        CHILD=1
+        shift 1
+        ;;
+        -q | --quiet)
+        QUIET=1
+        shift 1
+        ;;
+        -s | --strict)
+        STRICT=1
+        shift 1
+        ;;
+        -h)
+        HOST="$2"
+        if [[ $HOST == "" ]]; then break; fi
+        shift 2
+        ;;
+        --host=*)
+        HOST="${1#*=}"
+        shift 1
+        ;;
+        -p)
+        PORT="$2"
+        if [[ $PORT == "" ]]; then break; fi
+        shift 2
+        ;;
+        --port=*)
+        PORT="${1#*=}"
+        shift 1
+        ;;
+        -t)
+        TIMEOUT="$2"
+        if [[ $TIMEOUT == "" ]]; then break; fi
+        shift 2
+        ;;
+        --timeout=*)
+        TIMEOUT="${1#*=}"
+        shift 1
+        ;;
+        --)
+        shift
+        CLI="$@"
+        break
+        ;;
+        --help)
+        usage
+        ;;
+        *)
+        echoerr "Unknown argument: $1"
+        usage
+        ;;
+    esac
+done
+
+if [[ "$HOST" == "" || "$PORT" == "" ]]; then
+    echoerr "Error: you need to provide a host and port to test."
+    usage
+fi
+
+TIMEOUT=${TIMEOUT:-15}
+STRICT=${STRICT:-0}
+CHILD=${CHILD:-0}
+QUIET=${QUIET:-0}
+
+if [[ $CHILD -gt 0 ]]; then
+    wait_for
+    RESULT=$?
+    exit $RESULT
+else
+    if [[ $TIMEOUT -gt 0 ]]; then
+        wait_for_wrapper
+        RESULT=$?
+    else
+        wait_for
+        RESULT=$?
+    fi
+fi
+
+if [[ $CLI != "" ]]; then
+    if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then
+        echoerr "$cmdname: strict mode, refusing to execute subprocess"
+        exit $RESULT
+    fi
+    exec $CLI
+else
+    exit $RESULT
+fi
diff --git a/docker/tango/tango-dependencies/.release b/docker/tango/tango-dependencies/.release
new file mode 100644
index 0000000000000000000000000000000000000000..af544554bbe26d7ee06b680a9fd919f0c06a893d
--- /dev/null
+++ b/docker/tango/tango-dependencies/.release
@@ -0,0 +1,2 @@
+release=9.3.3
+tag=tango-dependencies-9.3.3
diff --git a/docker/tango/tango-dependencies/Dockerfile b/docker/tango/tango-dependencies/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..0acb2b7069fb8f3d502901976399ff1a83b770f3
--- /dev/null
+++ b/docker/tango/tango-dependencies/Dockerfile
@@ -0,0 +1,66 @@
+#
+# This Dockerfile compiles Tango dependencies (ZeroMQ and OmniORB) in an
+# intermediate image, then creates a release image containing the compiled
+# binaries.
+#
+FROM debian:buster-slim as buildenv
+
+# Copy across files that are used to help orchestrate container compositions
+# and test execution sequences
+COPY wait-for-it.sh /usr/local/bin/wait-for-it.sh
+COPY retry.sh /usr/local/bin/retry
+
+RUN DOCKERHOST=`awk '/^[a-z]+[0-9]+\t00000000/ { printf("%d.%d.%d.%d", "0x" substr($3, 7, 2), "0x" substr($3, 5, 2), "0x" substr($3, 3, 2), "0x" substr($3, 1, 2)) }' < /proc/net/route` \
+    && /usr/local/bin/wait-for-it.sh --host=$DOCKERHOST --port=3142 --timeout=3 --strict --quiet -- echo "Acquire::http::Proxy \"http://$DOCKERHOST:3142\";" > /etc/apt/apt.conf.d/30proxy \
+    && echo "Proxy detected on docker host - using for this build" || echo "No proxy detected on docker host"
+
+RUN ZEROMQ_DOWNLOAD_URL=https://github.com/zeromq/libzmq/archive/v4.3.2.tar.gz \
+    && buildDeps='autoconf automake build-essential ca-certificates curl libkrb5-dev libtool pkg-config unzip' \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && apt-get -y install $buildDeps --no-install-recommends \
+    && rm -rf /var/lib/apt/lists/* \
+    && mkdir /usr/src/zeromq \
+    && cd /usr/src/zeromq \
+    && curl -kfsSL "$ZEROMQ_DOWNLOAD_URL" -o zeromq.tar.gz \
+    && tar xf zeromq.tar.gz -C /usr/src/zeromq --strip-components=1 \
+    && ./autogen.sh \
+    && ./configure --enable-static=no \
+    && make -C /usr/src/zeromq -j$(nproc) \
+    && make -C /usr/src/zeromq install \
+    && rm -r /usr/src/zeromq
+
+
+RUN CPPZMQ_DOWNLOAD_URL=https://github.com/zeromq/cppzmq/archive/v4.4.1.tar.gz \
+    && buildDeps='autoconf automake build-essential ca-certificates curl libkrb5-dev libtool pkg-config unzip cmake' \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && apt-get -y install $buildDeps --no-install-recommends \
+    && rm -rf /var/lib/apt/lists/* \
+    && mkdir /usr/src/cppzmq \
+    && cd /usr/src/cppzmq \
+    && curl -kfsSL "$CPPZMQ_DOWNLOAD_URL" -o cppzmq.tar.gz \
+    && tar xf cppzmq.tar.gz -C /usr/src/cppzmq --strip-components=1 \
+    && mkdir build \
+    && cd build \
+    && cmake .. \
+    && make -j4 install \
+    && apt-get purge -y --auto-remove $buildDeps \
+    && rm -r /usr/src/cppzmq
+
+RUN OMNIORB_DOWNLOAD_URL=https://nexus.engageska-portugal.pt/repository/raw/omniorb/omniORB-4.2.3.tar.bz2 \
+    && buildDeps='build-essential ca-certificates curl python-dev python-pkgconfig' \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && apt-get -y install --no-install-recommends $buildDeps \
+    && rm -rf /var/lib/apt/lists/* \
+    && mkdir -p /usr/src/omniorb \
+    && cd /usr/src/omniorb \
+    && curl -kfsSL "$OMNIORB_DOWNLOAD_URL" -o omniorb.tar.bz2 \
+    && tar xf omniorb.tar.bz2 -C /usr/src/omniorb --strip-components=1 \
+    && ./configure --enable-static=no \
+    && make -C /usr/src/omniorb -j$(nproc) \
+    && make -C /usr/src/omniorb install \
+    && apt-get purge -y --auto-remove $buildDeps \
+    && rm -r /usr/src/omniorb
+
+FROM debian:buster-slim
+COPY --from=buildenv /usr/local /usr/local
+
diff --git a/docker/tango/tango-dependencies/Makefile b/docker/tango/tango-dependencies/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-dependencies/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-dependencies/retry.sh b/docker/tango/tango-dependencies/retry.sh
new file mode 100755
index 0000000000000000000000000000000000000000..0e5f6e97014db2377acecf3e84e44b1b1ca1f683
--- /dev/null
+++ b/docker/tango/tango-dependencies/retry.sh
@@ -0,0 +1,163 @@
+#!/usr/bin/env bash
+
+GETOPT_BIN=$IN_GETOPT_BIN
+GETOPT_BIN=${GETOPT_BIN:-getopt}
+
+__sleep_amount() {
+  if [ -n "$constant_sleep" ]; then
+    sleep_time=$constant_sleep
+  else
+    #TODO: check for awk
+    #TODO: check if user would rather use one of the other possible dependencies: python, ruby, bc, dc
+    sleep_time=`awk "BEGIN {t = $min_sleep * $(( (1<<($attempts -1)) )); print (t > $max_sleep ? $max_sleep : t)}"`
+  fi
+}
+
+__log_out() {
+  echo "$1" 1>&2
+}
+
+# Paramters: max_tries min_sleep max_sleep constant_sleep fail_script EXECUTION_COMMAND
+retry()
+{
+  local max_tries="$1"; shift
+  local min_sleep="$1"; shift
+  local max_sleep="$1"; shift
+  local constant_sleep="$1"; shift
+  local fail_script="$1"; shift
+  if [ -n "$VERBOSE" ]; then
+    __log_out "Retry Parameters: max_tries=$max_tries min_sleep=$min_sleep max_sleep=$max_sleep constant_sleep=$constant_sleep"
+    if [ -n "$fail_script" ]; then __log_out "Fail script: $fail_script"; fi
+    __log_out ""
+    __log_out "Execution Command: $*"
+    __log_out ""
+  fi
+
+  local attempts=0
+  local return_code=1
+
+
+  while [[ $return_code -ne 0 && $attempts -le $max_tries ]]; do
+    if [ $attempts -gt 0 ]; then
+      __sleep_amount
+      __log_out "Before retry #$attempts: sleeping $sleep_time seconds"
+      sleep $sleep_time
+    fi
+
+    P="$1"
+    for param in "${@:2}"; do P="$P '$param'"; done
+    #TODO: replace single quotes in each arg with '"'"' ?
+    export RETRY_ATTEMPT=$attempts
+    bash -c "$P"
+    return_code=$?
+    #__log_out "Process returned $return_code on attempt $attempts"
+    if [ $return_code -eq 127 ]; then
+      # command not found
+      exit $return_code
+    elif [ $return_code -ne 0 ]; then
+      attempts=$[$attempts +1]
+    fi
+  done
+
+  if [ $attempts -gt $max_tries ]; then
+    if [ -n "$fail_script" ]; then
+      __log_out "Retries exhausted, running fail script"
+      eval $fail_script
+    else
+      __log_out "Retries exhausted"
+    fi
+  fi
+
+  exit $return_code
+}
+
+# If we're being sourced, don't worry about such things
+if [ "$BASH_SOURCE" == "$0" ]; then
+  # Prints the help text
+  help()
+  {
+    local retry=$(basename $0)
+    cat <<EOF
+Usage: $retry [options] -- execute command
+    -h, -?, --help
+    -v, --verbose                    Verbose output
+    -t, --tries=#                    Set max retries: Default 10
+    -s, --sleep=secs                 Constant sleep amount (seconds)
+    -m, --min=secs                   Exponenetial Backoff: minimum sleep amount (seconds): Default 0.3
+    -x, --max=secs                   Exponenetial Backoff: maximum sleep amount (seconds): Default 60
+    -f, --fail="script +cmds"        Fail Script: run in case of final failure
+EOF
+  }
+
+  # show help for no arguments if stdin is a terminal
+  if { [ -z "$1" ] && [ -t 0 ] ; } || [ "$1" == '-h' ] || [ "$1" == '-?' ] || [ "$1" == '--help' ]
+  then
+    help
+    exit 0
+  fi
+
+  $GETOPT_BIN --test > /dev/null
+  if [[ $? -ne 4 ]]; then
+      echo "I’m sorry, 'getopt --test' failed in this environment. Please load GNU getopt."
+      exit 1
+  fi
+
+  OPTIONS=vt:s:m:x:f:
+  LONGOPTIONS=verbose,tries:,sleep:,min:,max:,fail:
+
+  PARSED=$($GETOPT_BIN --options="$OPTIONS" --longoptions="$LONGOPTIONS" --name "$0" -- "$@")
+  if [[ $? -ne 0 ]]; then
+    # e.g. $? == 1
+    #  then getopt has complained about wrong arguments to stdout
+    exit 2
+  fi
+  # read getopt’s output this way to handle the quoting right:
+  eval set -- "$PARSED"
+
+  max_tries=10
+  min_sleep=0.3
+  max_sleep=60.0
+  constant_sleep=
+  fail_script=
+
+  # now enjoy the options in order and nicely split until we see --
+  while true; do
+      case "$1" in
+          -v|--verbose)
+              VERBOSE=true
+              shift
+              ;;
+          -t|--tries)
+              max_tries="$2"
+              shift 2
+              ;;
+          -s|--sleep)
+              constant_sleep="$2"
+              shift 2
+              ;;
+          -m|--min)
+              min_sleep="$2"
+              shift 2
+              ;;
+          -x|--max)
+              max_sleep="$2"
+              shift 2
+              ;;
+          -f|--fail)
+              fail_script="$2"
+              shift 2
+              ;;
+          --)
+              shift
+              break
+              ;;
+          *)
+              echo "Programming error"
+              exit 3
+              ;;
+      esac
+  done
+
+  retry "$max_tries" "$min_sleep" "$max_sleep" "$constant_sleep" "$fail_script" "$@"
+
+fi
diff --git a/docker/tango/tango-dependencies/wait-for-it.sh b/docker/tango/tango-dependencies/wait-for-it.sh
new file mode 100755
index 0000000000000000000000000000000000000000..eca6c3b9c8c61aa6ce889c185c700ad094988cc2
--- /dev/null
+++ b/docker/tango/tango-dependencies/wait-for-it.sh
@@ -0,0 +1,161 @@
+#!/usr/bin/env bash
+#   Use this script to test if a given TCP host/port are available
+
+cmdname=$(basename $0)
+
+echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
+
+usage()
+{
+    cat << USAGE >&2
+Usage:
+    $cmdname host:port [-s] [-t timeout] [-- command args]
+    -h HOST | --host=HOST       Host or IP under test
+    -p PORT | --port=PORT       TCP port under test
+                                Alternatively, you specify the host and port as host:port
+    -s | --strict               Only execute subcommand if the test succeeds
+    -q | --quiet                Don't output any status messages
+    -t TIMEOUT | --timeout=TIMEOUT
+                                Timeout in seconds, zero for no timeout
+    -- COMMAND ARGS             Execute command with args after the test finishes
+USAGE
+    exit 1
+}
+
+wait_for()
+{
+    if [[ $TIMEOUT -gt 0 ]]; then
+        echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT"
+    else
+        echoerr "$cmdname: waiting for $HOST:$PORT without a timeout"
+    fi
+    start_ts=$(date +%s)
+    while :
+    do
+        (echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1
+        result=$?
+        if [[ $result -eq 0 ]]; then
+            end_ts=$(date +%s)
+            echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds"
+            break
+        fi
+        sleep 1
+    done
+    return $result
+}
+
+wait_for_wrapper()
+{
+    # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
+    if [[ $QUIET -eq 1 ]]; then
+        timeout $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
+    else
+        timeout $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
+    fi
+    PID=$!
+    trap "kill -INT -$PID" INT
+    wait $PID
+    RESULT=$?
+    if [[ $RESULT -ne 0 ]]; then
+        echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT"
+    fi
+    return $RESULT
+}
+
+# process arguments
+while [[ $# -gt 0 ]]
+do
+    case "$1" in
+        *:* )
+        hostport=(${1//:/ })
+        HOST=${hostport[0]}
+        PORT=${hostport[1]}
+        shift 1
+        ;;
+        --child)
+        CHILD=1
+        shift 1
+        ;;
+        -q | --quiet)
+        QUIET=1
+        shift 1
+        ;;
+        -s | --strict)
+        STRICT=1
+        shift 1
+        ;;
+        -h)
+        HOST="$2"
+        if [[ $HOST == "" ]]; then break; fi
+        shift 2
+        ;;
+        --host=*)
+        HOST="${1#*=}"
+        shift 1
+        ;;
+        -p)
+        PORT="$2"
+        if [[ $PORT == "" ]]; then break; fi
+        shift 2
+        ;;
+        --port=*)
+        PORT="${1#*=}"
+        shift 1
+        ;;
+        -t)
+        TIMEOUT="$2"
+        if [[ $TIMEOUT == "" ]]; then break; fi
+        shift 2
+        ;;
+        --timeout=*)
+        TIMEOUT="${1#*=}"
+        shift 1
+        ;;
+        --)
+        shift
+        CLI="$@"
+        break
+        ;;
+        --help)
+        usage
+        ;;
+        *)
+        echoerr "Unknown argument: $1"
+        usage
+        ;;
+    esac
+done
+
+if [[ "$HOST" == "" || "$PORT" == "" ]]; then
+    echoerr "Error: you need to provide a host and port to test."
+    usage
+fi
+
+TIMEOUT=${TIMEOUT:-15}
+STRICT=${STRICT:-0}
+CHILD=${CHILD:-0}
+QUIET=${QUIET:-0}
+
+if [[ $CHILD -gt 0 ]]; then
+    wait_for
+    RESULT=$?
+    exit $RESULT
+else
+    if [[ $TIMEOUT -gt 0 ]]; then
+        wait_for_wrapper
+        RESULT=$?
+    else
+        wait_for
+        RESULT=$?
+    fi
+fi
+
+if [[ $CLI != "" ]]; then
+    if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then
+        echoerr "$cmdname: strict mode, refusing to execute subprocess"
+        exit $RESULT
+    fi
+    exec $CLI
+else
+    exit $RESULT
+fi
diff --git a/docker/tango/tango-dsconfig/.release b/docker/tango/tango-dsconfig/.release
new file mode 100644
index 0000000000000000000000000000000000000000..80704639b17e1ec8e197d62a0cfacac82d3a926a
--- /dev/null
+++ b/docker/tango/tango-dsconfig/.release
@@ -0,0 +1,2 @@
+release=1.5.0
+tag=tango-dsconfig-1.5.0
diff --git a/docker/tango/tango-dsconfig/Dockerfile b/docker/tango/tango-dsconfig/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..f5479d16c77a9b8236fd9c59da10b67223e23305
--- /dev/null
+++ b/docker/tango/tango-dsconfig/Dockerfile
@@ -0,0 +1,30 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-cpp:latest
+
+USER root
+
+RUN runtimeDeps='libboost-python1.67.0 \
+		ca-certificates \
+		make \
+		curl \
+        git \
+		python3 \
+		python3-distutils' \
+    && DOCKERHOST=`awk '/^[a-z]+[0-9]+\t00000000/ { printf("%d.%d.%d.%d", "0x" substr($3, 7, 2), "0x" substr($3, 5, 2), "0x" substr($3, 3, 2), "0x" substr($3, 1, 2)) }' < /proc/net/route` \
+    && /usr/local/bin/wait-for-it.sh --host=$DOCKERHOST --port=3142 --timeout=3 --strict --quiet -- echo "Acquire::http::Proxy \"http://$DOCKERHOST:3142\";" > /etc/apt/apt.conf.d/30proxy \
+    && echo "Proxy detected on docker host - using for this build" || echo "No proxy detected on docker host" \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && apt-get -y install --no-install-recommends $runtimeDeps \
+    && rm -rf /var/lib/apt/lists/* /etc/apt/apt.conf.d/30proxy
+
+RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python3 get-pip.py
+COPY pip.conf /etc/pip.conf
+
+RUN python3 -m pip install wheel numpy==1.16.6
+
+RUN python3 -m pip install --extra-index-url https://nexus.engageska-portugal.pt/repository/pypi/simple python-dsconfig==1.5.0
+
+COPY json2tango .
+ENV PATH $PATH:/json2tango
+# RUN chmod +x ./json2tango.sh if needed
diff --git a/docker/tango/tango-dsconfig/Makefile b/docker/tango/tango-dsconfig/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-dsconfig/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-dsconfig/json2tango b/docker/tango/tango-dsconfig/json2tango
new file mode 100755
index 0000000000000000000000000000000000000000..0aaa5feb0f5fb6c761c1a91b72bc9ab99f2b552c
--- /dev/null
+++ b/docker/tango/tango-dsconfig/json2tango
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+/usr/local/bin/json2tango "$@"
+RESULT="$?"
+
+# check the result of json2tango to see if it is 2(CONFIG LOADED) and return successfully
+if [ "$RESULT" == "2" ]; then
+	echo "/usr/local/bin/json2tango returned exit code 2(CONFIG LOADED), returning 0"
+	exit 0
+else
+	# return the result of json2tango script
+	exit $RESULT
+fi
diff --git a/docker/tango/tango-dsconfig/pip.conf b/docker/tango/tango-dsconfig/pip.conf
new file mode 100644
index 0000000000000000000000000000000000000000..41d1dce5e2cce9176483b21e87ebf2c1cf5f1f6c
--- /dev/null
+++ b/docker/tango/tango-dsconfig/pip.conf
@@ -0,0 +1,4 @@
+[global]
+index-url = https://nexus.engageska-portugal.pt/repository/pypi/simple
+extra-index-url = https://pypi.org/simple
+disable-pip-version-check = True
diff --git a/docker/tango/tango-itango/.release b/docker/tango/tango-itango/.release
new file mode 100644
index 0000000000000000000000000000000000000000..09a41d841d24fb13c0cbbc2f55ab23b0b12db7ca
--- /dev/null
+++ b/docker/tango/tango-itango/.release
@@ -0,0 +1,2 @@
+release=9.3.2.1
+tag=tango-itango-9.3.2.1
diff --git a/docker/tango/tango-itango/Dockerfile b/docker/tango/tango-itango/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..de855437ab6c585910c576261be237a12ae290d9
--- /dev/null
+++ b/docker/tango/tango-itango/Dockerfile
@@ -0,0 +1,12 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/ska-python-buildenv:latest as buildenv
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/ska-python-runtime:latest
+
+# create ipython profile to so that itango doesn't fail if ipython hasn't run yet
+
+RUN python3 -m pip install itango==0.1.6
+RUN ipython profile create
+
+CMD ["itango3"]
diff --git a/docker/tango/tango-itango/Makefile b/docker/tango/tango-itango/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c45724e793b3e6193ddabe7e086fc771b2a92801
--- /dev/null
+++ b/docker/tango/tango-itango/Makefile
@@ -0,0 +1,67 @@
+include ../../make/Makefile
+
+# name of the Docker volume used to cache eggs and wheels
+CACHE_VOLUME = cache-tango-itango-test
+
+# optional docker run-time arguments
+DOCKER_RUN_ARGS =
+
+# defines the image to test
+IMAGE_TO_TEST = $(DOCKER_REGISTRY_HOST)/$(DOCKER_REGISTRY_USER)/tango-itango:latest
+
+# docker-compose commmand for a composition of services for the tango database,
+# databaseds device, and tangotest devices
+DOCKER_COMPOSE_COMMAND = PWD=$(CURDIR) \
+						 DOCKER_REGISTRY_HOST=$(DOCKER_REGISTRY_HOST) \
+						 DOCKER_REGISTRY_USER=$(DOCKER_REGISTRY_USER) \
+						 docker-compose \
+						 -f docker-compose.yml
+
+# defines a function to copy the ./test directory into the container and
+# then runs the requested make target in the container. The container is:
+#   1. attached to the network of the docker-compose test system
+#   2. uses a persistent volume to cache Python eggs and wheels so that fewer
+#      downloads are required
+#   3. uses a transient volume as a working directory, in which untarred files
+#      and test output can be written in the container and subsequently copied
+#      to the host
+make = tar -c test/ | \
+	   docker run -i --rm --network=$(notdir $(CURDIR))_default \
+	   -v $(CACHE_VOLUME):/home/tango/.cache \
+	   -v /build -w /build $(DOCKER_RUN_ARGS) $(IMAGE_TO_TEST) \
+	   bash -c "sudo chown tango /build /home/tango/.cache && \
+	   tar x --strip-components 1 --warning=all && \
+	   make TANGO_HOST=databaseds:10000 $1"
+
+all: test
+
+pull:  ## download the application image
+	docker pull $(IMAGE_TO_TEST)
+
+test: DOCKER_RUN_ARGS = --volumes-from=$(BUILD)
+test:
+	$(INIT_CACHE)
+	$(DOCKER_COMPOSE_COMMAND) up -d
+	$(call make,test); \
+	  status=$$?; \
+	  docker rm -f -v $(BUILD); \
+	  $(DOCKER_COMPOSE_COMMAND) down; \
+	  exit $$status
+
+piplock: build  ## overwrite Pipfile.lock with the image version
+	docker run $(IMAGE_TO_TEST) cat /app/Pipfile.lock > $(CURDIR)/Pipfile.lock
+
+# insert the line below after 'status=$$?;' to copy output from the test run
+# inside the container into ./build on the host.
+#	  docker cp $(BUILD):/build .; \
+
+.PHONY: all test
+
+# Creates Docker volume for use as a cache, if it doesn't exist already
+INIT_CACHE = \
+	docker volume ls | grep $(CACHE_VOLUME) || \
+	docker create --name $(CACHE_VOLUME) -v $(CACHE_VOLUME):/cache $(IMAGE_TO_TEST)
+
+# http://cakoose.com/wiki/gnu_make_thunks
+BUILD_GEN = $(shell docker create -v /build $(IMAGE_TO_TEST))
+BUILD = $(eval BUILD := $(BUILD_GEN))$(BUILD)
\ No newline at end of file
diff --git a/docker/tango/tango-itango/docker-compose.yml b/docker/tango/tango-itango/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..aa32522c11b53a3c34b329cf8b8f214fa9881d71
--- /dev/null
+++ b/docker/tango/tango-itango/docker-compose.yml
@@ -0,0 +1,61 @@
+#
+# Docker compose file for TANGO database and database device server
+#
+# Defines:
+#   - tangodb: MariaDB database with TANGO schema
+#   - databaseds: TANGO database device server
+#
+# Requires:
+#   - None
+#
+version: '2'
+volumes:
+  tangodb-tango-rest-test: {}
+
+services:
+  tangodb:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-db:latest
+    environment:
+    - MYSQL_ROOT_PASSWORD=secret
+    - MYSQL_DATABASE=tango
+    - MYSQL_USER=tango
+    - MYSQL_PASSWORD=tango
+    restart: on-failure
+
+  databaseds:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-cpp:latest
+    depends_on:
+    - tangodb
+    environment:
+    - MYSQL_HOST=tangodb:3306
+    - MYSQL_DATABASE=tango
+    - MYSQL_USER=tango
+    - MYSQL_PASSWORD=tango
+    - TANGO_HOST=databaseds:10000
+    entrypoint:
+    - /usr/local/bin/wait-for-it.sh
+    - tangodb:3306
+    - --timeout=30
+    - --strict
+    - --
+    - /usr/local/bin/DataBaseds
+    - "2"
+    - -ORBendPoint
+    - giop:tcp::10000
+    restart: on-failure
+
+  tangotest:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-java:latest
+    depends_on:
+    - databaseds
+    environment:
+    - TANGO_HOST=databaseds:10000
+    entrypoint:
+    - /usr/local/bin/wait-for-it.sh
+    - databaseds:10000
+    - --timeout=30
+    - --strict
+    - --
+    - /usr/local/bin/TangoTest
+    - test
+    restart: on-failure
diff --git a/docker/tango/tango-itango/test/Makefile b/docker/tango/tango-itango/test/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1acd6def88d662e3ca09a81f601491d4d52e2019
--- /dev/null
+++ b/docker/tango/tango-itango/test/Makefile
@@ -0,0 +1,12 @@
+all: test
+
+test:
+	[ -f /.dockerenv ] && sudo apt-get update && sudo apt-get -y install --no-install-recommends expect || true
+    # It takes several seconds for the tango database to be populated from
+    # scratch, so pause until DB is created and the device we test against is
+    # responsive. If the Tango DB volume already exists, there'll be no pause
+    # delay at all and the test will run immediately.
+	retry -- tango_admin --check-device sys/tg_test/1
+	./script.exp
+
+.PHONY: all test
diff --git a/docker/tango/tango-itango/test/script.exp b/docker/tango/tango-itango/test/script.exp
new file mode 100755
index 0000000000000000000000000000000000000000..d560527f63eaca1dc57ce4c1a9e72d6f3383146b
--- /dev/null
+++ b/docker/tango/tango-itango/test/script.exp
@@ -0,0 +1,84 @@
+#!/usr/bin/expect -f
+#
+# This Expect script was generated by autoexpect on Thu Nov 15 09:12:55 2018
+# Expect and autoexpect were both written by Don Libes, NIST.
+#
+# Note that autoexpect does not guarantee a working script.  It
+# necessarily has to guess about certain things.  Two reasons a script
+# might fail are:
+#
+# 1) timing - A surprising number of programs (rn, ksh, zsh, telnet,
+# etc.) and devices discard or ignore keystrokes that arrive "too
+# quickly" after prompts.  If you find your new script hanging up at
+# one spot, try adding a short sleep just before the previous send.
+# Setting "force_conservative" to 1 (see below) makes Expect do this
+# automatically - pausing briefly before sending each character.  This
+# pacifies every program I know of.  The -c flag makes the script do
+# this in the first place.  The -C flag allows you to define a
+# character to toggle this mode off and on.
+
+set force_conservative 0  ;# set to 1 to force conservative mode even if
+			  ;# script wasn't run conservatively originally
+if {$force_conservative} {
+	set send_slow {1 .1}
+	proc send {ignore arg} {
+		sleep .1
+		exp_send -s -- $arg
+	}
+}
+
+#
+# 2) differing output - Some programs produce different output each time
+# they run.  The "date" command is an obvious example.  Another is
+# ftp, if it produces throughput statistics at the end of a file
+# transfer.  If this causes a problem, delete these patterns or replace
+# them with wildcards.  An alternative is to use the -p flag (for
+# "prompt") which makes Expect only look for the last line of output
+# (i.e., the prompt).  The -P flag allows you to define a character to
+# toggle this mode off and on.
+#
+# Read the man page for more info.
+#
+# -Don
+
+set timeout 2
+spawn /venv/bin/itango3 --no-color-info --simple-prompt --no-banner
+match_max 100000
+
+expect {
+    timeout { send_user "Problem starting itango session"; exit 1 }
+    -ex "In \[1\]: " { }
+}
+
+send "dev = Device('sys/tg_test/1')\r"
+expect {
+    timeout { send_user "\nCould not create device proxy to TangoTest device\n"; exit 1 }
+    -ex "dev = Device('sys/tg_test/1')\r\n\r\nIn \[2\]: " {}
+}
+
+send "dev.status()\r"
+expect {
+    timeout { send_user "\nTangoTest device is in unexpected state\n"; exit 1 }
+    -ex "dev.status()\r\nOut\[2\]: 'The device is in RUNNING state.'\r\n\r\nIn \[3\]: " {}
+}
+
+send "dev.DevString('hello world!')\r"
+expect {
+    timeout { send_user "\nFailure executing command\n"; exit 1 }
+    -ex "dev.DevString('hello world!')\r\nOut\[3\]: 'hello world!'\r\n\r\nIn \[4\]: " {}
+}
+
+send "import numpy; isinstance(dev.read_attribute('short_spectrum_ro').value, numpy.ndarray)\r"
+expect {
+    timeout { send_user "\nFailure executing command\n"; exit 1 }
+    -ex "import numpy; isinstance(dev.read_attribute('short_spectrum_ro').value, numpy.ndarray)\r\nOut\[4\]: True\r\n\r\nIn \[5\]: " {}
+}
+
+send "import numpy; isinstance(dev.read_attribute('short_spectrum').value, numpy.ndarray)\r"
+expect {
+    timeout { send_user "\nFailure executing command\n"; exit 1 }
+    -ex "import numpy; isinstance(dev.read_attribute('short_spectrum').value, numpy.ndarray)\r\nOut\[5\]: True\r\n\r\nIn \[6\]: " {}
+}
+
+send "exit\r"
+expect eof
diff --git a/docker/tango/tango-java/.release b/docker/tango/tango-java/.release
new file mode 100644
index 0000000000000000000000000000000000000000..f11cd5130ff65f00d005acbfc962d24f4511b469
--- /dev/null
+++ b/docker/tango/tango-java/.release
@@ -0,0 +1,2 @@
+release=9.3.3
+tag=tango-java-9.3.3
diff --git a/docker/tango/tango-java/Dockerfile b/docker/tango/tango-java/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..080a7eb946b3644b6923fad945243daa80875e3e
--- /dev/null
+++ b/docker/tango/tango-java/Dockerfile
@@ -0,0 +1,55 @@
+#
+# This Dockerfile builds Tango including Java apps and libraries in an
+# intermediate image, then creates a release image containing the compiled
+# binaries.
+#
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-dependencies:latest
+
+RUN JAVA_DOWNLOAD_URL=https://nexus.engageska-portugal.pt/repository/raw/java/jre-8u221-linux-x64.tar.gz \
+    && mkdir /usr/java \
+    && cd /usr/java \
+    && buildDeps='wget sudo libxrender1 libxtst6 libxi6' \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends $buildDeps \
+    && wget --no-check-certificate "$JAVA_DOWNLOAD_URL" -O java.tar.gz \
+    && tar zxvf java.tar.gz \
+    && update-alternatives --install /usr/bin/java java /usr/java/jre1.8.0_221/bin/java 0 \
+    && update-alternatives --set java /usr/java/jre1.8.0_221/bin/java \
+    && rm /usr/java/java.tar.gz
+
+RUN TANGO_DOWNLOAD_URL=https://nexus.engageska-portugal.pt/repository/raw/tango-cs/tango-9.3.3-rc2.tar.gz \
+    && DOCKERHOST=`awk '/^[a-z]+[0-9]+\t00000000/ { printf("%d.%d.%d.%d", "0x" substr($3, 7, 2), "0x" substr($3, 5, 2), "0x" substr($3, 3, 2), "0x" substr($3, 1, 2)) }' < /proc/net/route` \
+    && /usr/local/bin/wait-for-it.sh --host=$DOCKERHOST --port=3142 --timeout=3 --strict --quiet -- echo "Acquire::http::Proxy \"http://$DOCKERHOST:3142\";" > /etc/apt/apt.conf.d/30proxy \
+    && echo "Proxy detected on docker host - using for this build" || echo "No proxy detected on docker host" \
+    && mkdir -p /usr/share/man/man1 \
+    && buildDeps='build-essential curl file libmariadbclient-dev libmariadbclient-dev-compat pkg-config python libmariadb3' \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends $buildDeps \
+    && rm -rf /var/lib/apt/lists/* \
+    && mkdir -p /usr/src/tango \
+    && cd /usr/src/tango \
+    && curl -fsSL -k "$TANGO_DOWNLOAD_URL" -o tango.tar.gz \
+    && tar xf tango.tar.gz -C /usr/src/tango --strip-components=1 \
+    && ./configure --with-zmq=/usr/local --with-omni=/usr/local --with-mysqlclient-prefix=/usr --enable-static=no \
+    && make -C /usr/src/tango -j$(nproc) \
+    && make -C /usr/src/tango install \
+    && ldconfig \
+    && apt-get purge -y --auto-remove $buildDeps \
+    && rm -r /usr/src/tango
+
+RUN LOG4J=https://nexus.engageska-portugal.pt/repository/raw/java/log4j-1.2.17.tar.gz \
+    && cd /usr/java \
+    && wget --no-check-certificate "$LOG4J" -O log4j.tar.gz \
+    && tar zxvf log4j.tar.gz \
+    && mv apache-log4j-1.2.17/log4j-1.2.17.jar /usr/local/share/java/log4j-1.2.17.jar \
+    && apt-get purge -y --auto-remove wget \
+    && rm /usr/java/log4j.tar.gz
+
+RUN useradd --create-home --home-dir /home/tango tango
+
+RUN echo "tango ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/tango \
+    && chmod 0440 /etc/sudoers.d/tango
+
+USER tango
diff --git a/docker/tango/tango-java/Makefile b/docker/tango/tango-java/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-java/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-jive/.release b/docker/tango/tango-jive/.release
new file mode 100644
index 0000000000000000000000000000000000000000..d6657a241cfa0cc6d20c75455390f0bbde70c6b2
--- /dev/null
+++ b/docker/tango/tango-jive/.release
@@ -0,0 +1,2 @@
+release=7.22
+tag=tango-jive-7.22
diff --git a/docker/tango/tango-jive/Dockerfile b/docker/tango/tango-jive/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..14f2cb953d041ae8b3b2f33b6ffa72af585da80c
--- /dev/null
+++ b/docker/tango/tango-jive/Dockerfile
@@ -0,0 +1,5 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-java
+
+ENTRYPOINT ["/usr/local/bin/jive"]
diff --git a/docker/tango/tango-jive/Makefile b/docker/tango/tango-jive/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-jive/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-libtango/.release b/docker/tango/tango-libtango/.release
new file mode 100644
index 0000000000000000000000000000000000000000..651516d7ac81cb1c294ca0e99ee8d006d31f98b4
--- /dev/null
+++ b/docker/tango/tango-libtango/.release
@@ -0,0 +1,2 @@
+release=9.3.4-rc7
+tag=tango-libtango-9.3.4-rc7
diff --git a/docker/tango/tango-libtango/Dockerfile b/docker/tango/tango-libtango/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..b8e68fc527aeb1e138182c679ac1fb8edb501dfd
--- /dev/null
+++ b/docker/tango/tango-libtango/Dockerfile
@@ -0,0 +1,4 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-cpp
+
diff --git a/docker/tango/tango-libtango/Makefile b/docker/tango/tango-libtango/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-libtango/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-panic-gui/Dockerfile b/docker/tango/tango-panic-gui/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..6e039bb7544fdb4a53a26464f299a10a45782b3d
--- /dev/null
+++ b/docker/tango/tango-panic-gui/Dockerfile
@@ -0,0 +1,92 @@
+ARG http_proxy
+ARG https_proxy
+FROM nexus.engageska-portugal.pt/ska-docker/ska-python-buildenv:9.3.2
+
+# # # NOTES
+# - pip2 crashes if the package we want isn't in the SKA repo,
+#     so we temporarily hide the SKA pip.conf 
+# - python-qt4 is needed for the panic gui (but not PyAlarm)
+# - pip doesn't automically install lxml (needed for GUI but not PyAlarm)
+# - Format of boost library name was apparently changed between 1.65 and 1.67,
+#     so we make a symlink
+# - panic uses python 2, but 'python' maps to python3 in our base image,
+#     so we use sed to edit the PyAlarm launcher
+RUN [ ! -z "$http_proxy" ] && \
+        sudo echo "Acquire::http::Proxy \"$http_proxy\";" > /etc/apt/apt.conf.d/30proxy ||  \
+        echo "no proxy" && \
+    sudo mv /etc/pip.conf /tmp/ska_pip_conf && \
+    DEBIAN_FRONTEND=noninteractive && sudo apt update && \
+    sudo apt install -y \
+        python2.7 \
+        python-pip \
+        python-qt4 \
+    && rm -rf /var/lib/apt/lists/ && \
+    ln -s /usr/lib/x86_64-linux-gnu/libboost_python27.so /usr/lib/x86_64-linux-gnu/libboost_python-py27.so && \
+    pip2 install panic lxml && \
+    sudo mv /tmp/ska_pip_conf /etc/pip.conf && \
+    sudo sed -i.original 's/python/python2/g' `which PyAlarm`
+
+# now the VNC stuff (ref. tango-vnc image in ska-docker repo)
+
+USER root
+
+RUN apt-get update && apt-mark hold iptables && \
+    env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+      dbus-x11 \
+      psmisc \
+      xdg-utils \
+      x11-xserver-utils \
+      x11-utils && \
+    env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+      xfce4 && \
+    env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+      gtk3-engines-xfce \
+      libgtk-3-bin \
+      mousepad \
+      xfce4-notifyd \
+      xfce4-taskmanager \
+      xfce4-terminal && \
+    env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+      xfce4-battery-plugin \
+      xfce4-clipman-plugin \
+      xfce4-cpufreq-plugin \
+      xfce4-cpugraph-plugin \
+      xfce4-diskperf-plugin \
+      xfce4-datetime-plugin \
+      xfce4-fsguard-plugin \
+      xfce4-genmon-plugin \
+      xfce4-indicator-plugin \
+      xfce4-netload-plugin \
+      xfce4-notes-plugin \
+      xfce4-places-plugin \
+      xfce4-sensors-plugin \
+      xfce4-smartbookmark-plugin \
+      xfce4-systemload-plugin \
+      xfce4-timer-plugin \
+      xfce4-verve-plugin \
+      xfce4-weather-plugin \
+      xfce4-whiskermenu-plugin && \
+    env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+      libxv1 \
+      mesa-utils \
+      mesa-utils-extra && \
+    sed -i 's%<property name="ThemeName" type="string" value="Xfce"/>%<property name="ThemeName" type="string" value="Raleigh"/>%' /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xsettings.xml
+
+RUN apt-get update && apt-get install -y \ 
+    git \
+    x11vnc \
+    software-properties-common \
+    unzip \
+    curl \
+    slim \
+    xvfb \ 
+    novnc \
+    python-websockify
+
+#Expose port 5920 to view display using VNC Viewer
+EXPOSE 5920
+EXPOSE 6081
+
+ENV DISPLAY=:20
+
+CMD Xvfb :20 -screen 0 1366x768x16 & x11vnc -passwd TestVNC -display :20 -N -forever & startxfce4 & websockify --web /usr/share/novnc 6081 localhost:5920 
diff --git a/docker/tango/tango-panic-gui/Makefile b/docker/tango/tango-panic-gui/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-panic-gui/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-panic/Dockerfile b/docker/tango/tango-panic/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..6f7536a8299226bf9a1f69ef0ac88aef37728cc5
--- /dev/null
+++ b/docker/tango/tango-panic/Dockerfile
@@ -0,0 +1,31 @@
+ARG http_proxy
+ARG https_proxy
+FROM nexus.engageska-portugal.pt/ska-docker/ska-python-buildenv:9.3.2
+
+# # # NOTES
+# - pip2 crashes if the package we want isn't in the SKA repo,
+#     so we temporarily hide the SKA pip.conf 
+# - exim4 is used for email alerts (configuration to be applied by user)
+# - Format of boost library name was apparently changed between 1.65 and 1.67,
+#     so we make a symlink
+# - panic uses python 2, but 'python' maps to python3 in our base image,
+#     so we use sed to edit the PyAlarm launcher
+RUN [ ! -z "$http_proxy" ] && \
+        sudo echo "Acquire::http::Proxy \"$http_proxy\";" > /etc/apt/apt.conf.d/30proxy ||  \
+        echo "no proxy" && \
+    sudo mv /etc/pip.conf /tmp/ska_pip_conf && \
+    DEBIAN_FRONTEND=noninteractive && sudo apt update && \
+    sudo apt install -y \
+        python2.7 \
+        python-pip \
+        exim4 \
+    && rm -rf /var/lib/apt/lists/ && \
+    ln -s /usr/lib/x86_64-linux-gnu/libboost_python27.so /usr/lib/x86_64-linux-gnu/libboost_python-py27.so && \
+    pip2 install panic && \
+    sudo mv /tmp/ska_pip_conf /etc/pip.conf && \
+    sudo sed -i.original 's/python/python2/g' `which PyAlarm`
+
+COPY aliases /etc/
+COPY update-exim4.conf.conf /etc/exim4/
+COPY entrypoint.sh /app/
+ENTRYPOINT ["/app/entrypoint.sh"]
diff --git a/docker/tango/tango-panic/Makefile b/docker/tango/tango-panic/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-panic/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-panic/aliases b/docker/tango/tango-panic/aliases
new file mode 100644
index 0000000000000000000000000000000000000000..3db6da1ffb884d2e2617180a308a4c1a33ac5a72
--- /dev/null
+++ b/docker/tango/tango-panic/aliases
@@ -0,0 +1,14 @@
+# /etc/aliases
+# this is the default aliases config file from exim4, edit it as required
+mailer-daemon: postmaster
+postmaster: root
+nobody: root
+hostmaster: root
+usenet: root
+news: root
+webmaster: root
+www: root
+ftp: root
+abuse: root
+noc: root
+security: root
diff --git a/docker/tango/tango-panic/entrypoint.sh b/docker/tango/tango-panic/entrypoint.sh
new file mode 100755
index 0000000000000000000000000000000000000000..694e6329f24df9dfdb2c77ef66b9da5b6ad7f11c
--- /dev/null
+++ b/docker/tango/tango-panic/entrypoint.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# PANIC launch script
+# Set environment variable PANIC_EMAIL to a non-zero value to enable emails.
+
+if [ -n "$PANIC_EMAIL" ] && [ "$PANIC_EMAIL" -ne 0 ]; then
+	echo "Enabling email"
+	sudo service exim4 start
+else
+	echo "email Disabled"
+fi
+
+exec "$@"
diff --git a/docker/tango/tango-panic/update-exim4.conf.conf b/docker/tango/tango-panic/update-exim4.conf.conf
new file mode 100644
index 0000000000000000000000000000000000000000..1fc5474d34ccee4a196057f865323edf1b10884a
--- /dev/null
+++ b/docker/tango/tango-panic/update-exim4.conf.conf
@@ -0,0 +1,31 @@
+# /etc/exim4/update-exim4.conf.conf
+#
+# Edit this file and /etc/mailname by hand and execute update-exim4.conf
+# yourself or use 'dpkg-reconfigure exim4-config'
+#
+# Please note that this is _not_ a dpkg-conffile and that automatic changes
+# to this file might happen. The code handling this will honor your local
+# changes, so this is usually fine, but will break local schemes that mess
+# around with multiple versions of the file.
+#
+# update-exim4.conf uses this file to determine variable values to generate
+# exim configuration macros for the configuration file.
+#
+# Most settings found in here do have corresponding questions in the
+# Debconf configuration, but not all of them.
+#
+# This is a Debian specific file
+
+dc_eximconfig_configtype='local'
+dc_other_hostnames=''
+dc_local_interfaces='127.0.0.1 ; ::1'
+dc_readhost=''
+dc_relay_domains=''
+dc_minimaldns='false'
+dc_relay_nets=''
+dc_smarthost=''
+CFILEMODE='644'
+dc_use_split_config='false'
+dc_hide_mailname=''
+dc_mailname_in_oh='true'
+dc_localdelivery='mail_spool'
diff --git a/docker/tango/tango-pogo/.release b/docker/tango/tango-pogo/.release
new file mode 100644
index 0000000000000000000000000000000000000000..5e56d3d0c97826e64e1738a2a773a4430a14d2c9
--- /dev/null
+++ b/docker/tango/tango-pogo/.release
@@ -0,0 +1,2 @@
+release=9.6.31
+tag=tango-pogo-9.6.31
diff --git a/docker/tango/tango-pogo/Dockerfile b/docker/tango/tango-pogo/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..268e6d9ca124bd2cb1678058c936065f58a33bb9
--- /dev/null
+++ b/docker/tango/tango-pogo/Dockerfile
@@ -0,0 +1,30 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-java:latest
+
+USER root
+
+# Extend the java image with Firefox so that Pogo help can be displayed
+RUN runtimeDeps='firefox-esr' \
+    && DOCKERHOST=`awk '/^[a-z]+[0-9]+\t00000000/ { printf("%d.%d.%d.%d", "0x" substr($3, 7, 2), "0x" substr($3, 5, 2), "0x" substr($3, 3, 2), "0x" substr($3, 1, 2)) }' < /proc/net/route` \
+    && /usr/local/bin/wait-for-it.sh --host=$DOCKERHOST --port=3142 --timeout=3 --strict --quiet -- echo "Acquire::http::Proxy \"http://$DOCKERHOST:3142\";" > /etc/apt/apt.conf.d/30proxy \
+    && echo "Proxy detected on docker host - using for this build" || echo "No proxy detected on docker host" \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends $runtimeDeps \
+    && rm -rf /var/lib/apt/lists/* /etc/apt/apt.conf.d/30proxy
+
+# Pogo is included in tango source distribution, but replace with a newer version
+# Official source:  https://bintray.com/tango-controls/maven/Pogo/_latestVersion
+RUN buildDeps='wget' \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends $buildDeps \
+    && POGO_DOWNLOAD_URL=https://nexus.engageska-portugal.pt/repository/raw/tango-cs/pogo/Pogo-9.6.31.jar \
+    && cd /usr/local/share/java \
+    && rm -f Pogo-*.jar \
+    && wget --no-check-certificate "$POGO_DOWNLOAD_URL" -O Pogo-9.6.31.jar \
+    && ln -sf Pogo-9.6.31.jar Pogo.jar
+
+USER tango
+
+CMD ["/usr/local/bin/pogo"]
+
diff --git a/docker/tango/tango-pogo/Makefile b/docker/tango/tango-pogo/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..94836ab29167354c4d66d227553973370130be99
--- /dev/null
+++ b/docker/tango/tango-pogo/Makefile
@@ -0,0 +1 @@
+include ../../make/Makefile
diff --git a/docker/tango/tango-pytango/.release b/docker/tango/tango-pytango/.release
new file mode 100644
index 0000000000000000000000000000000000000000..997eb195f1e6ab4ecff67a24be6a38f9685e5d57
--- /dev/null
+++ b/docker/tango/tango-pytango/.release
@@ -0,0 +1,2 @@
+release=9.3.2.1
+tag=tango-pytango-9.3.2.1
diff --git a/docker/tango/tango-pytango/Dockerfile b/docker/tango/tango-pytango/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..48297be66ab34ba7ffd6c7d6bcff1beec1b674ed
--- /dev/null
+++ b/docker/tango/tango-pytango/Dockerfile
@@ -0,0 +1,4 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/ska-python-buildenv:latest as buildenv
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/ska-python-runtime:latest
diff --git a/docker/tango/tango-pytango/Makefile b/docker/tango/tango-pytango/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-pytango/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-rest/.release b/docker/tango/tango-rest/.release
new file mode 100644
index 0000000000000000000000000000000000000000..f2a7069e0d02ba7cc4afe3c696ce3639666f10bd
--- /dev/null
+++ b/docker/tango/tango-rest/.release
@@ -0,0 +1,2 @@
+release=1.14
+tag=tango-rest-1.14
diff --git a/docker/tango/tango-rest/Dockerfile b/docker/tango/tango-rest/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..fc52d9ea019a6c4e44546986f961782814711db7
--- /dev/null
+++ b/docker/tango/tango-rest/Dockerfile
@@ -0,0 +1,39 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-dependencies:latest as buildenv
+
+RUN MTANGOREST_DOWNLOAD_URL=https://github.com/tango-controls/rest-server/releases/download/rest-server-1.14/rest-server-1.14.jar \
+    && DOCKERHOST=`awk '/^[a-z]+[0-9]+\t00000000/ { printf("%d.%d.%d.%d", "0x" substr($3, 7, 2), "0x" substr($3, 5, 2), "0x" substr($3, 3, 2), "0x" substr($3, 1, 2)) }' < /proc/net/route` \
+    && /usr/local/bin/wait-for-it.sh --host=$DOCKERHOST --port=3142 --timeout=3 --strict --quiet -- echo "Acquire::http::Proxy \"http://$DOCKERHOST:3142\";" > /etc/apt/apt.conf.d/30proxy \
+    && echo "Proxy detected on docker host - using for this build" || echo "No proxy detected on docker host" \
+    && buildDeps='ca-certificates curl' \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && apt-get -y install $buildDeps --no-install-recommends \
+    && rm -rf /var/lib/apt/lists/* \
+    && mkdir /usr/local/lib/tango \
+    && cd /usr/local/lib/tango \
+    && curl -fsSL "$MTANGOREST_DOWNLOAD_URL" -o mtangorest.jar \
+    && apt-get purge -y --auto-remove $buildDeps
+
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-java:latest
+
+COPY --from=buildenv /usr/local/lib/tango/mtangorest.jar /usr/local/lib/tango/mtangorest.jar
+
+USER root
+
+RUN runtimeDeps='supervisor' \
+    && mkdir -p /usr/share/man/man1 \
+    && DOCKERHOST=`awk '/^[a-z]+[0-9]+\t00000000/ { printf("%d.%d.%d.%d", "0x" substr($3, 7, 2), "0x" substr($3, 5, 2), "0x" substr($3, 3, 2), "0x" substr($3, 1, 2)) }' < /proc/net/route` \
+    && /usr/local/bin/wait-for-it.sh --host=$DOCKERHOST --port=3142 --timeout=3 --strict --quiet -- echo "Acquire::http::Proxy \"http://$DOCKERHOST:3142\";" > /etc/apt/apt.conf.d/30proxy \
+    && echo "Proxy detected on docker host - using for this build" || echo "No proxy detected on docker host" \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends $runtimeDeps \
+    && rm -rf /var/lib/apt/lists/* /etc/apt/apt.conf.d/30proxy
+
+COPY tango_register_device.sh /usr/local/bin/
+
+# Configure supervisord. Ensure supervisord.conf contains entries for your device!
+COPY supervisord.conf /etc/supervisor/conf.d/
+
+# Start supervisor as daemon
+CMD ["/usr/bin/supervisord", "--configuration", "/etc/supervisor/supervisord.conf"]
diff --git a/docker/tango/tango-rest/Makefile b/docker/tango/tango-rest/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..15911887c7c0272ebd60e7c82b4ae07a92065bad
--- /dev/null
+++ b/docker/tango/tango-rest/Makefile
@@ -0,0 +1,63 @@
+include ../../make/Makefile
+
+# name of the Docker volume used to cache eggs and wheels
+CACHE_VOLUME = tango-rest-test-cache
+
+# optional docker run-time arguments
+DOCKER_RUN_ARGS =
+
+# defines the image to test
+IMAGE_TO_TEST = $(DOCKER_REGISTRY_HOST)/$(DOCKER_REGISTRY_USER)/tango-itango:latest
+
+# docker-compose commmand for a composition of services for the tango database,
+# databaseds device, and tangotest devices
+DOCKER_COMPOSE_COMMAND = PWD=$(CURDIR) \
+						 DOCKER_REGISTRY_HOST=$(DOCKER_REGISTRY_HOST) \
+						 DOCKER_REGISTRY_USER=$(DOCKER_REGISTRY_USER) \
+						 docker-compose \
+						 -f docker-compose.yml
+
+# defines a function to copy the ./test directory into the container and
+# then runs the requested make target in the container. The container is:
+#   1. attached to the network of the docker-compose test system
+#   2. uses a persistent volume to cache Python eggs and wheels so that fewer
+#      downloads are required
+#   3. uses a transient volume as a working directory, in which untarred files
+#      and test output can be written in the container and subsequently copied
+#      to the host
+make = tar -c test/ | \
+	   docker run -i --rm --network=$(notdir $(CURDIR))_default \
+	   -v $(CACHE_VOLUME):/home/tango/.cache \
+	   -v /build -w /build $(DOCKER_RUN_ARGS) $(IMAGE_TO_TEST) \
+	   bash -c "sudo chown tango /build /home/tango/.cache && \
+	   sudo apt-get update && \
+	   sudo apt-get install make && \
+	   tar x --strip-components 1 --warning=all && \
+	   make TANGO_HOST=databaseds:10000 $1"
+
+all: test
+
+test: DOCKER_RUN_ARGS = --volumes-from=$(BUILD)
+test:
+	$(INIT_CACHE)
+	$(DOCKER_COMPOSE_COMMAND) up -d
+	$(call make,test); \
+	  status=$$?; \
+	  docker rm -f -v $(BUILD); \
+	  $(DOCKER_COMPOSE_COMMAND) down; \
+	  exit $$status
+
+# insert the line below after 'status=$$?;' to copy output from the test run
+# inside the container into ./build on the host.
+#	  docker cp $(BUILD):/build .; \
+
+.PHONY: all test
+
+# Creates Docker volume for use as a cache, if it doesn't exist already
+INIT_CACHE = \
+	docker volume ls | grep $(CACHE_VOLUME) || \
+	docker create --name $(CACHE_VOLUME) -v $(CACHE_VOLUME):/cache $(IMAGE_TO_TEST)
+
+# http://cakoose.com/wiki/gnu_make_thunks
+BUILD_GEN = $(shell docker create -v /build $(IMAGE_TO_TEST))
+BUILD = $(eval BUILD := $(BUILD_GEN))$(BUILD)
\ No newline at end of file
diff --git a/docker/tango/tango-rest/docker-compose.yml b/docker/tango/tango-rest/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9c65825a906a7124b1b421a75bc87347424e146b
--- /dev/null
+++ b/docker/tango/tango-rest/docker-compose.yml
@@ -0,0 +1,79 @@
+#
+# Docker compose file for TANGO database and database device server
+#
+# Defines:
+#   - tangodb: MariaDB database with TANGO schema
+#   - databaseds: TANGO database device server
+#
+# Requires:
+#   - None
+#
+version: '2'
+
+services:
+  tangodb:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-db:latest
+    environment:
+    - MYSQL_ROOT_PASSWORD=secret
+    - MYSQL_DATABASE=tango
+    - MYSQL_USER=tango
+    - MYSQL_PASSWORD=tango
+    restart: on-failure
+
+
+  databaseds:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-cpp:latest
+    depends_on:
+    - tangodb
+    environment:
+    - MYSQL_HOST=tangodb:3306
+    - MYSQL_DATABASE=tango
+    - MYSQL_USER=tango
+    - MYSQL_PASSWORD=tango
+    - TANGO_HOST=databaseds:10000
+    entrypoint:
+    - /usr/local/bin/wait-for-it.sh
+    - tangodb:3306
+    - --timeout=30
+    - --strict
+    - --
+    - /usr/local/bin/DataBaseds
+    - "2"
+    - -ORBendPoint
+    - giop:tcp::10000
+    restart: on-failure
+
+  tangotest:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-java:latest
+    depends_on:
+    - databaseds
+    environment:
+    - TANGO_HOST=databaseds:10000
+    entrypoint:
+    - /usr/local/bin/wait-for-it.sh
+    - databaseds:10000
+    - --timeout=30
+    - --strict
+    - --
+    - /usr/local/bin/TangoTest
+    - test
+    restart: on-failure
+
+  rest:
+    image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-rest:latest
+    depends_on:
+    - tangotest
+    environment:
+    - TANGO_HOST=databaseds:10000
+    ports:
+    - 8080:8080
+    entrypoint:
+    - /usr/local/bin/wait-for-it.sh
+    - databaseds:10000
+    - --timeout=30
+    - --strict
+    - --
+    - /usr/bin/supervisord
+    - --configuration
+    - /etc/supervisor/supervisord.conf
+    restart: on-failure
diff --git a/docker/tango/tango-rest/supervisord.conf b/docker/tango/tango-rest/supervisord.conf
new file mode 100644
index 0000000000000000000000000000000000000000..22a7582929357256854a3ad06bea0d00a54215e5
--- /dev/null
+++ b/docker/tango/tango-rest/supervisord.conf
@@ -0,0 +1,26 @@
+[supervisord]
+nodaemon=true
+
+[program:tango-rest]
+command=/bin/bash -c '
+  MYHOSTNAME=`hostname --short` &&
+  JAVA_OPTS="-Xmx4G -Xshare:off -XX:+UseG1GC -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5009" &&
+  /usr/local/bin/tango_register_device.sh TangoRestServer/$MYHOSTNAME TangoRestServer $MYHOSTNAME/rest/0 &&
+  /usr/local/bin/tango_admin --add-property $MYHOSTNAME/rest/0 TANGO_DB tango://$TANGO_HOST/sys/database/2 &&
+  /usr/local/bin/tango_admin --add-property $MYHOSTNAME/rest/0 TOMCAT_PORT 8080 &&
+  /usr/local/bin/tango_admin --add-property $MYHOSTNAME/rest/0 TOMCAT_AUTH_METHOD plain &&
+  exec -- /usr/bin/java -jar $JAVA_OPTS /usr/local/lib/tango/mtangorest.jar $MYHOSTNAME'
+autorestart=true
+# TODO investigate why this can't run as a non-privileged user
+#user=tango
+priority=1
+
+[unix_http_server]
+username = dummy
+password = dummy
+file = /var/tmp/supervisord.sock
+
+[supervisorctl]
+username = dummy
+password = dummy
+
diff --git a/docker/tango/tango-rest/tango_register_device.sh b/docker/tango/tango-rest/tango_register_device.sh
new file mode 100755
index 0000000000000000000000000000000000000000..837c22895c635c130319b23150a119b764541e87
--- /dev/null
+++ b/docker/tango/tango-rest/tango_register_device.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+if [ "$#" -ne 3 ]; then
+  echo "usage: $0 <exec>/<inst> <class> <device> "
+  exit 1
+fi
+
+tango_admin --check-device $3 || \
+tango_admin --add-server $1 $2 $3 || \
+exit 1
diff --git a/docker/tango/tango-rest/test/Makefile b/docker/tango/tango-rest/test/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a963fc1c1f492264b3d727c35a953c437549ab59
--- /dev/null
+++ b/docker/tango/tango-rest/test/Makefile
@@ -0,0 +1,13 @@
+all: test
+
+test:
+	[ -f /.dockerenv ] && sudo apt-get update && sudo apt-get -y install --no-install-recommends curl || true
+    # It takes several seconds for the Tango database to be populated from
+    # scratch, so pause until DB is created and the device we test against is
+    # responsive. If the Tango DB volume already exists, there'll be no delay
+    # at all and the test will run immediately.
+	retry -- tango_admin --check-device sys/tg_test/1
+	/usr/local/bin/wait-for-it.sh rest:8080 --timeout=30 --strict -- curl --user tango-cs:tango http://rest:8080/tango/rest/rc4/hosts/databaseds/10000/devices/sys/tg_test/1/attributes/boolean_scalar/value
+
+.PHONY: all test
+
diff --git a/docker/tango/tango-starter/.release b/docker/tango/tango-starter/.release
new file mode 100644
index 0000000000000000000000000000000000000000..e042898350709f236bffb466b9f7e0c6f1c3ff50
--- /dev/null
+++ b/docker/tango/tango-starter/.release
@@ -0,0 +1,2 @@
+release=7.3.0.1
+tag=tango-starter-7.3.0.1
diff --git a/docker/tango/tango-starter/Dockerfile b/docker/tango/tango-starter/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..da182cdfe4aeb35aca8f049853530cb85a348991
--- /dev/null
+++ b/docker/tango/tango-starter/Dockerfile
@@ -0,0 +1,23 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-cpp:latest
+
+USER root
+
+# supervisor is installed so that the TANGO Starter device runs on startup
+RUN runtimeDeps='supervisor' \
+    && DOCKERHOST=`awk '/^[a-z]+[0-9]+\t00000000/ { printf("%d.%d.%d.%d", "0x" substr($3, 7, 2), "0x" substr($3, 5, 2), "0x" substr($3, 3, 2), "0x" substr($3, 1, 2)) }' < /proc/net/route` \
+    && /usr/local/bin/wait-for-it.sh --host=$DOCKERHOST --port=3142 --timeout=3 --strict --quiet -- echo "Acquire::http::Proxy \"http://$DOCKERHOST:3142\";" > /etc/apt/apt.conf.d/30proxy \
+    && echo "Proxy detected on docker host - using for this build" || echo "No proxy detected on docker host" \
+    && DEBIAN_FRONTEND=noninteractive apt-get update \
+    && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends $runtimeDeps \
+    && rm -rf /var/lib/apt/lists/* /etc/apt/apt.conf.d/30proxy
+
+COPY tango_register_device.sh /usr/local/bin/
+
+# Configure supervisord. Ensure supervisord.conf contains entries for your device!
+COPY supervisord.conf /etc/supervisor/conf.d/
+
+# Start supervisor as daemon
+CMD ["/usr/bin/supervisord", "--configuration", "/etc/supervisor/supervisord.conf"]
+
diff --git a/docker/tango/tango-starter/Makefile b/docker/tango/tango-starter/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..94836ab29167354c4d66d227553973370130be99
--- /dev/null
+++ b/docker/tango/tango-starter/Makefile
@@ -0,0 +1 @@
+include ../../make/Makefile
diff --git a/docker/tango/tango-starter/supervisord.conf b/docker/tango/tango-starter/supervisord.conf
new file mode 100644
index 0000000000000000000000000000000000000000..cbe28fdf0a4bee82a9d0812b6b4753046f90291c
--- /dev/null
+++ b/docker/tango/tango-starter/supervisord.conf
@@ -0,0 +1,13 @@
+[supervisord]
+nodaemon=true
+
+[program:tango-starter]
+command=/bin/bash -c '
+  MYHOSTNAME=`hostname --short` &&
+  /usr/local/bin/tango_register_device.sh Starter/$MYHOSTNAME Starter tango/admin/$MYHOSTNAME &&
+  /usr/local/bin/tango_admin --add-property tango/admin/$MYHOSTNAME StartDsPath /usr/local/bin &&
+  exec -- /usr/local/bin/Starter $MYHOSTNAME'
+autorestart=true
+user=tango
+priority=1
+
diff --git a/docker/tango/tango-starter/tango_register_device.sh b/docker/tango/tango-starter/tango_register_device.sh
new file mode 100644
index 0000000000000000000000000000000000000000..837c22895c635c130319b23150a119b764541e87
--- /dev/null
+++ b/docker/tango/tango-starter/tango_register_device.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+if [ "$#" -ne 3 ]; then
+  echo "usage: $0 <exec>/<inst> <class> <device> "
+  exit 1
+fi
+
+tango_admin --check-device $3 || \
+tango_admin --add-server $1 $2 $3 || \
+exit 1
diff --git a/docker/tango/tango-test/.release b/docker/tango/tango-test/.release
new file mode 100644
index 0000000000000000000000000000000000000000..1365ed62d0fe2347de331dcb422da6f0a52762c8
--- /dev/null
+++ b/docker/tango/tango-test/.release
@@ -0,0 +1,2 @@
+release=2.1.0.2
+tag=tango-test-2.1.0.2
diff --git a/docker/tango/tango-test/Dockerfile b/docker/tango/tango-test/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..82846e61883eacfcea40c3a2f29e19431fc6f724
--- /dev/null
+++ b/docker/tango/tango-test/Dockerfile
@@ -0,0 +1,5 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-libtango:latest
+
+ENTRYPOINT ["/usr/local/bin/TangoTest"]
diff --git a/docker/tango/tango-test/Makefile b/docker/tango/tango-test/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-test/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-vnc/.release b/docker/tango/tango-vnc/.release
new file mode 100644
index 0000000000000000000000000000000000000000..205f5fb62f5c39629a2c201838496713ba597e1b
--- /dev/null
+++ b/docker/tango/tango-vnc/.release
@@ -0,0 +1,2 @@
+release=0.1.0
+tag=tango-vnc-0.1.0
diff --git a/docker/tango/tango-vnc/Dockerfile b/docker/tango/tango-vnc/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..95145e733760b6db823082648b25166396f4d21d
--- /dev/null
+++ b/docker/tango/tango-vnc/Dockerfile
@@ -0,0 +1,71 @@
+#
+# This Dockerfile builds Tango including Java apps and libraries in an
+# intermediate image, then creates a release image containing the compiled
+# binaries.
+#
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/tango-java:latest
+
+USER root
+
+RUN apt-get update && apt-mark hold iptables && \
+    env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+      dbus-x11 \
+      psmisc \
+      xdg-utils \
+      x11-xserver-utils \
+      x11-utils && \
+    env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+      xfce4 && \
+    env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+      gtk3-engines-xfce \
+      libgtk-3-bin \
+      mousepad \
+      xfce4-notifyd \
+      xfce4-taskmanager \
+      xfce4-terminal && \
+    env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+      xfce4-battery-plugin \
+      xfce4-clipman-plugin \
+      xfce4-cpufreq-plugin \
+      xfce4-cpugraph-plugin \
+      xfce4-diskperf-plugin \
+      xfce4-datetime-plugin \
+      xfce4-fsguard-plugin \
+      xfce4-genmon-plugin \
+      xfce4-indicator-plugin \
+      xfce4-netload-plugin \
+      xfce4-notes-plugin \
+      xfce4-places-plugin \
+      xfce4-sensors-plugin \
+      xfce4-smartbookmark-plugin \
+      xfce4-systemload-plugin \
+      xfce4-timer-plugin \
+      xfce4-verve-plugin \
+      xfce4-weather-plugin \
+      xfce4-whiskermenu-plugin && \
+    env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+      libxv1 \
+      mesa-utils \
+      mesa-utils-extra && \
+    sed -i 's%<property name="ThemeName" type="string" value="Xfce"/>%<property name="ThemeName" type="string" value="Raleigh"/>%' /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xsettings.xml
+
+RUN apt-get update && apt-get install -y \ 
+    git \
+    x11vnc \
+    software-properties-common \
+    unzip \
+    curl \
+    slim \
+    xvfb \ 
+    novnc \
+    python-websockify
+
+#Expose port 5920 to view display using VNC Viewer
+EXPOSE 5920
+EXPOSE 6081
+
+ENV DISPLAY=:20
+
+CMD Xvfb :20 -screen 0 1366x768x16 & x11vnc -passwd TestVNC -display :20 -N -forever & startxfce4 & websockify --web /usr/share/novnc 6081 localhost:5920
\ No newline at end of file
diff --git a/docker/tango/tango-vnc/Makefile b/docker/tango/tango-vnc/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-vnc/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-vscode/.release b/docker/tango/tango-vscode/.release
new file mode 100644
index 0000000000000000000000000000000000000000..1f92611496ea80f6ff4b036952360265e5c82050
--- /dev/null
+++ b/docker/tango/tango-vscode/.release
@@ -0,0 +1,2 @@
+release=0.2.9
+tag=tango-vscode-0.2.9
diff --git a/docker/tango/tango-vscode/Dockerfile b/docker/tango/tango-vscode/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..ff27ff75693dc756f2c03c40583875fae19eda4f
--- /dev/null
+++ b/docker/tango/tango-vscode/Dockerfile
@@ -0,0 +1,69 @@
+ARG DOCKER_REGISTRY_USER
+ARG DOCKER_REGISTRY_HOST
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/ska-python-buildenv:latest as buildenv
+FROM ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/ska-python-runtime:latest
+
+USER root
+
+ARG SSH_PASSWORD=vscodessh
+
+ENV ssh_cmd tango:$SSH_PASSWORD
+ENV KUBE_LATEST_VERSION="v1.16.2"
+ENV HELM_VERSION="v3.3.1"
+ENV DEBIAN_FRONTEND="noninteractive"
+ENV RUNLEVEL="1"
+
+RUN echo $ssh_cmd
+
+RUN apt-get update && apt-get install -y \
+  openssh-server \
+  && rm -rf /var/lib/apt/lists/*
+
+RUN mkdir /var/run/sshd
+RUN echo $ssh_cmd | chpasswd
+
+RUN apt-get update && apt-get install -y curl net-tools git software-properties-common \
+    apt-transport-https wget gnupg libx11-xcb1 libasound2 x11-apps libice6 libsm6 \
+    libxaw7 libxft2 libxmu6 libxpm4 libxt6 x11-apps xbitmaps
+
+RUN python3 -m pip install docker-compose yamllint yamale
+
+RUN wget -q https://storage.googleapis.com/kubernetes-release/release/${KUBE_LATEST_VERSION}/bin/linux/amd64/kubectl -O /usr/local/bin/kubectl \
+    && chmod +x /usr/local/bin/kubectl \
+    && wget -q https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz -O - | tar -xzO linux-amd64/helm > /usr/local/bin/helm \
+    && chmod +x /usr/local/bin/helm
+
+RUN wget -q https://github.com/helm/chart-testing/releases/download/v3.0.0-beta.1/chart-testing_3.0.0-beta.1_linux_amd64.tar.gz -O /tmp/ct.tar.gz \
+    && cd /tmp \
+    && tar -xf ct.tar.gz \
+    && mv ct /usr/local/bin/ct
+
+COPY base-requirements.txt ./
+
+RUN pip3 install -r base-requirements.txt && rm base-requirements.txt
+
+RUN apt-get install bash-completion -y
+
+RUN printf "#!/bin/sh\nexit 0" > /usr/sbin/policy-rc.d
+
+# Allows the SSH user to pass environment variables into their SSH session
+# For this stage of development this is useful as it allows the TANGO_HOST
+# to be overwritten by the user.
+RUN echo "PermitUserEnvironment yes" >> /etc/ssh/sshd_config
+
+RUN echo "X11UseLocalhost no" >> /etc/ssh/sshd_config
+
+RUN echo "if [[ ! -d ~/skampi ]]; then " >> /home/tango/.bashrc
+RUN echo "  git clone https://gitlab.com/ska-telescope/skampi.git" >> /home/tango/.bashrc
+RUN echo "fi" >> /home/tango/.bashrc
+
+# SSH login fix. Otherwise user is kicked off after login
+RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
+
+ENV NOTVISIBLE "in users profile"
+RUN echo "export VISIBLE=now" >> /etc/profile
+
+RUN tar -xvzf vscode-server.tar -C /home/tango/
+
+EXPOSE 22
+CMD ["/usr/sbin/sshd", "-D"]
diff --git a/docker/tango/tango-vscode/Makefile b/docker/tango/tango-vscode/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9f046a948604496191fe3dcfb695d21018b6435b
--- /dev/null
+++ b/docker/tango/tango-vscode/Makefile
@@ -0,0 +1,7 @@
+include ../../make/Makefile
+
+pre-build:
+	@echo do some stuff before the docker build
+
+post-build:
+	@echo do some stuff after the docker build
\ No newline at end of file
diff --git a/docker/tango/tango-vscode/base-requirements.txt b/docker/tango/tango-vscode/base-requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..693856abe08cd3986bde45761ae5967e18feead6
--- /dev/null
+++ b/docker/tango/tango-vscode/base-requirements.txt
@@ -0,0 +1,25 @@
+pytest
+pytest-cov
+pytest-json-report
+pycodestyle<2.7.0,>=2.6.0a1
+pytest-bdd
+elasticsearch
+kubernetes
+pytest-runner
+sphinx
+recommonmark
+assertpy
+astropy
+marshmallow
+mock
+importlib
+pyyaml
+pytest-ordering
+kubernetes
+elasticsearch-dsl
+aiohttp
+aiojobs
+pytest-asyncio
+ska_logging
+aiohttp_cors
+flake8
\ No newline at end of file
diff --git a/docker/tango/tango-vscode/vscode-server.tar b/docker/tango/tango-vscode/vscode-server.tar
new file mode 100644
index 0000000000000000000000000000000000000000..fff82513a0c73a7f67c328ba7c7a567024808679
Binary files /dev/null and b/docker/tango/tango-vscode/vscode-server.tar differ