Skip to main content

LibreNMS & Oxidized on Docker — Complete Setup Guide

Version: 1.0
Audience: Junior IT staff with basic Windows familiarity and limited Linux experience
Outcome: A fully operational LibreNMS network monitoring instance with Oxidized configuration backup, accessible via a clean URL, running on Docker inside an Ubuntu Server VM.


Table of Contents

  1. Preface
  2. Part 1 — Create the Ubuntu Server VM
  3. Part 2 — Ubuntu Server Initial Setup
  4. Part 3 — Install Docker and Docker Compose
  5. Part 4 — Project Layout and Configuration Files
  6. Part 5 — Start the Stack and Initial LibreNMS Setup
  7. Part 6 — SNMP Configuration by Device Type
  8. Part 7 — Adding Devices to LibreNMS
  9. Part 8 — Setting Up Alerting
  10. Part 9 — Managing Device Dependencies
  11. Part 10 — Oxidized: Verifying Config Backups
  12. Appendix

Preface

What This Guide Covers

This guide walks you through the complete setup of LibreNMS, an open-source network monitoring platform, paired with Oxidized, a tool that automatically backs up the configuration of your network devices. Both applications run in Docker containers on a single Ubuntu Server virtual machine, making them easy to manage, update, and recover.

Caddy is included as a reverse proxy, which means you can access LibreNMS and Oxidized using a clean web address (like http://librenms.yourschool.org) rather than typing an IP address and port number.

What You Will End Up With

By the end of this guide you will have:

  • An Ubuntu Server VM running on your chosen hypervisor (Proxmox, VMware, or Hyper-V)
  • LibreNMS monitoring your network devices and servers via SNMP
  • Oxidized automatically capturing device configuration backups nightly
  • A Caddy reverse proxy providing clean, consistent web addresses
  • Email or Teams/Slack alerting when devices go down or thresholds are exceeded
  • Device dependency mapping so you don't get flooded with alerts when a single uplink fails

Prerequisites Checklist

Before you begin, confirm the following:

  • You have administrator access to your hypervisor (Proxmox, VMware, or Hyper-V)
  • You have downloaded the Ubuntu Server 24.04 LTS ISO from ubuntu.com
  • You have an internal DNS entry (or plan to create one) for your LibreNMS hostname, pointing to the VM's IP address
  • You know your network's SNMP community string (or have decided on one, e.g. YourOrg_Monitor)
  • You have SSH or Telnet credentials for your network devices (needed for Oxidized)
  • Your firewall or ACLs allow SNMP (UDP port 161) from the LibreNMS VM to your devices
  • Your firewall or ACLs allow SSH (TCP port 22) from the LibreNMS VM to your devices (for Oxidized)

Tip — SNMP Community Strings: A community string is like a read-only password for SNMP. Choose something more specific than public or private. A string like YourOrg_NMS2024 is a good pattern. You will use the same string on every device and tell LibreNMS what it is.


Part 1 — Create the Ubuntu Server VM

Resource Minimum Recommended
vCPUs 2 4
RAM 4 GB 8 GB
Disk 40 GB 80 GB
Network 1 NIC 1 NIC
OS Ubuntu Server 24.04 LTS Ubuntu Server 24.04 LTS

Note — Disk Size: LibreNMS stores historical polling data (RRD files). For environments with 100+ devices, 80 GB is a more comfortable starting point. Disk can usually be expanded later, but it is easier to start larger.


1.1 Proxmox

  1. Log in to the Proxmox web interface and navigate to the node where you want to create the VM.

  2. Upload the Ubuntu ISO to Proxmox storage:

    • In the left panel, click your storage (e.g., local), then click ISO ImagesUpload.
    • Select the Ubuntu Server ISO from your computer and upload it.
  3. Click Create VM in the top-right corner.

  4. Work through the wizard using these settings:

    Tab Setting Value
    General Name librenms
    OS ISO Image Select the Ubuntu ISO you uploaded
    OS Type / Version Linux / 6.x - 2.6 Kernel
    System Machine Default (i440fx)
    System BIOS SeaBIOS (or OVMF for UEFI)
    Disks Bus/Device VirtIO Block
    Disks Disk Size 80 GB
    CPU Cores 4
    Memory Memory 8192 MB (8 GB)
    Network Bridge vmbr0 (or your management bridge)
    Network Model VirtIO
  5. On the final Confirm tab, check Start after created and click Finish.

  6. Click on your new VM in the left panel, then click Console to see the display. The Ubuntu installer will start — continue to Part 2.


1.2 VMware ESXi / vSphere

  1. Log in to the vSphere Client (web browser) or the ESXi host's direct management page.

  2. Upload the Ubuntu ISO:

    • Click Storage → select your datastore → FilesUpload → select the ISO.
  3. Click Create / Register VM and choose Create a new virtual machine.

  4. Configure the VM:

    Setting Value
    Name librenms
    Compatibility ESXi 7.0+ (or your current version)
    Guest OS Family Linux
    Guest OS Version Ubuntu Linux (64-bit)
    Storage Select your datastore
    vCPUs 4
    Memory 8 GB
    Hard Disk 1 80 GB (Thin provisioned is fine)
    Network Adapter Your management port group
    CD/DVD Drive Datastore ISO — browse to your Ubuntu ISO
  5. Make sure Connect at Power On is checked for the CD/DVD drive.

  6. Click Finish, then right-click the VM and select Power On.

  7. Open the Web Console from the VM's summary page. Continue to Part 2.


1.3 Hyper-V

  1. Open Hyper-V Manager on your Windows Server or Windows 10/11 machine.

  2. In the right-hand Actions panel, click New → Virtual Machine.

  3. Work through the wizard:

    Step Setting Value
    Name and Location Name librenms
    Specify Generation Generation Generation 2
    Assign Memory Startup memory 8192 MB
    Assign Memory Dynamic Memory Uncheck (use fixed memory)
    Configure Networking Connection Your management virtual switch
    Virtual Hard Disk Size 80 GB
    Installation Options Install from ISO Browse to your Ubuntu ISO

    Important — Generation 2: Generation 2 VMs use UEFI and are required for Ubuntu Server 24.04. If the VM won't boot from the ISO, disable Secure Boot: right-click VM → Settings → Security → uncheck Secure Boot (or change template to Microsoft UEFI Certificate Authority).

  4. Click Finish, then right-click the VM in the list and select Start.

  5. Right-click the VM again and click Connect to open the console. Continue to Part 2.


Part 2 — Ubuntu Server Initial Setup

2.1 Installation Walkthrough

The Ubuntu Server installer is text-based. Use your arrow keys, Tab, Space, and Enter to navigate.

  1. Language: Select English and press Enter.

  2. Keyboard: Choose your keyboard layout (usually English (US)).

  3. Type of Install: Choose Ubuntu Server (not minimized).

  4. Network: The installer will try to get an IP via DHCP. Leave it for now — you will assign a static IP after installation. Note what IP was assigned (shown on screen) so you can SSH in after the install.

  5. Proxy: Leave blank and press Enter.

  6. Ubuntu Archive Mirror: Accept the default and continue.

  7. Storage: Choose Use an entire disk. Leave LVM checked. Select your 80 GB virtual disk. Confirm by selecting Done, then Continue on the destructive action warning.

  8. Profile Setup: Fill in:

    • Your name: IT Admin (or your name)
    • Server name: librenms
    • Username: itadmin (or your preferred username — avoid admin as it is sometimes reserved)
    • Password: Choose a strong password and confirm it.
  9. SSH: Check Install OpenSSH Server. This lets you connect remotely via SSH without needing the console.

  10. Featured Snaps: Do not select anything here. Press Done.

  11. Installation will proceed automatically. When complete, press Reboot Now. When prompted, press Enter to eject the virtual disc.

  12. The VM will reboot into your new Ubuntu Server. You will see a login prompt.


2.2 Linux Basics Crash Course

Before going further, here is the minimum you need to know about working in Linux:

The Terminal

Everything in this guide is done in a terminal — a text-based interface where you type commands. When you SSH into your server (covered next), everything you see is a terminal.

Commands You Will Use Most

Command What It Does Example
ls List files in the current folder ls
cd Change directory (folder) cd /opt/monitoring
mkdir Create a directory mkdir /opt/monitoring
nano Edit a text file nano config.txt
cat Print the contents of a file cat .env
sudo Run a command as administrator sudo apt update
pwd Show your current location pwd
cp Copy a file cp file1 file2
mv Move or rename a file mv old.txt new.txt
rm Delete a file rm old.txt

The sudo Command

In Linux, most system-level tasks require administrator (root) privileges. Rather than logging in as root, you prefix commands with sudo. The system will ask for your password the first time you use it per session.

sudo apt update

Think of sudo as "Run this as administrator."

Editing Files with nano

nano is a simple text editor that runs in the terminal. To edit a file:

nano filename.txt
  • Use arrow keys to move around
  • Type to add text
  • Ctrl + X → Exit
  • When prompted to save: press Y → then Enter to confirm

Tip — Copying from this Guide: If you are using SSH and a terminal on your own computer, you can paste text with right-click or Ctrl+Shift+V in most terminal applications.


2.3 Assign a Static IP

LibreNMS needs a fixed IP address so that DNS entries, device ACLs, and firewall rules stay consistent. Ubuntu uses Netplan to manage network settings.

  1. Log into the VM console (or SSH using the DHCP address).

  2. Find your network interface name:

    ip link show
    

    Look for an interface name that is not lo. It will typically be ens18 (Proxmox), ens192 (VMware), or eth0 (Hyper-V).

  3. Open the Netplan config file (the filename may vary slightly):

    sudo nano /etc/netplan/00-installer-config.yaml
    
  4. Replace the entire contents with the following, substituting your network values:

    network:
      version: 2
      ethernets:
        ens18:                          # Replace with your interface name
          dhcp4: no
          addresses:
            - 192.168.1.50/24           # Replace with your desired static IP and subnet mask
          routes:
            - to: default
              via: 192.168.1.1          # Replace with your default gateway
          nameservers:
            addresses:
              - 192.168.1.1             # Your primary DNS server
              - 192.168.1.2             # Your secondary DNS server (optional)
    

    Important — YAML Indentation: YAML files are very sensitive to indentation. Every indented line uses spaces, not tabs. Copy the block above exactly. If Netplan gives an error, indentation is almost always the cause.

  5. Save the file (Ctrl+X → Y → Enter).

  6. Apply the new configuration:

    sudo netplan apply
    
  7. Verify the IP address took effect:

    ip addr show
    

    You should see your chosen IP address listed under your interface.

  8. Test internet connectivity:

    ping -c 4 8.8.8.8
    

2.4 Enable SSH for Remote Access

If you checked Install OpenSSH Server during installation, SSH is already running. Verify it:

sudo systemctl status ssh

You should see Active: active (running). If not:

sudo apt install openssh-server
sudo systemctl enable --now ssh

Connect via SSH from Your Computer

On Windows: Use Windows Terminal, PuTTY, or any SSH client:

ssh itadmin@192.168.1.50

Replace itadmin with your username and 192.168.1.50 with your VM's IP. Accept the host key fingerprint the first time by typing yes.

On Mac/Linux: Open Terminal and run the same command.

From this point on, you can do everything from an SSH session on your own computer — no need to use the VM's console directly.


Part 3 — Install Docker and Docker Compose

Docker allows you to run applications in isolated, self-contained packages called containers. Docker Compose lets you define and run multiple containers together using a single configuration file.

Run the following commands one at a time. Copy each block, paste it into your SSH session, and wait for it to finish before continuing.

Step 1 — Update the package lists:

sudo apt update && sudo apt upgrade -y

Step 2 — Install required tools:

sudo apt install -y ca-certificates curl gnupg

Step 3 — Add Docker's official GPG signing key:

sudo install -m 0755 -d /etc/apt/keyrings

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

sudo chmod a+r /etc/apt/keyrings/docker.gpg

Step 4 — Add the Docker software repository:

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Step 5 — Install Docker Engine and Docker Compose:

sudo apt update

sudo apt install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

Step 6 — Allow your user to run Docker without sudo:

sudo usermod -aG docker $USER

Important: You must log out and back in for this to take effect. Disconnect your SSH session and reconnect before continuing:

exit

Then reconnect: ssh itadmin@192.168.1.50

Step 7 — Verify Docker is working:

docker run hello-world

You should see a message that begins with Hello from Docker!. If you do, Docker is installed correctly.


Part 4 — Project Layout and Configuration Files

All of your configuration files will live in one folder. This makes it easy to back up, version, or rebuild the entire stack.

4.1 Directory Structure

Create the project directory:

sudo mkdir -p /opt/monitoring/oxidized
sudo chown -R $USER:$USER /opt/monitoring
cd /opt/monitoring

When you are done, your folder will look like this:

/opt/monitoring/
├── docker-compose.yml      ← Defines all containers
├── .env                    ← Secret values (passwords, etc.)
├── Caddyfile               ← Web proxy configuration
└── oxidized/
    └── config              ← Oxidized settings

4.2 The Environment File (.env)

The .env file stores sensitive values like passwords so they are not written directly into docker-compose.yml. Create it now:

nano /opt/monitoring/.env

Paste the following content, replacing each placeholder value:

# ── Timezone ──────────────────────────────────────────────────────────────
# Find your timezone string at: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TZ=America/Detroit

# ── Database Passwords ─────────────────────────────────────────────────────
# These are internal passwords for the MariaDB container.
# Choose strong, unique values. You will not need to type these manually.
DB_ROOT_PASSWORD=ChangeThisRootPassword!
DB_PASSWORD=ChangeThisDbPassword!

# ── LibreNMS ───────────────────────────────────────────────────────────────
# A random secret key used for session encryption.
# Generate one by running: openssl rand -base64 32
APP_KEY=SomeRandomLongStringHere

Security Note: The .env file contains passwords. Do not share it or commit it to a public repository. Keep a secure backup of it (for example, in your password manager or on an encrypted drive).

Save and close the file (Ctrl+X → Y → Enter).


4.3 The Docker Compose File

This is the main configuration file. It tells Docker which containers to run and how they connect to each other.

nano /opt/monitoring/docker-compose.yml

Paste the entire contents below:

---
version: "3.8"

# ──────────────────────────────────────────────────────────────────────────────
# LibreNMS + Oxidized + Caddy — Docker Compose Stack
# ──────────────────────────────────────────────────────────────────────────────

services:

  # ── Database (MariaDB) ────────────────────────────────────────────────────
  # LibreNMS stores all device data, alerts, and history in this database.
  db:
    image: mariadb:10.11
    container_name: librenms_db
    restart: unless-stopped
    command:
      - "mysqld"
      - "--innodb-file-per-table=1"
      - "--lower-case-table-names=0"
      - "--character-set-server=utf8mb4"
      - "--collation-server=utf8mb4_unicode_ci"
    environment:
      MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}"
      MYSQL_DATABASE: "librenms"
      MYSQL_USER: "librenms"
      MYSQL_PASSWORD: "${DB_PASSWORD}"
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - monitoring_net

  # ── Cache (Redis) ──────────────────────────────────────────────────────────
  # LibreNMS uses Redis for fast in-memory caching and job queuing.
  redis:
    image: redis:7-alpine
    container_name: librenms_redis
    restart: unless-stopped
    networks:
      - monitoring_net

  # ── LibreNMS Web Application ───────────────────────────────────────────────
  # This is the main LibreNMS container that runs the web interface and polling.
  librenms:
    image: librenms/librenms:latest
    container_name: librenms_app
    restart: unless-stopped
    depends_on:
      - db
      - redis
    environment:
      DB_HOST: db
      DB_PORT: "3306"
      DB_NAME: librenms
      DB_USER: librenms
      DB_PASSWORD: "${DB_PASSWORD}"
      REDIS_HOST: redis
      REDIS_PORT: "6379"
      REDIS_DB: "0"
      TZ: "${TZ}"
    volumes:
      - librenms_data:/data
    networks:
      - monitoring_net

  # ── LibreNMS Dispatcher ────────────────────────────────────────────────────
  # Handles background polling tasks (gathering SNMP data from devices).
  librenms_dispatcher:
    image: librenms/librenms:latest
    container_name: librenms_dispatcher
    restart: unless-stopped
    depends_on:
      - librenms
    environment:
      DB_HOST: db
      DB_PORT: "3306"
      DB_NAME: librenms
      DB_USER: librenms
      DB_PASSWORD: "${DB_PASSWORD}"
      REDIS_HOST: redis
      REDIS_PORT: "6379"
      REDIS_DB: "0"
      TZ: "${TZ}"
      DISPATCHER_NODE_ID: dispatcher1
      SIDECAR_DISPATCHER: "1"
    volumes:
      - librenms_data:/data
    networks:
      - monitoring_net

  # ── Oxidized ───────────────────────────────────────────────────────────────
  # Connects to network devices via SSH and backs up their configurations.
  # It reads the device list from the LibreNMS API automatically.
  oxidized:
    image: oxidized/oxidized:latest
    container_name: oxidized
    restart: unless-stopped
    environment:
      CONFIG_RELOAD_INTERVAL: "600"
    volumes:
      - ./oxidized:/home/oxidized/.config/oxidized
    networks:
      - monitoring_net

  # ── Caddy (Reverse Proxy) ─────────────────────────────────────────────────
  # Sits in front of LibreNMS and Oxidized, providing a clean URL and
  # handling HTTPS automatically.
  caddy:
    image: caddy:2-alpine
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    networks:
      - monitoring_net

