# Docker compose

You can run the application as docker compose service. 
It is based on the production Dockerfile.

Advantages:
* it has the same OS and software environment as production
* it can be run in any architecture (x86, arm)

Docker compose consists of 2 services:
* decider - the service that listens to SWF and triggers workers
* worker - the service that executes the tasks

All services share the same docker image.

Note: you can spin up multiple workers to increase the throughput.

## Pre-requisites
1. have docker and docker-compose installed
2. Configure `.env` file as described in the [Configure `.env` file](README.md#configure-env-file) section
Note: There is no need saving AWS_* env variables to `.env` 
The keys will be propagated to the container from your shell directly.

## Build

Build process need to do it only once.
(Until you change something in dependencies or Dockerfile)

Note: You need to have active VPN connection when building the image 
in order to access dependent Python libraries from corporate packages index.

Docker image is based on the production Dockerfile. 
Base image is located in PROD AWS account ECR,
so we need to login to ECR in order to pull the base image.

```shell script
$ awsume dev
MFA Token: .....
$ make docker_login
$ docker compose build
```

## Run

To run the containers you need to have fresh AWS_ creds for dev account.
Follow the steps in [Configure `.env` file](README.md#configure-env-file) section.

Note: no need saving AWS_* to `.env` file. You can run `awsume dev` in your shell.
The keys env variables will be propagated to the container from the shell.

__IMPORTANT__: You need to set `DOCKER_COMPOSE_FLOW` in `.env`
to the flow you are working on (e.g. `DOCKER_COMPOSE_FLOW=apple_music_streams`)

The source code will be mounted as volume, 
so you do not need to rebuild the image between code changes.

To start the service run the following commands:

```shell script
$ awsumde dev
$ docker compose up
```
Note: after 1 hour your session token will expire, and you will need to stop the service and then rerun the commands again.

## Trigger SWF execution

After you have your service up you can trigger execution:
Below as example we trigger `apple_music_streams` flow with specified context.
```shell
$ docker compose exec worker garcon exec apple_music_streams -c '{"context_date": "2024-06-16", "licensor": "theorchard"}'
```
If you want to stop all active executions in your SWF_DOMAIN:
```shell
$ docker compose exec worker python ./feed_ingestion/bin/swf-stop.py
```

## Run unit tests and linter

```shell
$ docker compose exec worker make test_unit
$ docker compose exec worker make lint
```

__Known issue__: some unit tests are failing in the docker container (about 28)
It happends because bad isolation of unit tests from environment variables.
The fix should not be difficult, but it is not a priority now. 

## Internals

In `Dockerfile` new argument IS_DEV was introduced. If it set to `true` then the image will include development aspects.

## Debugging

You can have shell to worker container:

```shell
$ docker compose exec worker bash
```

It is also possible to run PyCharm debugger in the container.
The detail instruction can be provided additionally.
Refer to Egor Fedorov for help.
