Using Tango docker containers

Intended audience: advanced developers, Programming language: all

In this section we describe how one can test newly developed tango device server using docker containers.

Tango docker containers provide a lightweight solution for deploying tango, especially useful for local workstation development.

To get info on how to install docker on your machine please refer to the docker documentation.

Once docker is installed one can pull docker images with pre-installed tango.

Tango docker containers

SKAO provides several docker containers for Tango development and deployment, including but not limited to:

  • tango-db: a (mysql-compatible) mariadb container with the Tango schema

  • tango-cpp: a container with core Tango libraries and dependencies that can run the DatabaseDS Device Server

  • tango-rest: a Tango REST server

  • tango-test: the well-established TangoTest device server

These container images are hosted on SKAO Nexus service: https://artefact.skao.int/#browse/browse:docker-all from where they can be pulled with the prefix artefact.skao.int/

The sources for these docker images are hosted and maintained on the SKAO gitlab: https://gitlab.com/ska-telescope/ska-tango-images

Tango docker stack

The easiest way to setup the whole stack on a local development/test computer is to use docker compose

Here is a very small example of docker-compose.yml which runs up the DB and the Database Device Server:

version: '3'
networks:
  tango-net:
    name: tango-net
    driver: bridge

services:
  tango-db:
    image: artefact.skao.int/ska-tango-images-tango-db:10.4.19
    platform: linux/x86_64
    networks:
      - tango-net
    ports:
      - "9999:3306"
    environment:
      - MARIADB_ROOT_PASSWORD=root
      - MARIADB_DATABASE=tango
      - MARIADB_USER=tango
      - MARIADB_PASSWORD=tango

  tango-dbds:
    image: artefact.skao.int/ska-tango-images-tango-cpp:9.4.1
    platform: linux/x86_64
    networks:
      - tango-net
    ports:
      - "10000:10000"
    environment:
      - TANGO_HOST=localhost:10000
      - MYSQL_HOST=tango-db:3306
      - MYSQL_USER=tango
      - MYSQL_PASSWORD=tango
      - MYSQL_DATABASE=tango
    links:
      - "tango-db:localhost"
    depends_on:
      - tango-db
    # Alternative to use health-check as a depends_on/condition
    # is to wait for port to be open:
    entrypoint:
      - /usr/local/bin/wait-for-it.sh
      - tango-db:3306 --timeout=30 --strict
      - --
      - /usr/local/bin/DataBaseds 2 -ORBendPoint giop:tcp::10000

To start the whole stack execute docker compose up in the same directory as the above docker-compose yaml file.

Note

docker compose (V2) is installed by default with Docker Desktop. However, if you have another type of docker/container installation then you may be able to use docker-compose up instead - or install the newer docker compose V2 manually from here: https://docs.docker.com/compose/

Once docker containers are up and running one can access the database on localhost:9999 and the tango host on localhost:10000

For instance, one can start jive (assuming it is installed on the system) and use the Jive GUI to interact with the Device Servers, running in the containers.

Tango docker stack for Tango REST API

One can setup Tango docker stack for Tango REST API as well. SKAO provides a containerized build of the Tango Rest Server.

The following compose.yaml compose.yaml assembles the whole stack:

version: '3'
networks:
  tango-net:
    name: tango-net
    driver: bridge

