# Dockerized LAVA

The [Dockerfile](Dockerfile) in this directory creates an image based on the
LAVA Debian packaging that exists in the repository for lava-server. You can
use it using regular docker commands and an environment file with at least the
following variables:

```
INSTANCE_NAME=<arbitrary name>
DATABASE_URL=<database>://<user>:<password>@<host>:<port>/<database>
SECRET_KEY=<django's secret key>
ALLOWED_HOSTS=<hosts that can connect to the django server>
```

All of these are regular Django settings that would go into settings.py
`or local_settings.py except for DATABASE_URL, which is specific to the
django-environ library. The reason we use that instead of having variables
for each piece of the database configuration is django-environ handles
corner cases like using sqlite's memory backend for us.

Find more information on the format and database-specific quirks in
[django-environ's documentation](https://django-environ.readthedocs.io/en/latest/).

In addition to lava-server there are also Dockerfile setups for a sinmple
packages build [Dockerfile.build](Dockerfile.build), a dispatcher/worker
[Dockerfile.dispatcher](Dockerfile.dispatcher), which depends on the image from
the packages build, and one for providing the `lavacli` command line utility
[Dockerfile.lavacli](Dockerfile.lavacli).

To use the dispatcher/worker image you can specify the following
variables:

```
WORKER_NAME=--name <name>
URL=--url http://<host>:<port>/
WS_URL=--ws-url http://<host>:<ws-port>/ws/
LOGLEVEL=--log-level <level>
TOKEN=--token <token>
```

They are basically the same you will need to set up in the configuration
file if you use the package. Note that lava-server opens two ports, which
by default are 8000 and 8001, the first one is for `URL` and the second
is the web socket port, `WS_URL`.

## Using docker-compose

A [basic docker-compose file](docker-compose.yaml) exists that can serve as a
basis for your own setup. It specifies 2 volumes, `lavaconfig` and `lavadbdata`
to be used for mounting configuration and database directories respectively.
The actual volumes created and used by docker-compose will get a prefix based on
the directory that hosts the compose file.

For instance, if you simply use the files provided in this repository to start
your lava-server instance the volumes will have a `collabora_` prefix:

```
kov@cereja ~/L/lava> docker volume ls
DRIVER    VOLUME NAME
local     collabora_lavaconfig
local     collabora_lavadbdata
kov@cereja ~/L/lava>
```

It is possible to simply use this base compose file along with a minimal local
override, as long as you have the PostgreSQL server set up with the appropriate
user and database created. First create the override file at the root of the
repository to specify the variables:

```
$ cat docker-compose.local.yaml
version: "3"

services:
    lava:
        environment:
            - INSTANCE_NAME=collabora
            - DATABASE_URL=postgresql://lavaserver:lavapass@db:5432/lavaserver
            - SECRET_KEY=a-ib@8x^c!-n=xf!831@ka$0&x2h8k%ml+is_x!+hn&kcjklt)
            - ALLOWED_HOSTS=*
$
```

You can then fire it up from the root of the repository by running
docker-compose like this:

```
$ docker-compose -f docker/collabora/docker-compose.yaml -f docker-compose.local.yaml up
```

### Ports and reverse-proxying

Running the default compose service will open 2 new ports on your localhost:
`8000` is the main LAVA server instance. It is where you should point your main
reverse proxy to. A second port, `8001` is also opened and is for the web
socket used by the dispatcher/worker.

This is what an apache2 mod-proxy configuration would look like:

```
    # Send web socket requests to lava-publisher
    ProxyPass /ws/ ws://127.0.0.1:8001/ws/
    ProxyPassReverse /ws/ ws://127.0.0.1:8001/ws/

    # Send request to Gunicorn
    ProxyPass / http://127.0.0.1:8000/
    ProxyPassReverse / http://127.0.0.1:8000/
    ProxyPreserveHost On
```

### Dispatcher configuration and tokens

When setting up the worker, if you are using a gateway like Apache or Nginx you
don't need to worry about the two different ports as they will all be available
through the same one. If you set up a worker talking directly to the
containers, though, don't forget that there are two separate ports.

The key settings are `URL`, which should point to the server URL, and `WS_URL`
that should point to the server URL with `/ws/` appended at the end. This
suffix is crucial for it to work.

The final key setting is `TOKEN`, which you obtain when you create the worker
on the LAVA server. If you use the Django admin web interface, you will see the
token at the bottom of the page. You can just copy it out of there and put it
in your configuration file.

The token is also shown when you use the `lava-server manage` command line
tool to create the worker on the server, of when querying worker details:

```
# lava-server manage workers details ci.worker
hostname   : my.worker
state      : Offline
health     : Active
description:
token      : kfiq2vPsNqH7Pj22rMCQYN0lLDeV7nMe
devices    : 1
#
```

A worker configuration for the worker above may look something like this:

```
$ cat /etc/lava-dispatcher/lava-worker
# Configuration for lava-worker daemon

# worker name
# Should be set for host that have random hostname (containers, ...)
# The name can be any unique string.
WORKER_NAME="--name my.worker"

# Logging level should be uppercase (DEBUG, INFO, WARN, ERROR)
# LOGLEVEL="DEBUG"

# Server connection
URL="http://lava.internal/"
TOKEN="--token kfiq2vPsNqH7Pj22rMCQYN0lLDeV7nMe"
WS_URL="--ws-url http://lava.internal/ws/"
# HTTP_TIMEOUT="--http-timeout 600"
$
```

Note that `WORKER_NAME` may be very important here as well. If your worker does
not have an FQDN or if you set a name other than the server's FQDN when
creating it on server, then you need to set this to match.

### Dockerized database

If you prefer to not have to deal with the database yourself, you can use the
sample [docker-compose.server-db.yaml](docker-compose.server-db.yaml) override.
You can use it where it is, and it will use the sample database configuration.
Or, if you prefer setting your own username, password, secret key and so on,
you should copy the file over to the root of the repository renaming it to
`docker-compose.local.yaml` so you can use the same command as above, and edit
it to your hearts' content.

If you do prefer to use the provided sample configuration, you can simply run
it like this:

```
$ docker-compose -f docker/collabora/docker-compose.yaml -f docker/collabora/docker-compose.server-db.yaml up
```

### Dockerized dispatcher/worker

We recommend running the worker directly on a host using the Debian package.
The main reason for that is giving access to all of the resources needed to
properly control the boards may be tricky, while at the same time the worker is
small and doesn't have a lot of configuration or state.

If you do prefer to run the worker on docker you can use the
[Dockerfile.dispatcher](Dockerfile.dispatcher) file after building the base
build image from [Dockerfile.build](Dockerfile.build).

### Dockerize all the things!

In the repository you can find
[docker-compose.ci.yaml](docker-compose.ci.yaml), used for our CI test run but
which can be used as a docker-compose override to run everything as a container
on the same host. If you intend to use that you will benefit from reading
through the scripts used by the CI, since you first need to set up a worker on
the server before the dispatcher service will work, for instance.

A good place to start is the [ci-run](ci-run) script, which calls out to the
other scripts that build, set up and start the various services in order.
