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
- Preface
- Part 1 — Create the Ubuntu Server VM
- Part 2 — Ubuntu Server Initial Setup
- Part 3 — Install Docker and Docker Compose
- Part 4 — Project Layout and Configuration Files
- Part 5 — Start the Stack and Initial LibreNMS Setup
- Part 6 — SNMP Configuration by Device Type
- Part 7 — Adding Devices to LibreNMS
- Part 8 — Setting Up Alerting
- Part 9 — Managing Device Dependencies
- Part 10 — Oxidized: Verifying Config Backups
- 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
publicorprivate. A string likeYourOrg_NMS2024is 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
Recommended VM Specifications
| 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
-
Log in to the Proxmox web interface and navigate to the node where you want to create the VM.
-
Upload the Ubuntu ISO to Proxmox storage:
- In the left panel, click your storage (e.g.,
local), then click ISO Images → Upload. - Select the Ubuntu Server ISO from your computer and upload it.
- In the left panel, click your storage (e.g.,
-
Click Create VM in the top-right corner.
-
Work through the wizard using these settings:
Tab Setting Value General Name librenmsOS 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 -
On the final Confirm tab, check Start after created and click Finish.
-
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
-
Log in to the vSphere Client (web browser) or the ESXi host's direct management page.
-
Upload the Ubuntu ISO:
- Click Storage → select your datastore → Files → Upload → select the ISO.
-
Click Create / Register VM and choose Create a new virtual machine.
-
Configure the VM:
Setting Value Name librenmsCompatibility 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 -
Make sure Connect at Power On is checked for the CD/DVD drive.
-
Click Finish, then right-click the VM and select Power On.
-
Open the Web Console from the VM's summary page. Continue to Part 2.
1.3 Hyper-V
-
Open Hyper-V Manager on your Windows Server or Windows 10/11 machine.
-
In the right-hand Actions panel, click New → Virtual Machine.
-
Work through the wizard:
Step Setting Value Name and Location Name librenmsSpecify Generation Generation Generation 2 Assign Memory Startup memory 8192MBAssign Memory Dynamic Memory Uncheck (use fixed memory) Configure Networking Connection Your management virtual switch Virtual Hard Disk Size 80GBInstallation 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). -
Click Finish, then right-click the VM in the list and select Start.
-
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.
-
Language: Select
Englishand press Enter. -
Keyboard: Choose your keyboard layout (usually
English (US)). -
Type of Install: Choose Ubuntu Server (not minimized).
-
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.
-
Proxy: Leave blank and press Enter.
-
Ubuntu Archive Mirror: Accept the default and continue.
-
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.
-
Profile Setup: Fill in:
- Your name:
IT Admin(or your name) - Server name:
librenms - Username:
itadmin(or your preferred username — avoidadminas it is sometimes reserved) - Password: Choose a strong password and confirm it.
- Your name:
-
SSH: Check Install OpenSSH Server. This lets you connect remotely via SSH without needing the console.
-
Featured Snaps: Do not select anything here. Press Done.
-
Installation will proceed automatically. When complete, press Reboot Now. When prompted, press Enter to eject the virtual disc.
-
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.
-
Log into the VM console (or SSH using the DHCP address).
-
Find your network interface name:
ip link showLook for an interface name that is not
lo. It will typically beens18(Proxmox),ens192(VMware), oreth0(Hyper-V). -
Open the Netplan config file (the filename may vary slightly):
sudo nano /etc/netplan/00-installer-config.yaml -
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.
-
Save the file (Ctrl+X → Y → Enter).
-
Apply the new configuration:
sudo netplan apply -
Verify the IP address took effect:
ip addr showYou should see your chosen IP address listed under your interface.
-
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:
exitThen 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
.envfile 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.orgto 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_HEREas-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
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
-
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
- Using hostname:
-
Log in with username
adminand the password you just created. -
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 internalCaddy 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.
- In LibreNMS, click on the admin username in the top-right corner → API Access.
- Click Create New Token.
- Give it a description like
Oxidized Integrationand click Create. - 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.
5.6 Link Oxidized Inside LibreNMS
Tell LibreNMS where Oxidized is running so you can view configs directly from device pages.
-
In LibreNMS, go to Settings (gear icon, top-right) → External Integration → Oxidized.
-
Fill in:
- Oxidized URL:
http://oxidized:8888 - Enable: Enabled
- Oxidized URL:
-
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 sysDescrReplace
192.168.1.10with 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
insideor 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:
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:
- Go to Device → Setup → Operations.
- Under Miscellaneous, click SNMP Setup.
- Set:
- Location: Your location string
- Contact: Your email
- Go to Device → Server Profiles → SNMP Trap — this is for traps, which is optional.
- 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.50is 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:
- Open Server Manager → Manage → Add Roles and Features.
- Click through to Features and check SNMP Service.
- Install it.
- After installation, open Services (search for it in Start), find SNMP Service, right-click → Properties.
- 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.
- Under "Accepted community names," click Add → select READ ONLY → enter
- 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
-
In LibreNMS, click Devices in the top navigation → Add Device.
-
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 -
Leave other fields at their defaults unless you know you need to change them.
-
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:
- Go to Settings (gear icon) → Discovery.
- Ensure Discovery is enabled.
- Under Networks to Discover, add your subnet ranges (e.g.,
192.168.1.0/24,10.10.0.0/16). - 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:
- Go to Devices → Manage Groups → Create Group.
- Give the group a name (e.g.,
Core Switches,Building A,Firewalls). - Choose Dynamic (automatic, rule-based) or Static (manual membership).
- For a dynamic group, set rules such as:
type = network→ groups all network gearhostname contains bldg-a→ groups devices with that naming patternos = 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:
- Go to Alerts → Alert Rules.
- Click Alert Rule Collection at the top.
- 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:
- Click Create Rule.
- Give it a name (e.g.,
Device Unreachable). - Set the Rule using the builder:
devices.status = 0— triggers when a device status is down
- Set Severity (critical, warning, info).
- Set Delay — how long the condition must be true before alerting (e.g., 5 minutes avoids alerts on brief blips).
- 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
- Go to Alerts → Alert Transports → Create Transport.
- Choose Mail.
- Fill in:
- Transport Name:
Email Alerts - Email(s):
helpdesk@yourschool.org(comma-separate multiple addresses)
- Transport Name:
- 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
-
In Microsoft Teams, create an Incoming Webhook connector on the channel where you want alerts:
- Open the channel → click ... → Connectors → Incoming Webhook → Configure.
- Give it a name and copy the webhook URL.
-
Back in LibreNMS, go to Alerts → Alert Transports → Create Transport.
-
Choose Microsoft Teams.
-
Paste the webhook URL and save.
Slack Transport
- In Slack, go to your workspace's app settings and create an Incoming Webhooks app.
- Create a webhook for your chosen channel and copy the URL.
- 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.
-
Go to Alerts → Alert Templates → Create Template.
-
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 }}/ -
Assign this template to your alert rules by editing each rule and selecting your template.
Part 9 — Managing Device Dependencies
Why Dependencies Matter
When an uplink switch goes down, everything behind it also becomes unreachable. Without dependency mapping, LibreNMS will fire an alert for every single device behind that switch — potentially hundreds of alerts — when the real problem is one switch.
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
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:
- On the parent device's page, click Edit → temporarily change its status to Disabled.
- Check Alerts — you should see alerts only for the parent, not for all downstream children.
- 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:
| 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
- In LibreNMS, go to the device's page.
- Click the Configs tab.
- Click on any backup entry to see the full configuration at that point in time.
- 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_PASSWORDin.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
- Verify SNMP is configured on the device.
- Test SNMP manually:
docker exec librenms_app snmpwalk -v2c -c YOUR_COMMUNITY <device_ip> sysDescr - Check that UDP 161 is permitted from the LibreNMS IP on any ACLs or firewalls between them.
- Force a poll:
docker exec librenms_app lnms device:poll <device_ip>
Oxidized shows fail for all devices
- Check that the API token in
/opt/monitoring/oxidized/configis correct. - Verify Oxidized can reach LibreNMS:
docker exec oxidized curl http://librenms_app:8000/api/v0/oxidized -H "X-Auth-Token: YOUR_TOKEN" - Check credentials — ensure the username/password in the config can SSH into your devices.
Oxidized shows fail for specific device
- Try SSH manually from the Oxidized container:
docker exec oxidized ssh username@device_ip - Check whether the device requires an enable password (add
secret: your_enable_passwordto the device in LibreNMS's Oxidized settings). - Ensure the device's OS is listed in the
model_mapin the Oxidized config.
Caddy not serving HTTPS / certificate error
docker compose logs caddy
Common causes:
- Hostname in
Caddyfiledoes 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