# ── Persistent Storage ───────────────────────────────────────────────────────
# Named volumes are managed by Docker and survive container restarts.
volumes:
  db_data:
  librenms_data:
  caddy_data:
  caddy_config:

# ── Private Network ──────────────────────────────────────────────────────────
# All containers communicate with each other on this internal network.
# Only Caddy exposes ports to the outside world (80 and 443).
networks:
  monitoring_net:
    driver: bridge

Save and close the file.


4.4 The Caddyfile

Caddy is your reverse proxy. It listens on ports 80 and 443 and forwards requests to the correct container. Using the tls internal directive tells Caddy to generate and manage its own internal TLS certificates, so your connections are encrypted even without a public certificate.

nano /opt/monitoring/Caddyfile

Paste the following, replacing the hostnames with your own:

# ── LibreNMS ──────────────────────────────────────────────────────────────────
librenms.yourschool.org {
    tls internal
    reverse_proxy librenms_app:8000
}

# ── Oxidized ──────────────────────────────────────────────────────────────────
oxidized.yourschool.org {
    tls internal
    reverse_proxy oxidized:8888
}

DNS Requirement: For the hostname to work, you need a DNS record on your internal DNS server pointing librenms.yourschool.org to the static IP of your Ubuntu VM (e.g., 192.168.1.50). Create an A record on your domain controller or DNS server.

