LibreNMS & docker-compose

If you don’t know LibreNMS, it is a great monitoring tool with auto discovery, auto operating system detection, custom alert settings, extended application support and more. For details check out: https://www.librenms.org, https://github.com/librenms

I was recently deploying it with docker-compose and ran into an issue, whenever I’d run docker-compose up -d I’d see the following warnings:

WARNING: The TZ variable is not set. Defaulting to a blank string.
WARNING: The MYSQL_DATABASE variable is not set. Defaulting to a blank string.
WARNING: The MYSQL_USER variable is not set. Defaulting to a blank string.
WARNING: The MYSQL_PASSWORD variable is not set. Defaulting to a blank string.
WARNING: The PUID variable is not set. Defaulting to a blank string.
WARNING: The PGID variable is not set. Defaulting to a blank string.

Then docker-compose logs -f would say:

dispatcher_1  | ERROR: Either DB_PASSWORD or DB_PASSWORD_FILE must be defined
librenms      | ERROR: Either DB_PASSWORD or DB_PASSWORD_FILE must be defined
snmptrapd_1   | ERROR: Either DB_PASSWORD or DB_PASSWORD_FILE must be defined

But wait, I have defined those in librenms.env, then what is the matter? Also some are not mandatory. After looking into a bunch of things I added a new user, became the new user and run docker-compose as the new user.

sudo adduser librenms --disabled-password --home /home/librenms --no-create-home --gecos ''
sudo su - librenms

C’est la vie, no more warning, no more errors. Good! As later turned out I wasn’t done yet. The were no LibreNMS graphs. I started looking into this. The solution was to make the data directory used by the LibreNMS containers owned by librenms:docker

sudo chown -R librenms:docker /data/librenms/

In my case all volumes live under /data/librenms

    volumes:
      - "/data/librenms/db:/var/lib/mysql"
--
    volumes:
      - "/data/librenms/librenms/rrd:/data/db"
      - "/data/librenms/rrd-journal:/data/journal"
--
    volumes:
      - "/data/librenms/data:/data"
--
    volumes:
      - "/data/librenms/data:/data"
 --
    volumes:
      - "/data/librenms/data:/data

With this my LibreNMS started to work as expected. Yay!

Example files for docker-compose and environment variables can be found on the LibreNMS github site. Pay lots of attention to the environment variables!


I’m including my slightly edited configuration files:

docker-compose.yaml

replace: yourdomain.com with YOUR domain, db and other container versions might update by the time you are reading this, read up about them before deploying

version: "3.5"

services:
  db:
    image: mariadb:10.5
    container_name: librenms_db
    command:
      - "mysqld"
      - "--innodb-file-per-table=1"
      - "--lower-case-table-names=0"
      - "--character-set-server=utf8"
      - "--collation-server=utf8_unicode_ci"
    volumes:
      - "/data/librenms/db:/var/lib/mysql"
    environment:
      - "TZ=${TZ}"
      - "MYSQL_ALLOW_EMPTY_PASSWORD=yes"
      - "MYSQL_DATABASE=${MYSQL_DATABASE}"
      - "MYSQL_USER=${MYSQL_USER}"
      - "MYSQL_PASSWORD=${MYSQL_PASSWORD}"
    restart: always

  memcached:
    image: memcached:alpine
    container_name: librenms_memcached
    environment:
      - "TZ=${TZ}"
    restart: always

  redis:
    image: redis:5.0-alpine
    container_name: librenms_redis
    environment:
      - "TZ=${TZ}"
    restart: always

  rrdcached:
    image: crazymax/rrdcached
    container_name: librenms_rrdcached
    volumes:
      - "/data/librenms/librenms/rrd:/data/db"
      - "/data/librenms/rrd-journal:/data/journal"
    environment:
      - "TZ=${TZ}"
      - "PUID=${PUID}"
      - "PGID=${PGID}"
      - "LOG_LEVEL=LOG_INFO"
      - "WRITE_TIMEOUT=1800"
      - "WRITE_JITTER=1800"
      - "WRITE_THREADS=4"
      - "FLUSH_DEAD_DATA_INTERVAL=3600"
    restart: always

  msmtpd:
    image: crazymax/msmtpd:latest
    container_name: librenms_msmtpd
    env_file:
      - "./msmtpd.env"
    restart: always

  librenms:
    image: librenms/librenms:latest
    container_name: librenms
    domainname: yourdomain.com
    hostname: librenms
    ports:
      - target: 8000
        published: 8000
        protocol: tcp
    depends_on:
      - db
      - memcached
      - rrdcached
      - msmtpd
    volumes:
      - "/data/librenms/data:/data"
    env_file:
      - "./librenms.env"
    environment:
      - "TZ=${TZ}"
      - "PUID=${PUID}"
      - "PGID=${PGID}"
      - "DB_HOST=db"
      - "DB_NAME=${MYSQL_DATABASE}"
      - "DB_USER=${MYSQL_USER}"
      - "DB_PASSWORD=${MYSQL_PASSWORD}"
      - "DB_TIMEOUT=60"
    restart: always

  dispatcher:
    image: librenms/librenms:latest
    container_name: librenms_dispatcher
    domainname: yourdomain.com
    hostname: librenms
    depends_on:
      - librenms
      - redis
    volumes:
      - "/data/librenms/data:/data"
    env_file:
      - "./librenms.env"
    environment:
      - "TZ=${TZ}"
      - "PUID=${PUID}"
      - "PGID=${PGID}"
      - "DB_HOST=db"
      - "DB_NAME=${MYSQL_DATABASE}"
      - "DB_USER=${MYSQL_USER}"
      - "DB_PASSWORD=${MYSQL_PASSWORD}"
      - "DB_TIMEOUT=60"
      - "REDIS_HOST=redis"
      - "REDIS_PORT=6379"
      - "REDIS_DB=0"
      - "SIDECAR_DISPATCHER=1"
    restart: always

  syslog-ng:
    image: librenms/librenms:latest
    container_name: librenms_syslog
    domainname: example.com
    hostname: librenms
    depends_on:
      - librenms
    ports:
      - target: 514
        published: 514
        protocol: tcp
      - target: 514
        published: 514
        protocol: udp
    volumes:
      - "/data/librenms/data:/data"
    env_file:
      - "./librenms.env"
    environment:
      - "TZ=${TZ}"
      - "PUID=${PUID}"
      - "PGID=${PGID}"
      - "DB_HOST=db"
      - "DB_NAME=${MYSQL_DATABASE}"
      - "DB_USER=${MYSQL_USER}"
      - "DB_PASSWORD=${MYSQL_PASSWORD}"
      - "DB_TIMEOUT=60"
      - "SIDECAR_SYSLOGNG=1"
    restart: always
