Intro

So I’ve been wanting to include a network monitoring suite in my home network for a while now. The tool I chose was “ntopng”. I already have a Raspberry Pi running, so the choice was obvious. Dockerise the installation and get it up and running on the Pi. Not as easy as I thought.

Ntopng

I’ll be super brief here, I assume you’re familiar with the tool if you’re reading this. Ntopng is a full on network monitoring tool, that’s open-source and easy to use. It’s built on top of “ntop”, the original network probe. For more info on the tool, visit their homepage here

The strategy

I wanted to Dockerise the install instead of having to install the tool “bare metal”. That choice was made for a number of reasons, one of which is that I’m apparently a masochist.
Seriously though, it’s way faster and easier to clean up a docker setup if I wanted to move to a different tool in the future. Furthermore, I wanted a challenge, I wanted something that I really had to spend some time with to get working. Yes, there’re official binaries on Ntop’s website, and yes there’s one for getting this up and running on a Raspberry. If you don’t dare to spend 8 hours on getting a docker container up, use the links above.

Ready-made images

As a dev, the first thing I thought of was: “There must be an image out there already”. Actually, there’re a number of them:
ntop/ntopng (Offical image)
joviniko/ntopng-docker
vimagic/ntopng

The thing is that the above images didn’t run properly on my Raspberry Pi. My assumption is that I might’ve overlooked a dependency somewhere, so I made the “only other choice” – build it from scratch

Pre-requisites

Redis

Ntop requires a working Redis container in the network. Honestly, this was the easiest part of this whole adventure. Here’s the docker-compose declaration for it:

version: '3'

services:
  redis:
    image: redis:alpine
    command: --save 900 1
    volumes:
      - ./data/redis:/data
    restart: on-failure:5
    network_mode: "host"

Note – I’ll talk about the network_mode: host param in a bit.

The above thing declares a new container, grabs redis:alpine from the land of docker images, and maps the /data directory to a local one.
The container is restarted 5 times if it fails and is then left alone.
The only other notable thing here is the command declaration. We invoke the save command, to ensure that we store the data. For a better explanation click here

OS/arch

This is the fun part. Ntopng supports both ARM and x86/64. That’s great. Let’s look at what they support for x64:

ntop OS and architecture support

Cool, there’s both Debian and Ubuntu. These are my preferred distros, and the ones I have the most experience with. So, I chose Debian.

ntopng on Debian

I went over to the land of docker images and grabbed Debian 11. Ntop has support for that, per this link

ntopng Debian version support

And that’s where the great things end. I set up a container with version 11 and tried to follow the guide above. And that’s when I hit integration hell.
Ntopng requires a base set of dependencies, cool, just a standard thing. The thing is that I couldn’t quite figure out which one I was missing. I kept installing and uninstalling, switching between alpine and stable, going to v 10, v 9 etc.
Four hours in I just gave up and switched over to Ubuntu, the size difference in the base image was about +3MB compressed, so whatever – I bit the bullet.
My overall experience with Debian – 3/10, would not recommend.

ntopng on Ubuntu

I grabbed 20.04 (focal) from the docker repo and got to work. As we can see here, the tool supports the latest stable versions on Ubuntu:

ntopng Ubuntu version support

Great news, this worked perfectly, let’s get to the docker config.

Dockerfile

FROM ubuntu:focal 

RUN apt-get update && apt-get -y upgrade \
    && echo "8 48" | apt-get install -y software-properties-common wget curl \
    && add-apt-repository universe \
    && wget https://packages.ntop.org/apt-stable/20.04/all/apt-ntop-stable.deb \
    && apt install -y ./apt-ntop-stable.deb \
    && apt-get install -y ntopng \
    && systemctl enable ntopng

RUN mkdir /ntopngcustom \
    && chmod 777 /ntopngcustom