If you do not have internal DNS set up yet, you can access LibreNMS temporarily by its IP and port: http://192.168.1.50:8000

Save and close the file.


4.5 The Oxidized Config File

This file tells Oxidized how to connect to devices and where to store backups. Oxidized will pull its device list automatically from the LibreNMS API, so you only need to add devices in one place.

nano /opt/monitoring/oxidized/config

Paste the following:

---
# ── Credentials ───────────────────────────────────────────────────────────────
# These are the SSH/Telnet credentials Oxidized will use to log into devices.
# You can override these per-device or per-group in LibreNMS later.
username: your_device_username
password: your_device_password

# ── Default Model ─────────────────────────────────────────────────────────────
# Fallback device type if Oxidized cannot determine it from LibreNMS.
model: ios

# ── Polling Interval ──────────────────────────────────────────────────────────
# How often (in seconds) to back up devices. 3600 = every hour.
interval: 3600

# ── Logging ───────────────────────────────────────────────────────────────────
use_syslog: false
debug: false

# ── Performance ───────────────────────────────────────────────────────────────
threads: 30
timeout: 20
retries: 3

# ── REST API ──────────────────────────────────────────────────────────────────
# Enables the Oxidized web interface and API, used by LibreNMS integration.
rest: 0.0.0.0:8888

