# 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/"
        }
    }