TI-Stack with docker-compose

I am playing around with telegraf and influxdb v2. I want to get both running in Docker, using docker-compose. This post explains how to do it, but it lets telegraf use the admin token, which I do not like.
I want to create a special user with only write access to a specific bucket.

There are a lot of OS solutions for this out there using InfluxDB 1, but in InfluxDB 2 this has gotten difficult: The telegraf plugin now requires a token. The influx CLI does not let me choose a token. Hence, there is this temporal dependency where I first have to run InfluxDB, then create the user and the token, and then set the token in telegraf (e.g. as an environment variable). This is not possible with a single docker-compose file. Curiously enough, the influx setup script actually would let me specify the token myself, but I can only run this once for an org. Am I missing something?

So my current solution uses two docker-compose files and the following script to up both:

docker-compose -f docker-compose.influxdb.yaml up -d
INFLUXDB_TELEGRAF_TOKEN=$token docker-compose -f docker-compose.telegraf.yaml up -d

This is the script I currently use to setup the metrics bucket:

set -e
metrics_bucket_id=$(influx bucket create -n metrics -o myorg --hide-headers | awk '{print $1}')
influx user create -n telegraf -o myorg
influx auth create -u telegraf -d telegraf_token -o myorg --write-bucket $metrics_bucket_id

My influxdb docker-compose file sets the admin account using the DOCKER_INFLUXDB_INIT_* variables, and mounts the above script to /docker-entrypoint-initdb.d.

Are there any better ideas for this? Or is my aversion of using the admin user misguided?

You could use a start script in influxdb like you are to create the user and then do a volume share between the containers but I don’t think it is exactly worth the effort. You can always just start one container at a time with docker-compose on first start.

That helped me a lot!

Your answer contains two bits of information which I did not think/know about:

  1. I only need to create and extract the token on first start, after that the token will persist in the mounted volume
  2. It is possible to start a specific container of a docker-compose file

So what I will try to do is: for the first start extract the token with the script, but then, instead of providing it as an environment variable to the docker-compose command, I persist it in a local .env file. All successive starts are a simple docker-compose up.


Glad to have helped :slight_smile:

Always something new to learn.

care to share the result?

I made it work, the next challenge was that telegraf inside docker has to observe the host.

here is the relevant part of my docker-compose:

version: '3'
        image: influxdb:2.0.4
        container_name: influxdb
        - 8086:8086
        - ./influxdb/scripts:/docker-entrypoint-initdb.d # setup.sh, see my previous post
        - influxdb-storage:/var/lib/influxdb2
        - influxdb-config:/etc/influxdb2  # Stores credentials, so docker exec does not need them
        image: telegraf:1.18.1
        container_name: telegraf
        - ./telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro
        - /:/hostfs:ro # to enable collecting metrics from the host
        - HOST_ETC=/hostfs/etc # to enable collecting metrics from the host
        - HOST_PROC=/hostfs/proc
        - HOST_SYS=/hostfs/sys
        - HOST_MOUNT_PREFIX=/hostfs
        - influxdb
        privileged: true

the script I run for first startup:

# This script has to be run on first startup of the TI-Stack. 
# Every startup after that can simply be done by docker-compose up
# The reason for this script is that the influxdb token for telegraf
# has to be set as an environment variable to the telegraf container,
# but the token is only created after the first startup of influxdb.
wait_for_influxdb() {
    echo -n "Waiting for InfluxDB "
    until $(curl --output /dev/null --silent --head --fail http://localhost:8086); do
        echo -n "."
        sleep 1
        i=$((i + 1))
        if [[ $i -gt 15 ]] ; then
            echo " Timeout. InfluxDB container is not reachable."
            return 1
    echo " Success."
    return 0

docker-compose up -d influxdb
token=$(docker exec -it influxdb influx auth list | grep telegraf_token | awk '{print $3}')
echo INFLUXDB_TELEGRAF_TOKEN=$token >> .env
docker-compose up -d telegraf

Please consider that the security of this solution relies on the attacker not having access to the server: the credentials are stored plain-text in the .env file, and docker-exec does not even require the token.

1 Like