# ── Device List Source (LibreNMS API) ─────────────────────────────────────────
# Oxidized pulls its device list from LibreNMS automatically.
# Replace YOUR_LIBRENMS_API_TOKEN_HERE after completing Part 5.
source:
  default: http
  http:
    url: http://librenms_app:8000/api/v0/oxidized
    scheme: http
    secure: false
    map:
      name: hostname
      model: os
      group: group
    headers:
      X-Auth-Token: "YOUR_LIBRENMS_API_TOKEN_HERE"

# ── Config Backup Storage ─────────────────────────────────────────────────────
# Stores device configs in a local Git repository inside the container.
# This gives you full version history — you can see exactly what changed and when.
output:
  default: git
  git:
    single_repo: true
    user: Oxidized
    email: oxidized@yourschool.org
    repo: "/home/oxidized/.config/oxidized/oxidized.git"

# ── OS to Model Mapping ───────────────────────────────────────────────────────
# Maps LibreNMS OS names to Oxidized model names.
model_map:
  ios: ios
  iosxe: iosx
  nxos: nxos
  arubaos: arubaos
  aoscx: aoscx
  fortios: fortios
  panos: panos
  asa: asa

Note — API Token: Leave YOUR_LIBRENMS_API_TOKEN_HERE as-is for now. You will generate the token in Part 5.4 and come back to update this file.

Save and close the file.


Part 5 — Start the Stack and Initial LibreNMS Setup

5.1 Start the Containers

Navigate to your project directory and start everything:

cd /opt/monitoring
docker compose up -d

The -d flag runs the containers in the background (detached mode). Docker will download all the required images on the first run — this may take a few minutes depending on your internet connection.

Watch the startup progress:

docker compose logs -f

Press Ctrl+C to stop watching logs (the containers keep running). Wait until you stop seeing rapid log activity and things settle down — usually 1–2 minutes.

Check that all containers are running:

docker compose ps

You should see all six containers (librenms_db, librenms_redis, librenms_app, librenms_dispatcher, oxidized, caddy) with a status of Up.

If any container shows Exited, check its logs:

docker compose logs <container_name>

For example: docker compose logs librenms_app


5.2 Create the Admin Account

With the Docker version of LibreNMS, the admin user is created from the command line rather than through a web wizard.

docker exec librenms_app lnms user:add --role=admin admin

You will be prompted to enter and confirm a password for the admin account. Choose a strong password.


5.3 Log In and Verify

  1. Open a web browser and navigate to your LibreNMS URL:

    • Using hostname: https://librenms.yourschool.org
    • Using IP directly: http://192.168.1.50:8000
  2. Log in with username admin and the password you just created.

  3. You will land on the LibreNMS dashboard. It will be mostly empty until you add devices.

