Creating an Elastalert Docker Image on Docker Hub

In this article I will show how I created a Docker image for Elastalert and create an automated build for the image on Docker Hub.
Among other things, I will show how to wait on other services that a service running in a Docker container depends on.

Introduction

For those who are not familiar with Elastalert I can briefly mention that it is a piece of software that can monitor data in an Elasticsearch instance and generate alerts upon detecting a variety of conditions. I were originally looking at Watcher from the makers of Elasticsearch, but it is not open source and after having failed to obtain a price quote over e-mail I gave up and started looking elsewhere.
In a subsequent article I will show how to use the Elastalert Docker image with the ELK Docker image I created in an earlier article.

# Copy the Elastalert configuration file to Elastalert home directory to be used when creating index first time an Elastalert container is launched.

cp${ELASTALERT_CONFIG}${ELASTALERT_HOME}/config.yaml&&\

# Add Elastalert to Supervisord.

supervisord-c${ELASTALERT_SUPERVISOR_CONF}

# Define mount points.

VOLUME["${CONFIG_DIR}","${RULES_DIRECTORY}","${LOG_DIR}"]

# Launch Elastalert when a container is started.

CMD["/opt/start-elastalert.sh"]

Some noteworthy things are:

Version 0.0.63 of Elastalert is used.
At the time of writing, this was the most current tag.

When using the Elastalert Docker image, you have to create a link to the Docker container in which the Elasticsearch instance that Elastalert is to query for data.
The port is assumed to be 9200.

After having installed Elastalert, there is a command “pip install -e .”.
I had some troubles when installing Elastalert and the Elastalert package did not get installed. This command fixed this (big thanks to Qmando for helping me out with this one!). If everything already has bee installed correctly, this will be detected and nothing will happen when this command is executed.

Supervisor is installed.
Supervisor is used to start Elastalert in a Docker container and to redirect log output to files.

The Elastalert and Supervisor configuration files are taken from the Elastalert download and modified slightly.

I originally wanted to create a “elastalert” user in the Docker image and run Elastalert using this user but ran into some problems that caused me to postpone this and settle for letting the root user run Elastalert.

Elastalert Start Script

The Elastalert start script were a little tricky, since Elastalert require one-time initialization and also require that the Elasticsearch instance it is to query to be online.

start-elastalert.sh

Shell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

#!/bin/sh

set-e

# Wait until Elasticsearch is online since otherwise Elastalert will fail.

Checking whether the Elasticsearch instance is online is done with the wget command. The while-loop will wait indefinitely until something answers at the Elasticsearch port and address. I did try the technique employed by docker-wait, but the script hang once the Elasticsearch instance came online.

The wget command is also used to determine if an index with the name “elastalert_status” exists in Elasticsearch. If it does not, the index is created.

Having created these two files and a readme-file, I created a new GitHub project.

Creating an Automated Build on DockerHub

First and foremost: There is no need whatsoever to push an image to DockerHub if you want to create an automated build, in which you display the Dockerfile of your image.
The following steps describes how to create an automated build on DockerHub that will build a new version of your Docker image whenever there is a change in the repository in which the source-files are stored.

Log in to DockerHub.

In the Create menu, select Create Automated Build.

Creating a new automated build in DockerHub.

If you haven’t already, you need to link your GitHub account to DockerHub.
Do this in the Link Accounts menu.

Select the repository containing your Dockerfile.
The following screen will appear:

Now is the last chance to name your Docker image.
If I were to leave the parameters in the above picture unchanged, my Docker image would be named ivankrizsan/elastalert-docker. I did not want that, so I changed “elastalert-docker” to plain “elastalert”.

Enter a short description of your Docker image.
The contents of any readme-file from your GitHub repository will be copied into the long description of the Docker image.

Configure additional tags for your Docker image.
These can be for, for instance, different version of the program that is to be run in Docker containers created from the image.

Decide whether the image is to be public or private.

Decide whether or not new pushes to the repository are to trigger automatic builds of the image.

Click the Create button.

Since I have already committed all the files to my GitHub repository, I will need to trigger the first build manually:

Hello!
It looks as you do not have any rules configured for Elastalert. You have to share the rules directory from the container with the a directory in the host OS which contains Elastalert rules.
For an example, see my example at GitHub: https://github.com/krizsan/alerting-with-elk-and-elastalert
Happy coding!

Hi Sunil!
You should set the environment variable when you run the Docker image, like in the following example:
docker run -e SET_CONTAINER_TIMEZONE=true [additional parameters] ivankrizsan/elastalert
Happy coding!

Hello!
Sorry, I have not encountered those kind of problems myself. Someone mentioned that my Elastalert image sometimes does not build properly. I suggest that you download the sources and try to build it yourself.
I am in the process of contributing the Elastalert Docker image to Yelp in order to have an official Elastalert Docker image, so I won’t make any modifications to it.