Setting up a Zabbix 7 + TimescaleDB monitoring server in docker
Greetings!

In this guide we will deploy the popular Zabbix monitoring system using TimescaleDB โ€” a plugin for the PostgreSQL database that allows efficient work with “time series”. We’ll wrap all this goodness inside docker containers ๐Ÿณ. It’s going to be interesting ๐Ÿ˜‰.

Let me remind you that in one of the previous posts we discussed what monitoring systems in IT are, what kinds exist, and learned a bit about popular implementations today, among which is Zabbix.

Right away, please note that all actions described in this guide are performed at your own risk and responsibility. My blog is just a platform where I talk about my experience and share my opinion on various things and phenomena. Thanks for understanding.

Ivan Cherniy

Introduction

The distinctive feature of the installation described in this article is not just deploying the Zabbix monitoring system in docker containers, but also using it in conjunction with a time series database โ€” TimescaleDB.

Before we begin, let’s give a few definitions as an introduction.

Zabbix is an open platform for monitoring networks and servers. It uses relational DBMSs for data storage, for example: PostgreSQL, MySQL, MariaDB, Oracle, SQLite, etc.

Time series in databases is a set of data ordered by time, where values are recorded at equal or unequal time intervals.

Time series databases are specialized databases designed for efficient storage, management, and analysis of time series. These are often no sql databases.

TimescaleDB (TSDB) is an extension for PostgreSQL that optimizes working with time series in this DBMS, while preserving all the power and flexibility of classic SQL-like databases. Since some time, Zabbix has learned to work with this DBMS.

A quote from the official Zabbix documentation:

Zabbix supports TimescaleDB, a PostgreSQL-based database solution of automatically partitioning data into time-based chunks to support faster performance at scale.

Zabbix.com

For a better understanding of the reasoning behind this particular combination, I recommend an article on Habr: Zabbix, time series and TimescaleDB.

I also ask you to pay attention to the warning from the official Zabbix documentation:

Warning: Currently, TimescaleDB is not supported by Zabbix proxy.

Zabbix.com 09.2024

I’m sure this will be fixed in the future. But enough talk for now, let’s get down to business ๐Ÿคตโ€โ™‚๏ธ.

Preparation

We’ll deploy Zabbix in an environment based on the Debian 12 ๐Ÿ’ฟ distribution with Docker engine ๐Ÿณ installed. If you don’t already have a ready Linux server, I recommend my previous articles:

We will also need a user with root privileges for further work.

Hey, this article is part of a series about building your own infrastructure. Previous articles:

And here’s the diagram, with the monitoring server added to it:

Installing the required utilities

Today we’ll need utilities for interacting with the web. Open a terminal and install the git version control system and the curl utility:

BASH
sudo apt update && sudo apt install -y git curl
Click to expand and view more

Downloading the project files

All the project files are located in my repository on GitHub. Let’s clone it using the previously installed git utility into the path /opt/zabbix:

BASH
sudo git clone https://github.com/r4ven-me/zabbix /opt/zabbix
Click to expand and view more

If needed, edit the deploy block for the relevant services in the docker-compose.yml file, depending on the server resources you have available. By default, the most minimal values are used.

Creating the zabbix service user

For security purposes, we create a restricted group and a service user to run the zabbix containers:

BASH
sudo addgroup --system --gid 1995 zabbix

sudo adduser --system --gecos "Zabbix monitoring system" \
    --disabled-password --uid 1997 --ingroup zabbix  \
    --shell /sbin/nologin --home /opt/zabbix/zabbix_data zabbix
Click to expand and view more

Creating the postgres service user

Now we similarly create a group and user to run the TimescaleDB container:

BASH
sudo addgroup --system --gid 70 postgres

sudo adduser --system --gecos "PostgreSQL database" \
    --disabled-password --uid 70 --ingroup postgres  \
    --shell /sbin/nologin --home /opt/zabbix/postgres_data postgres
Click to expand and view more

Let’s check that all the necessary files and folders are present:

BASH
ls -l /opt/zabbix
Click to expand and view more

Great, let’s move on ๐Ÿšถ.

Creating a password for the Postgres database

By default, in the file /opt/zabbix/env/.POSTGRES_PASSWORD I set a password of the same name for the zabbix DB. But I highly recommend generating a new one, for example with a command like this:

BASH
tr -cd "[:alnum:]" < /dev/urandom | head -c 30 \
    | sudo tee /opt/zabbix/env/.POSTGRES_PASSWORD
Click to expand and view more

Don’t pay attention to the % character at the end of the line in my example. This is a feature of the ZSH shell, which prints it (or # for root) when there is no newline character.

Launching the Zabbix stack with docker compose

Starting the Postgres server

First we start the DBMS server, with this command:

BASH
sudo docker compose -f /opt/zabbix/docker-compose.yml up -d postgres-server
Click to expand and view more

After the image is downloaded and the container started, let’s look at its output:

BASH
sudo docker logs -f postgres-server
Click to expand and view more

On a successful start, you’ll see something like this:

On the first start, scripts for preparing the environment and basic DBMS configuration run inside the container, depending on the server’s parameters. In one of my tests, such a script set the max_connections parameter to 25 โ€” which is not enough even to import the zabbix DB schema, and the process will fail with an error:

BASH
FATAL:  sorry, too many clients already
Click to expand and view more

You can check the max_connections value with this command:

BASH
sudo grep 'max_connections' /opt/zabbix/postgres_data/postgresql.conf
Click to expand and view more

If you have <=25, this parameter needs to be increased. Open the file for editing with any console editor, for example, Vim/Neovim ๐Ÿ˜Ž:

BASH
sudo vim /opt/zabbix/postgres_data/postgresql.conf
Click to expand and view more

Find this line there:

PLAINTEXT
max_connections = 25
Click to expand and view more

And change it, for example, to:

PLAINTEXT
max_connections = 200
Click to expand and view more

Save the file, exit the editor.

To apply the changes, restart the postgres-server container and check the current max_connections value:

BASH
sudo docker compose -f /opt/zabbix/docker-compose.yml restart postgres-server

sudo docker exec -it postgres-server psql -U zabbix -c "SHOW max_connections;"
Click to expand and view more

Everything is applied, let’s move on to starting the zabbix-server container.

Starting the Zabbix server

Start it with this command:

BASH
sudo docker compose -f /opt/zabbix/docker-compose.yml up -d zabbix-server
Click to expand and view more

Let’s look at the container’s output:

BASH
sudo docker logs -f zabbix-server
Click to expand and view more

On the first start, the container will begin creating the database. This will take some time. The output will pause at this line:

PLAINTEXT
Creating 'zabbix' schema in PostgreSQL
Click to expand and view more

Make sure you wait for the database creation process to finish!

On a successful start you should see something like this:

At the very end there may be output like this:

PLAINTEXT
256:20240922:121849.602 Zabbix agent item "system.cpu.util[,system]" on host "Zabbix server" failed: first network error, wait for 15 seconds
225:20240922:121855.944 item "Zabbix server:zabbix[vmware,buffer,pused]" became not supported: No "vmware collector" processes started.
225:20240922:121858.958 item "Zabbix server:zabbix[process,report writer,avg,busy]" became not supported: No "report writer" processes started.
225:20240922:121859.962 item "Zabbix server:zabbix[process,report manager,avg,busy]" became not supported: No "report manager" processes started.
256:20240922:121904.599 Zabbix agent item "system.users.num" on host "Zabbix server" failed: another network error, wait for 15 seconds
256:20240922:121919.602 Zabbix agent item "system.cpu.load[all,avg5]" on host "Zabbix server" failed: another network error, wait for 15 seconds
225:20240922:121928.010 item "Zabbix server:zabbix[connector_queue]" became not supported: connector is not initialized: please check "StartConnectors" configuration parameter
225:20240922:121929.016 item "Zabbix server:zabbix[process,connector manager,avg,busy]" became not supported: No "connector manager" processes started.
225:20240922:121930.021 item "Zabbix server:zabbix[process,connector worker,avg,busy]" became not supported: No "connector worker" processes started.
256:20240922:121934.600 temporarily disabling Zabbix agent checks on host "Zabbix server": interface unavailable
Click to expand and view more

Don’t pay any attention to it.

Let’s check the status of the running containers:

BASH
sudo docker ps
Click to expand and view more

All good โ€” let’s move on.

Creating the schema for TimescaleDB

Let’s print the password we created earlier to the terminal, we’ll need it soon. Then let’s connect to the shell of the zabbix-server container:

BASH
sudo cat /opt/zabbix/env/.POSTGRES_PASSWORD

sudo docker exec -it zabbix-server bash
Click to expand and view more

Now let’s import the TimescaleDB schema using an SQL script that the Zabbix developers kindly included in the system files. When entering the import command, we’ll be asked for the DB password, which we printed in the previous step:

BASH
psql -h postgres-server -U zabbix zabbix < /usr/share/doc/zabbix-server-postgresql/timescaledb.sql
Click to expand and view more

The import process is simply redirecting the contents of the SQL script to the input of the DB connection command via psql.

The output should look like this:

Exit the zabbix-server container and check that there’s chunk information in Postgres:

BASH
exit

sudo docker exec -it postgres-server \
    psql -U zabbix -c "SELECT * FROM chunks_detailed_size('history')"
Click to expand and view more

If your output looks the same as in the screenshot above, then everything was imported successfully ๐Ÿฅณ.

At this point, the Postgres/TimescaleDB database and the Zabbix server are ready ๐Ÿ˜‰.

Starting the whole TimescaleDB + Zabbix server + Zabbix web + Zabbix agent stack

Let’s stop the running containers and start the whole installation, including Zabbix web and Zabbix agent:

BASH
sudo docker compose -f /opt/zabbix/docker-compose.yml down

sudo docker compose -f /opt/zabbix/docker-compose.yml up -d
Click to expand and view more

Let’s check that all containers started correctly:

BASH
sudo docker ps

sudo docker compose -f /opt/zabbix/docker-compose.yml logs -f
Click to expand and view more

Great. Now let’s check that Zabbix itself works:

BASH
curl -I http://localhost:8080

nc -zv localhost 10051

ss -tulnap | grep -E '8080|10051'
Click to expand and view more

With the first command we checked the availability of the web interface from the console, with the second โ€” the availability of the zabbix-server port, and with the third we printed the ports being listened on by the host OS.

Great, everything works ๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰.

Access to the Zabbix web interface

The way to get access to the Zabbix web interface depends on the conditions in which you deployed the stack. I’ll describe a few obvious options.

To log in to the web interface, use the standard login: Admin and password: zabbix

If you saw this:

My congratulations ๐Ÿ˜Ž! The Zabbix server with TimescaleDB is up and ready to work ๐Ÿ‘ทโ€โ™‚๏ธ.

Optional

Below are optional but recommended steps of the guide ๐Ÿ˜‰.

Minimal initial setup of the Zabbix server

Configuring autostart of the Zabbix stack with systemd

Installing and running the Zabbix agent in docker on a remote host

Setting up sending Zabbix notifications to Telegram with a graph

Conclusion

Phew..๐Ÿคฏ that was not the simplest article. Especially in terms of the amount of information processed. But, I think it was worth it. In the end we got a flexible and easily portable monitoring system project running inside docker containers. We also set up concise but informative notifications with graphs in Telegram, to always stay aware of the state of our infrastructure.

I’d also like to note the excellent work of the Zabbix developers. In particular, the relevance and variety of docker images and the availability of their build files. After writing this article, I respect them even more ๐Ÿ‘.

Thanks for reading ๐Ÿ˜Š. If you have questions โ€” I invite you to the Raven chat, as you guessed, on Telegram ๐Ÿ˜…. We have a friendly community there ๐Ÿšถโ€โ™€๏ธ๐Ÿง๐Ÿšถ๐Ÿง๐Ÿšถโ€โ™‚๏ธ๐Ÿง. And be sure to subscribe to the main Telegram channel: @r4ven_me, so you don’t miss new publications on the site.

I wish you success and an attacking prod! ๐Ÿ˜Œ

Sources used

Comments

Copyright Notice

Author: Ivan Cherniy

Link: https://r4ven.me/en/monitoring/podnimaem-server-monitoringa-zabbix-7-timescaledb-v-docker/

License: CC BY-NC-SA 4.0

Blog materials may be used with attribution to the author and source, for non-commercial purposes, and under the same license.

Start searching

Enter keywords to search articles

โ†‘โ†“
โ†ต
ESC
โŒ˜K Shortcut