Browser Certificate Warning: If you are using the tls internal Caddy setting, your browser will show a certificate warning the first time you connect. This is expected — Caddy uses a self-signed internal CA. You can safely click "Advanced" → "Proceed" to continue. To permanently trust Caddy's CA, see the Caddy documentation on local HTTPS.


5.4 Generate a LibreNMS API Token for Oxidized

Oxidized needs an API token to pull the device list from LibreNMS.

  1. In LibreNMS, click on the admin username in the top-right corner → API Access.
  2. Click Create New Token.
  3. Give it a description like Oxidized Integration and click Create.
  4. Copy the generated token — you will only see it once.

5.5 Finish the Oxidized Config

Now update the Oxidized config with the API token you just copied:

nano /opt/monitoring/oxidized/config

Find the line:

      X-Auth-Token: "YOUR_LIBRENMS_API_TOKEN_HERE"

Replace YOUR_LIBRENMS_API_TOKEN_HERE with your actual token. Save and close the file.

Restart Oxidized to apply the change:

docker compose restart oxidized

Verify Oxidized can reach the LibreNMS API:

docker compose logs oxidized

Look for lines indicating it loaded devices from the API. If you see connection errors, double-check the token and ensure LibreNMS is running.


Tell LibreNMS where Oxidized is running so you can view configs directly from device pages.

  1. In LibreNMS, go to Settings (gear icon, top-right) → External IntegrationOxidized.

  2. Fill in:

    • Oxidized URL: http://oxidized:8888
    • Enable: Enabled
  3. Click Save.

Now when you view a device page in LibreNMS, you will see a Configs tab showing the backup history from Oxidized.


Part 6 — SNMP Configuration by Device Type

6.1 What is SNMP and Why It Matters

SNMP (Simple Network Management Protocol) is the language LibreNMS uses to ask devices questions like: "How busy is your CPU?", "How much traffic is on this port?", and "Are all your interfaces up?"

Every device you want to monitor needs to have SNMP enabled and configured to allow queries from your LibreNMS server's IP address.

Key concepts:

Term Meaning
Community String A shared read-only password. Devices with SNMP v2c use this.
SNMP v2c The most common version — simple and widely supported. This guide uses v2c.
UDP 161 The port SNMP uses. Your LibreNMS VM must be able to reach this port on every device.
Read-Only (RO) LibreNMS only needs read access. Never give it read-write.

In all examples below, replace YOUR_COMMUNITY with the community string you chose for your environment (e.g., YourOrg_Monitor). Replace 192.168.1.50 with the static IP of your LibreNMS VM.


6.2 Cisco IOS / IOS-XE Switches and Routers

Connect to the device via SSH or the console and enter privileged exec mode (enable), then global configuration mode:

enable
configure terminal

Configure SNMP with an ACL to restrict which hosts can query the device:

! Create an ACL that permits only your LibreNMS server
ip access-list standard SNMP_ALLOWED
 permit host 192.168.1.50
 deny   any

! Apply SNMP read-only with the ACL
snmp-server community YOUR_COMMUNITY RO SNMP_ALLOWED

! Optional but recommended — set location and contact info
snmp-server location Building A - IDF Closet 2
snmp-server contact helpdesk@yourschool.org

! Save the configuration
end
write memory

Verify it works: From the LibreNMS VM, you can test SNMP manually:

docker exec librenms_app snmpwalk -v2c -c YOUR_COMMUNITY 192.168.1.10 sysDescr

Replace 192.168.1.10 with the device's IP. You should see a description string returned.


6.3 Aruba CX Switches (AOS-CX)

Connect via SSH and enter configuration mode:

configure terminal

! Enable SNMP globally
snmp-server community YOUR_COMMUNITY

! Restrict to your management VRF and set contact info
snmp-server vrf default
snmp-server system-contact helpdesk@yourschool.org
snmp-server system-location Building A - IDF Closet 2

! Save
end
write memory

For additional security, create an SNMP host restriction:

configure terminal
snmp-server host 192.168.1.50 community YOUR_COMMUNITY version v2c

6.4 Aruba Legacy Switches (AOS-Switch / ProCurve)

These are older switches like the 2530, 2930, and similar. Connect via SSH or the console.

config

snmp-server community "YOUR_COMMUNITY" operator restricted
snmp-server contact "helpdesk@yourschool.org"
snmp-server location "Building A - IDF Closet 2"

! Restrict SNMP access to your LibreNMS server only
snmp-server host 192.168.1.50 community "YOUR_COMMUNITY" snmp-version v2c

write memory

6.5 Cisco Firewalls (ASA)

Firewall Note: On ASA firewalls, SNMP must be configured on the specific interface (nameif) that LibreNMS can reach. In most school environments this will be your inside or management interface.

configure terminal

! Allow SNMP from your LibreNMS server on the inside interface
snmp-server host inside 192.168.1.50 community YOUR_COMMUNITY version 2c

! Enable SNMP globally
snmp-server community YOUR_COMMUNITY
snmp-server location Building A - Server Room
snmp-server contact helpdesk@yourschool.org

! Ensure SNMP traffic is allowed through the interface ACL
! (Check your existing ACL on the inside interface — UDP 161 from LibreNMS must be permitted)

write memory

6.6 Fortinet FortiGate

Via the GUI:

  1. Navigate to System → SNMP.
  2. Click Create New under SNMP v1/v2c.
  3. Set:
    • Community Name: YOUR_COMMUNITY
    • Hosts: Click Add, enter your LibreNMS IP: 192.168.1.50
    • Queries (Port 161): Enabled
  4. Click OK.

Via the CLI (SSH):