services:
  tango-db:
    image: artefact.skao.int/ska-tango-images-tango-db:10.4.19
    platform: linux/x86_64
    networks:
      - tango-net
    ports:
      - "9999:3306"
    environment:
      - MARIADB_ROOT_PASSWORD=root
      - MARIADB_DATABASE=tango
      - MARIADB_USER=tango
      - MARIADB_PASSWORD=tango

  tango-dbds:
    image: artefact.skao.int/ska-tango-images-tango-cpp:9.4.1
    platform: linux/x86_64
    networks:
      - tango-net
    ports:
      - "10000:10000"
    environment:
      - TANGO_HOST=localhost:10000
      - MYSQL_HOST=tango-db:3306
      - MYSQL_USER=tango
      - MYSQL_PASSWORD=tango
      - MYSQL_DATABASE=tango
    links:
      - "tango-db:localhost"
    depends_on:
      - tango-db
    # The proper way to wait for a service to be ready is to use a container health-check. 
    # However, this is not yet available in the container image. So an alternative approach
    # is to wait for port to be open:
    entrypoint:
      - /usr/local/bin/wait-for-it.sh
      - tango-db:3306 --timeout=30 --strict
      - --
      - /usr/local/bin/DataBaseds 2 -ORBendPoint giop:tcp:0.0.0.0:10000

  tango-rest:
    image: artefact.skao.int/ska-tango-images-tango-rest:1.14.8
    platform: linux/x86_64
    networks:
      - tango-net
    ports:
      - "8080:8080"
    environment:
      - TANGO_HOST=tango-dbds:10000
    links:
      - "tango-dbds:localhost"
    depends_on:
      - tango-dbds
    entrypoint:
      - /usr/local/bin/wait-for-it.sh
      - tango-dbds:10000 --timeout=30 --strict
      - --
      - /usr/bin/supervisord --configuration /etc/supervisor/supervisord.conf

  tango-test:
    image: artefact.skao.int/ska-tango-images-tango-test:3.0.5
    platform: linux/x86_64
    networks:
      - tango-net
    environment:
      - TANGO_HOST=tango-dbds:10000
    links:
      - "tango-dbds:localhost"
    depends_on:
      - tango-dbds
    entrypoint:
      - /usr/local/bin/wait-for-it.sh
      - tango-dbds:10000 --timeout=30 --strict
      - --
      - /usr/local/bin/TangoTest test

Note this is almost the same as the previous, except we have added tango-rest and tango-test containers. A few seconds after the stack has been started with docker compose up, the Tango REST API can be accessed at http://localhost:8080/tango/rest/rc4/

The default username/password is tango-cs/tango and an example query from the host might look like this:

curl -s -u "tango-cs:tango" http://localhost:8080/tango/rest/rc4/hosts/tango-dbds/10000/devices/dserver/TangoTest/test/ | python3 -m json.tool
{
    "name": "dserver/TangoTest/test",
    "info": {
        "last_exported": "3rd April 2023 at 14:59:32",
        "last_unexported": "3rd April 2023 at 14:59:23",
        "name": "dserver/tangotest/test",
        "ior": "IOR:010000001700000049444c3a54616e676f2f4465766963655f353a312e3000000100000000000000ad000000010102000b0000003137322e31382e302e340000e7ce00000e000000fed4e92a6400000001000000000100000300000000000000080000000100000000545441010000001c000000010000000100010001000000010001050901010001000000090101000254544141000000010000000d00000036343139356661396237343500000000250000002f746d702f6f6d6e692d74616e676f2f3030303030303030312d3136383035333339373200",
        "version": "5",
        "exported": true,
        "pid": 1,
        "server": "TangoTest/test",
        "hostname": "64195fa9b745",
        "classname": "unknown",
        "is_taco": false
    },
    "attributes": "http://localhost:8080/tango/rest/rc4/hosts/tango-dbds/10000/devices/dserver/TangoTest/test//attributes",
    "commands": "http://localhost:8080/tango/rest/rc4/hosts/tango-dbds/10000/devices/dserver/TangoTest/test//commands",
    "pipes": "http://localhost:8080/tango/rest/rc4/hosts/tango-dbds/10000/devices/dserver/TangoTest/test//pipes",
    "properties": "http://localhost:8080/tango/rest/rc4/hosts/tango-dbds/10000/devices/dserver/TangoTest/test//properties",
    "state": "http://localhost:8080/tango/rest/rc4/hosts/tango-dbds/10000/devices/dserver/TangoTest/test//state",
    "_links": {
        "_self": "http://localhost:8080/tango/rest/rc4/hosts/tango-dbds/10000/devices/dserver/TangoTest/test/",
        "_parent": "http://localhost:8080/tango/rest/rc4/hosts/tango-dbds/10000/devices/dserver/"
    }
}