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:

#!/bin/bash
...
docker-compose -f docker-compose.influxdb.yaml up -d
wait_for_influxdb
token=$(telegraf/extract-token.sh)
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:

#!/bin/bash
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.

Thanks!

Glad to have helped :slight_smile:

Always something new to learn.

care to share the result?

Sure.
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'
services:
    influxdb:
        image: influxdb:2.0.4
        container_name: influxdb
        ports: 
        - 8086:8086
        volumes:
        - ./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
        environment:
        - INFLUXD_REPORTING_DISABLED=true
        - DOCKER_INFLUXDB_INIT_MODE=setup
        - DOCKER_INFLUXDB_INIT_USERNAME=admin 
        - DOCKER_INFLUXDB_INIT_PASSWORD=${INFLUXDB_ADMIN_PASSWORD} # set in .env
        - DOCKER_INFLUXDB_INIT_ORG=myorg
        - DOCKER_INFLUXDB_INIT_BUCKET=game
    telegraf:
        image: telegraf:1.18.1
        container_name: telegraf
        volumes:
        - ./telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro
        - /:/hostfs:ro # to enable collecting metrics from the host
        environment:
        - INFLUXDB_TELEGRAF_TOKEN=${INFLUXDB_TELEGRAF_TOKEN}
        - HOST_ETC=/hostfs/etc # to enable collecting metrics from the host
        - HOST_PROC=/hostfs/proc
        - HOST_SYS=/hostfs/sys
        - HOST_MOUNT_PREFIX=/hostfs
        depends_on:
        - influxdb
        privileged: true
volumes:
    influxdb-config:
    influxdb-storage:

the script I run for first startup:

#!/bin/bash
# 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 "
    i=0
    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
        fi
    done
    echo " Success."
    return 0
}

docker-compose up -d influxdb
wait_for_influxdb
token=$(docker exec -it influxdb influx auth list | grep telegraf_token | awk '{print $3}')
sed -i '/INFLUXDB_TELEGRAF_TOKEN/d' .env
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