config system snmp community
    edit 1
        set name "YOUR_COMMUNITY"
        config hosts
            edit 1
                set ip 192.168.1.50 255.255.255.255
            next
        end
        set query-v2c-status enable
        set query-v2c-port 161
    next
end

Firewall Policy: FortiGate only responds to SNMP queries on interfaces where SNMP is explicitly permitted. Go to Network → Interfaces, edit the management interface, and ensure SNMP is checked under Administrative Access.


6.7 Palo Alto Networks

Via the GUI:

  1. Go to Device → Setup → Operations.
  2. Under Miscellaneous, click SNMP Setup.
  3. Set:
    • Location: Your location string
    • Contact: Your email
  4. Go to Device → Server Profiles → SNMP Trap — this is for traps, which is optional.
  5. For SNMP polling, go to Device → Setup → Management and ensure your management interface is accessible from your LibreNMS IP.

Via the CLI (SSH):

set deviceconfig system snmp-setting access-setting version v2c
set deviceconfig system snmp-setting access-setting version v2c snmp-community-string YOUR_COMMUNITY
set deviceconfig system snmp-setting system location "Building A - Server Room"
set deviceconfig system snmp-setting system contact "helpdesk@yourschool.org"
commit

Management Interface: SNMP on Palo Alto responds only on the management interface (MGT). Ensure that UDP 161 from 192.168.1.50 is allowed in the management interface's permitted source IPs under Device → Setup → Interfaces → Management.


6.8 Windows Server

Option A — Using PowerShell (recommended):

Open PowerShell as Administrator and run:

# Install SNMP service and WMI provider
Install-WindowsFeature -Name SNMP-Service, SNMP-WMI-Provider -IncludeManagementTools

# Set the community string with read-only access (value 4 = READ ONLY)
Set-ItemProperty `
  -Path "HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\ValidCommunities" `
  -Name "YOUR_COMMUNITY" `
  -Value 4

# Restrict SNMP to only respond to your LibreNMS server
New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\PermittedManagers" -Force
Set-ItemProperty `
  -Path "HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\PermittedManagers" `
  -Name "1" `
  -Value "192.168.1.50"

# Restart SNMP service to apply changes
Restart-Service SNMP

Option B — Via Server Manager GUI:

  1. Open Server Manager → Manage → Add Roles and Features.
  2. Click through to Features and check SNMP Service.
  3. Install it.
  4. After installation, open Services (search for it in Start), find SNMP Service, right-click → Properties.
  5. Go to the Security tab:
    • Under "Accepted community names," click Add → select READ ONLY → enter YOUR_COMMUNITY.
    • Under "Accept SNMP packets from these hosts," select Only accept SNMP packets from these hosts and add 192.168.1.50.
  6. Click OK and restart the service.

Windows Firewall: Ensure Windows Firewall allows inbound UDP 161. The SNMP feature installation usually creates this rule automatically, but verify it in Windows Defender Firewall → Inbound Rules.


6.9 Linux Servers (Ubuntu / Debian)

Step 1 — Install the SNMP daemon:

sudo apt update
sudo apt install snmpd -y

Step 2 — Configure it:

sudo nano /etc/snmp/snmpd.conf

Find and replace the relevant lines, or add the following to the bottom of the file. The simplest working configuration:

# Allow read-only access from your LibreNMS server with your community string
rocommunity YOUR_COMMUNITY 192.168.1.50

# System information (optional but useful in LibreNMS)
syslocation Building A - Server Room
syscontact helpdesk@yourschool.org

# Extend what SNMP reports to include disk, CPU, and memory details
extend .1.3.6.1.4.1.2021.7890.1 distro /usr/bin/distro

Step 3 — Save, enable, and start the service:

sudo systemctl enable snmpd
sudo systemctl restart snmpd

Step 4 — Allow SNMP through the firewall (if UFW is active):

sudo ufw allow from 192.168.1.50 to any port 161 proto udp

Tip — LibreNMS Agent: For deeper Linux monitoring (process lists, disk I/O detail, etc.), LibreNMS also supports an agent that runs on the monitored server and reports extra data via TCP port 6556. This is optional and beyond the scope of this guide, but look up "LibreNMS agent" when you want to explore it.


Part 7 — Adding Devices to LibreNMS

7.1 Add a Device Manually

  1. In LibreNMS, click Devices in the top navigation → Add Device.

  2. Fill in the form:

    Field Value
    Hostname / IP The device's IP address or DNS hostname
    SNMP Version v2c
    Community Your SNMP community string
    Port 161
    Port Association ifIndex
  3. Leave other fields at their defaults unless you know you need to change them.

  4. Click Add Device.

LibreNMS will immediately attempt to contact the device via SNMP. If successful, it will appear in your device list. Initial data (graphs, interface lists) populates within the first few polling cycles — usually within 5–10 minutes.

Device Not Adding? If you get an error, check:

  • Can the LibreNMS VM ping the device? (docker exec librenms_app ping -c 3 192.168.1.10)
  • Is SNMP configured on the device with the correct community string?
  • Is UDP 161 allowed from the LibreNMS IP on the device's ACL or firewall?
  • Run a manual SNMP test: docker exec librenms_app snmpwalk -v2c -c YOUR_COMMUNITY 192.168.1.10 sysDescr

7.2 Auto-Discovery

LibreNMS can automatically discover new devices using several methods. The most common for a school network is SNMP-based network discovery, where LibreNMS polls ARP tables and CDP/LLDP neighbors to find new devices.

To configure discovery:

  1. Go to Settings (gear icon) → Discovery.
  2. Ensure Discovery is enabled.
  3. Under Networks to Discover, add your subnet ranges (e.g., 192.168.1.0/24, 10.10.0.0/16).
  4. Configure which discovery methods to use — ARP, CDP, LLDP, and OSPF neighbors are good starting points.