From the top-down – first, we update and upgrade the base image, to ensure that we’re working with the latest and greatest.
We then request the installation of software-properties-common wget curl. I won’t cover wget and curl, but the software-properties-common is interesting. You might’ve never used that. Think of this package as a dependency installer for commonly used tools and infra. A couple of things that are included in there are python3 and ca-certificates. Super useful scripts, and most importantly – these are ntopng’s dependencies. For more info on the package click here.

We then add the universe ppa. And we grab the ntop .deb file with wget.
The next line teaches apt-get what ntopng is.
And we finally get to install the tool with apt-get install -y ntopng
The last line here is the inclusion of the service to systemd so that it can start if the container is restarted.

The second block here instantiates a folder for ntopng to use for its wildest storage dreams, and we give it full access. Yes, yes, I know 777 is a horrible thing to have to use, but I never made any promises that this will/is the best way to do this. If you have a better idea – modify the hell out of this.

Cool, let’s add both containers to a network

Docker-compose

I’ll be wrapping up both containers in a single docker-compose yaml for easier management. Here’s the file:

version: '3'

services:
  redis:
    image: redis:alpine
    command: --save 900 1
    volumes:
      - ./data/redis:/data
    restart: on-failure:5
    network_mode: "host"
  ntopng:
    build:
      context: ntop
      dockerfile: Dockerfile
    command: ntopng -r localhost:6379 -d /ntopngcustom
    volumes:
      - ./data/ntopng:/var/lib/ntopng
    restart: on-failure:5
    network_mode: "host"
    depends_on:
      - redis

Let’s break it down

Networking time

You have several options here. Initially, I started the containers with a bridged external network, as I’m used to the microservice world where this is widely accepted. The thing is that if you leave the config with a bridged network ntopng will only see the containers in the network. Not ideal for a network-wide monitoring tool.
So I swapped it over to host. I’m sure some of you had a heart attack by just reading that I attached a container to the host network, but it is what it is. I want the tool to be able to see my whole network.

Starting the tool

The other key thing here is the command line. There’re a couple of ways you can indicate that a container has successfully exited build time and for docker to swap it over to run time. One of them is by modifying the “Entrypoint”, the other is by using the command statement. I chose the latter.

We essentially call ntopng with a -r argument pointing to the redis server we previously took a look at. We also call for -d with the custom directory, so that no ACL gets in the way of the precious files.

A volume binding has been added for … “reasons” and the container is set to try to restart 5 times if it falls over.

Also, ntopng is declared as being dependent on redis. Think of this as another mechanism to ensure that we don’t lose any data. Monitoring will not start unless we have a redis server to talk to.

TL;DR files

Directory tree:

/ docker-compose.yaml
  - data
  - ntop
    - Dockerfile

docker-compose.yaml

version: '3'

services:
  redis:
    image: redis:alpine
    command: --save 900 1
    volumes:
      - ./data/redis:/data
    restart: on-failure:5
    network_mode: "host"
  ntopng:
    build:
      context: ntop
      dockerfile: Dockerfile
    command: ntopng -r localhost:6379 -d /ntopngcustom
    volumes:
      - ./data/ntopng:/var/lib/ntopng
    restart: on-failure:5
    network_mode: "host"
    depends_on:
      - redis

ntop/Dockerfile

FROM ubuntu:focal 

RUN apt-get update && apt-get -y upgrade \
    && echo "8 48" | apt-get install -y software-properties-common wget curl \
    && add-apt-repository universe \
    && wget https://packages.ntop.org/apt-stable/20.04/all/apt-ntop-stable.deb \
    && apt install -y ./apt-ntop-stable.deb \
    && apt-get install -y ntopng \
    && systemctl enable ntopng

RUN mkdir /ntopngcustom \
    && chmod 777 /ntopngcustom

Or, grab the whole thing from here: https://github.com/MSarandev/ntopng-docker-raspberry

Conclusion

Ntopng is a great tool, go ahead and try it. Happy coding