librenms.env

Replace 0.0.0.0/32 with your server’s IP, you want to define MYSQL_DATABASE / MYSQL_PASSWORD you can do it here. It is recommended to use snmp v3; encryption for the win

MEMORY_LIMIT=256M
UPLOAD_MAX_SIZE=16M
OPCACHE_MEM_SIZE=128
REAL_IP_FROM=0.0.0.0/32
REAL_IP_HEADER=X-Forwarded-For
LOG_IP_VAR=remote_addr
TZ=Etc/UTC
#PUID=1002
#PGID=1002

LIBRENMS_SNMP_COMMUNITY=librenmsdocker
MEMCACHED_HOST=memcached
MEMCACHED_PORT=11211
RRDCACHED_HOST=rrdcached
RRDCACHED_PORT=42217

LIBRENMS_SERVICE_POLLER_WORKERS=24
LIBRENMS_SERVICE_SERVICES_WORKERS=8
LIBRENMS_SERVICE_DISCOVERY_WORKERS=16

LIBRENMS_SERVICE_POLLER_FREQUENCY=300
LIBRENMS_SERVICE_SERVICES_FREQUENCY=300
LIBRENMS_SERVICE_DISCOVERY_FREQUENCY=21600
LIBRENMS_SERVICE_BILLING_FREQUENCY=300
LIBRENMS_SERVICE_BILLING_CALCULATE_FREQUENCY=60
LIBRENMS_SERVICE_POLLER_DOWN_RETRY=60
LIBRENMS_SERVICE_LOGLEVEL=INFO
LIBRENMS_SERVICE_UPDATE_FREQUENCY=86400

LIBRENMS_SERVICE_PING_ENABLED=false
LIBRENMS_SERVICE_WATCHDOG_ENABLED=false

LIBRENMS_WEATHERMAP=false
LIBRENMS_WEATHERMAP_SCHEDULE=*/5 * * * *

msmtpd.env

I’m adding gmail examples since that’s a popular email service. Please check https://github.com/crazy-max/docker-msmtpd for details

SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_TLS=on
SMTP_STARTTLS=on
SMTP_TLS_CHECKCERT=on
SMTP_AUTH=on
SMTP_USER=youruser
SMTP_PASSWORD=REDACTED
SMTP_FROM=youruser@gmail.com

Enjoy & good luck! 🍀

2024.01.06. – update: if you are migrating the docker instance to a new server make sure the directories under data are owned by the same user as before. In my case the directories under data/rrd/ were not and no new graphs were created, after I chown-ed to the same as before the graphs showed up

2 thoughts on “LibreNMS & docker-compose”

  1. in original compose of librenms there is no memcached nor rrdcached containers, why did you add them?

    1. Good question, I think when I set it up the first time it might have been there. Did you deploy it recently without it? If so do you happen to have a docker compose file that you can share?

Leave a Reply

Your email address will not be published. Required fields are marked *