Auto-Discovery Caution: Discovery will attempt SNMP against every IP it finds. Ensure all discovered devices have SNMP configured with your community string, otherwise they will show as failed discoveries. You can ignore or exclude specific IPs or subnets.


7.3 Device Groups

Device groups let you organize devices (e.g., by building, type, or vendor) and apply rules to them collectively — such as alert rules or polling settings.

To create a group:

  1. Go to DevicesManage GroupsCreate Group.
  2. Give the group a name (e.g., Core Switches, Building A, Firewalls).
  3. Choose Dynamic (automatic, rule-based) or Static (manual membership).
  4. For a dynamic group, set rules such as:
    • type = network → groups all network gear
    • hostname contains bldg-a → groups devices with that naming pattern
    • os = iosxe → groups all IOS-XE devices

Groups are used heavily in alerting and dependency management, covered in the next sections.


Part 8 — Setting Up Alerting

8.1 Alert Rules

Alert rules define the conditions that trigger an alert. LibreNMS ships with a large library of built-in rules, which is a great starting point.

Enable built-in alert rules:

  1. Go to AlertsAlert Rules.
  2. Click Alert Rule Collection at the top.
  3. Browse the community rules and click the + button to import useful ones. Good starting rules include:
    • Device Down via ICMP — alerts when a device stops responding to pings
    • Port Down — alerts when a network interface goes down
    • BGP Peer Down — useful if you run BGP
    • Device CPU/Memory Usage — alerts on high resource usage
    • Disk Usage — for monitored servers

Create a custom rule:

  1. Click Create Rule.
  2. Give it a name (e.g., Device Unreachable).
  3. Set the Rule using the builder:
    • devices.status = 0 — triggers when a device status is down
  4. Set Severity (critical, warning, info).
  5. Set Delay — how long the condition must be true before alerting (e.g., 5 minutes avoids alerts on brief blips).
  6. Assign a Transport (covered next).

8.2 Alert Transports (Email and Teams/Slack)

Transports define where alerts are sent. LibreNMS supports many options. Below are the most common.

Email Transport

  1. Go to AlertsAlert TransportsCreate Transport.
  2. Choose Mail.
  3. Fill in:
    • Transport Name: Email Alerts
    • Email(s): helpdesk@yourschool.org (comma-separate multiple addresses)
  4. Save.

Email Requires SMTP Configuration: LibreNMS needs a mail server to send emails. Go to Settings → Email and configure your SMTP server details (host, port, credentials). Most school environments can use their Exchange server or a relay.

Microsoft Teams Transport

  1. In Microsoft Teams, create an Incoming Webhook connector on the channel where you want alerts:

    • Open the channel → click ...ConnectorsIncoming WebhookConfigure.
    • Give it a name and copy the webhook URL.
  2. Back in LibreNMS, go to Alerts → Alert Transports → Create Transport.

  3. Choose Microsoft Teams.

  4. Paste the webhook URL and save.

Slack Transport

  1. In Slack, go to your workspace's app settings and create an Incoming Webhooks app.
  2. Create a webhook for your chosen channel and copy the URL.
  3. In LibreNMS, choose Slack as the transport type, paste the webhook URL, and save.

8.3 Alert Templates

Alert templates control the format of alert messages. The default template is functional, but you can customize it.

  1. Go to Alerts → Alert Templates → Create Template.

  2. Use the Blade/Twig-style templating to include device information. A simple useful template:

    ⚠️  ALERT: {{ $alert->name }}
    
    Device:   {{ $alert->hostname }}
    Severity: {{ $alert->severity }}
    Time:     {{ $alert->timestamp }}
    Status:   {{ $alert->state == 1 ? 'FIRING' : 'RECOVERED' }}
    
    Message:  {{ $alert->string }}
    
    View in LibreNMS: https://librenms.yourschool.org/device/device={{ $alert->device_id }}/
    
  3. Assign this template to your alert rules by editing each rule and selecting your template.


Part 9 — Managing Device Dependencies

Why Dependencies Matter

Dependencies solve this: If you define that all devices in a closet depend on the closet switch, and the switch goes down, LibreNMS will only alert you about the switch. The downstream devices are suppressed until the switch comes back up.

Configuring Parent/Child Relationships

  1. Navigate to the device page of the device you want to set as a child (the device that depends on something else).

  2. Click Edit (pencil icon) at the top right of the device page.

  3. Scroll to Dependencies.

  4. In the Parent Device field, search for and select the upstream device (e.g., the closet switch that this device plugs into).

  5. Click Save.

Repeat this for each device. A logical structure might be:

Core Switch (no parent)
  └── Distribution Switch Building A
        ├── Closet Switch A-1
        │     ├── AP-101
        │     ├── AP-102
        │     └── Workstation-Printer-VLAN-Monitor
        └── Closet Switch A-2
              └── ...

Tip — Start at the Top: Configure dependencies from the top of your network hierarchy down. Start with your core switch (no parent), then distribution switches (parent = core), then edge switches (parent = distribution), and finally APs and servers.

Testing Dependency Behavior

To verify dependencies are working correctly without actually taking down a device:

  1. On the parent device's page, click Edit → temporarily change its status to Disabled.
  2. Check Alerts — you should see alerts only for the parent, not for all downstream children.
  3. Re-enable the parent device.

Alternatively, check the Device Map under Overview → Maps → Device Dependency Map for a visual representation of your dependency tree.


Part 10 — Oxidized: Verifying Config Backups

Checking Backup Status

Once devices are in LibreNMS with the correct OS type, Oxidized will attempt to back them up on its polling interval.

Check the Oxidized web interface:

Navigate to https://oxidized.yourschool.org (or http://192.168.1.50:8888). You will see a table listing every device with its last backup status:

