Docker: Setting up Prometheus, Grafana and Postgres with TLS via Step-Ca
Following on from my post about setting up Gitea and the adventures into docker here https://www.rjruss.info/2024/11/docker-setting-up-gitea-with-postgres.html
I decided to add Grafana and Prometheus into my homelab setup. Using TLS via step-ca as well, as using encryption is an increasingly important activity in my day job.
It got complicated via some cyber security reasons around storing passwords in clear text. Some security frameworks state that this issue is an instant fail/breach. Grafana stores the database password in clear text. I did mask the Grafana password by using Postgres pure “cert” authentication and not use the actual password but chose to use a “-” character in the Grafana ini file.
The Postgres setup was the main driver to split out my docker compose and Dockerfiles into single targeted service related files. I wanted to use my Postgres config in my Gitea project but it was tangled up inside the global Docker and compose files of my original Gitea project. So I chose to split it all out into individual compose and docker files (that are dependent) and combine them into a controlling compose file using the “include” notation. It does not use any provided docker hub or other setup, I chose to install the software during the build on a prepared base image. The version control is in the .env file. And also the entry command scripts are based on one general control script “template_start_script.sh” to try and keep consistency in the approach.
An important step for enabling consistent certificate generation is time syncing across servers. I set up the following on a new Ubuntu server connecting to the step-ca running on an Alma linux host. I use Google and Cloudflare time sync for my linux servers, time sync is not covered here but an example to check time sync source follows. Creating certificates will fail if the time between servers is out of the permitted range.
Ubuntu checks with timedatectl
# timedatectl show-timesync
SystemNTPServers=time.google.com time.cloudflare.com
FallbackNTPServers=ntp.ubuntu.com
Alma checks with chronyc
# chronyc sources
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^+ time2.google.com 1 6 77 17 -1734us[ +245us] +/- 11ms
^* time.cloudflare.com 3 6 77 16 +1937us[+3929us] +/- 15ms
The following is based on downloading the git repo and setting up the pre-reqs, it's been tested on Alma and Ubuntu linux systems.
*All steps need to be executed by the root user unless otherwise stated
Step 1 setup local user and directory
Creating a dedicated docker user in this example dockeruser1 - if this is changed the .env file needs to be adapted in step 2
The directory where the downloaded project is stored can be adapted as well.
The example uses /srv/docker-config
Example using the name of the downloaded zip as prometheus-grafana-postgres-docker
Step 2 Adapt the .env file
Change bold entries if required and ignore any other settings in the .env file
Local docker user and group needs to match the user created in step 1
** it is important that the TX_STEP_HOST variable points to a working step-ca service check with the following command (using this as an example). This should display the root certificate of the step-ca service.
The above would be allow the services to be accessed
Via the docker user
Adapt the dockeruser1 - group dockeruser1 is used by default
Via the shared group
Adapt the group id of 5501 a new group will be created with that gid
Via a new directory/volume (it will be created if it does not exist)
Adapt the /docker-vol1
Via the following domain, hostname and ports
rjruss.org = this needs to be adapted to the required domain
ubhost-step = for step-ca hostname
ubhost-post1 = postgres hostname
ubhost-grafana = grafana hostname
ubhost-prom = prometheus hostname
ubhost-nodeexp = node exporter hostname
Grafana port = 5009
Prometheus port = 9091
Alert Manager port = 9094
Node Exporter port = 9021
MY_HOST_FQDN = FQDN of current host server
(postgres is not by default open to connections other than on the docker network and uses the standard postgres port 5432 in the docker network)
Step 3 adapt the age related password files
The age (see step 4) command is used to store passwords in an encrypted file on a docker volume. These can be shared between containers via the bash scripts in the base docker container build.
These .*.info files should be deleted ***after completing the step 4 process***
#Grafana DB connection password (not used but can be used if postgres config adapted)
Step 4 Create Volumes, Networks and encrypted passwords
Following script installs operating system pre-req packages, volumes, networks and encrypts the passwords.
After running the script the following volumes and network will be available.
[root@zhawalma monitor]# docker volume ls |grep tx
local tx_monitor_grafana_vol1
local tx_monitor_info_vol1
local tx_monitor_keys_vol1
local tx_monitor_node_exporter_vol1
local tx_monitor_pgdata_vol1
local tx_monitor_prometheus_vol1
[root@zhawalma monitor]# docker network ls |grep tx
5c122c720cc6 tx-monitor-net1 bridge local
[root@zhawalma monitor]#
**** delete these password files ****ENSURE YOU KNOW THE PASSWORDS before deleting**** the current password used in all files is testing!123
ls -a .*.info
Step 5 build and run it
The script “build-it-and-run-it.sh” checks the step-ca hostname via TX_STEP_HOST in the .env file. As all services rely on TLS and step-ca then the script will fail if it cannot resolve the defined step host.
Step 6 Setup host windows/client computer
Install step-ca root certificate on host windows
Download the root CA certificate and ignore the certificate with the “-k” option as it will be subsequently installed. This is based on the step-ca running in this project.
Using Powershell add the downloaded certificate as trusted.
Answer YES at the prompt
I have a homelab Hyper-V landscape with a windows DNS host, and it is important to set up dns resolution for Grafana and Prometheus.
For my local windows based P.C I updated the host file with the Grafana and Prometheus hostnames so they resolve.
By default the hostname is ubhost-grafana.rjruss.org and ubhost-prom.rjruss.org
Step 7 Access Grafana, Prometheus and Alert Manager
Grafana - user is “admin” with password set in .GRAF.info
https://ubhost-grafana.rjruss.org:5009/login
Prometheus
https://ubhost-prom.rjruss.org:9091/
Check the targets setup for node-exporter and prometheus - both should be “up”
Alert Manager
https://ubhost-prom.rjruss.org:9094/
Miscellaneous actions
Remove demo certs from certstore, from the example code only - if the root CA name is changed then the *basestep* match won't match any…..