Status Meaning
success Backup completed successfully
fail Could not connect or authenticate
never Not yet attempted
🔄 running Currently backing up

Check via LibreNMS:

Go to any device page → click the Configs tab. You will see a list of backed-up configuration files with timestamps.

Common Reasons for Backup Failures

Symptom Likely Cause
fail on all devices Wrong credentials in oxidized/config, or API token issue
fail on specific device SSH not reachable, wrong enable password, or device type not detected
Device not in Oxidized list Device not added in LibreNMS, or OS not in the model_map

View Oxidized logs:

docker compose logs -f oxidized

Viewing a Device's Configuration History

  1. In LibreNMS, go to the device's page.
  2. Click the Configs tab.
  3. Click on any backup entry to see the full configuration at that point in time.
  4. Click Diff to compare two backups and see exactly what changed between them — lines in red were removed, lines in green were added.

This is invaluable when troubleshooting changes ("the network broke after someone made changes last Tuesday — what changed?").

Forcing an Immediate Backup

To trigger a backup right now without waiting for the next interval:

docker exec oxidized oxidized-reload

Or use the REST API:

curl http://192.168.1.50:8888/nodes/next/device-hostname

Appendix

A: Common Linux Commands Reference Card

Command Description Example
ls List files ls /opt/monitoring
ls -la List files with details and hidden files ls -la
cd Change directory cd /opt/monitoring
pwd Show current directory pwd
mkdir Create a directory mkdir /opt/monitoring
nano <file> Edit a file nano docker-compose.yml
cat <file> Display file contents cat .env
sudo <command> Run as administrator sudo apt update
apt update Refresh package list sudo apt update
apt install <pkg> Install a package sudo apt install curl
systemctl status <svc> Check a service's status sudo systemctl status docker
systemctl restart <svc> Restart a service sudo systemctl restart snmpd
ip addr show Show IP addresses ip addr show
ping <host> Test connectivity ping 192.168.1.1
history Show recent commands history
Ctrl + C Cancel/stop a running command
Ctrl + L Clear the screen
Tab Auto-complete a command or path

B: SNMP Quick-Reference Table

Device Type Configuration Method SNMP Version Notes
Cisco IOS / IOS-XE CLI v2c Use ACL to restrict access
Aruba AOS-CX CLI v2c Specify VRF
Aruba AOS-Switch (legacy) CLI v2c restricted keyword limits to listed hosts
Cisco ASA CLI v2c Specify interface name (inside/mgmt)
Fortinet FortiGate GUI or CLI v2c Enable SNMP on management interface
Palo Alto GUI or CLI v2c MGT interface only; set permitted source IPs
Windows Server PowerShell or GUI v2c Allow UDP 161 in Windows Firewall
Linux (Ubuntu/Debian) snmpd.conf v2c Use UFW rule if firewall is active

C: Useful LibreNMS CLI Commands

All commands are run inside the LibreNMS container:

docker exec librenms_app <command>
Command What It Does
lnms user:add -r admin username Create a new admin user
lnms user:list List all users
lnms device:add 192.168.1.10 Add a device from the command line
lnms device:poll 192.168.1.10 Force an immediate poll of a device
lnms discovery:run -h 192.168.1.10 Run discovery on a specific host
lnms snmp:test 192.168.1.10 Test SNMP connectivity to a device
lnms alerts:test Send a test alert
lnms maintenance:clear-queue Clear a stuck job queue

Test SNMP from within the LibreNMS container:

docker exec librenms_app snmpwalk -v2c -c YOUR_COMMUNITY 192.168.1.10 sysDescr

D: Troubleshooting Common Issues

Container will not start

docker compose logs <container_name>

Common causes:

  • db: Wrong or missing DB_ROOT_PASSWORD in .env
  • librenms_app: Database not yet ready — wait 30 seconds and try again
  • caddy: Syntax error in Caddyfile — check indentation and formatting

LibreNMS shows "DB Error" after starting

The database container sometimes takes longer to initialize than LibreNMS expects. Restart the app container:

docker compose restart librenms_app librenms_dispatcher

Device shows as "down" but is actually up

  1. Verify SNMP is configured on the device.
  2. Test SNMP manually: docker exec librenms_app snmpwalk -v2c -c YOUR_COMMUNITY <device_ip> sysDescr
  3. Check that UDP 161 is permitted from the LibreNMS IP on any ACLs or firewalls between them.
  4. Force a poll: docker exec librenms_app lnms device:poll <device_ip>

Oxidized shows fail for all devices

  1. Check that the API token in /opt/monitoring/oxidized/config is correct.
  2. Verify Oxidized can reach LibreNMS: docker exec oxidized curl http://librenms_app:8000/api/v0/oxidized -H "X-Auth-Token: YOUR_TOKEN"
  3. Check credentials — ensure the username/password in the config can SSH into your devices.

Oxidized shows fail for specific device

  1. Try SSH manually from the Oxidized container: docker exec oxidized ssh username@device_ip
  2. Check whether the device requires an enable password (add secret: your_enable_password to the device in LibreNMS's Oxidized settings).
  3. Ensure the device's OS is listed in the model_map in the Oxidized config.

Caddy not serving HTTPS / certificate error

docker compose logs caddy

Common causes:

  • Hostname in Caddyfile does not match the URL you are visiting
  • DNS is not pointing to the VM's IP
  • Port 80 or 443 is blocked by a firewall on the VM or network

Check if ports are open on the VM:

sudo ss -tlnp | grep -E '80|443'

How to update the stack to the latest versions

cd /opt/monitoring
docker compose pull
docker compose up -d

This downloads the latest images and recreates the containers. Your data is preserved in named Docker volumes.


Guide Version 1.0 — LibreNMS Docker Stack with Oxidized and Caddy
Target Platform: Ubuntu Server 24.04 LTS