Skip to content

Instantly share code, notes, and snippets.

@dot-mike
Last active August 20, 2026 09:14
Show Gist options
  • Select an option

  • Save dot-mike/a95cc0b5b90b262b640ff2da7d96577d to your computer and use it in GitHub Desktop.

Select an option

Save dot-mike/a95cc0b5b90b262b640ff2da7d96577d to your computer and use it in GitHub Desktop.
LibreNMS deveveloper environment with DDEV

LibreNMS dev environment with DDEV

Run LibreNMS application locally for development, without PHP, mariadb-server or redis on the host. Only Docker, git and DDEV are needed.

Tested on Ubuntu 24.04 (WSL2), DDEV 1.25, Docker 29.

This setup binds everything to 127.0.0.1 with fixed ports, so nothing depends on *.ddev.site DNS. LibreNMS is accessible on htttps://127.0.0.1:8888

Login with: u: admin / p: admin

Install DDEV

sudo apt-get update -y && sudo apt-get install -y curl
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://pkg.ddev.com/apt/gpg.key | sudo tee /etc/apt/keyrings/ddev.asc > /dev/null
sudo chmod a+r /etc/apt/keyrings/ddev.asc
printf "Types: deb\nURIs: https://pkg.ddev.com/apt/\nSuites: *\nComponents: *\nSigned-By: /etc/apt/keyrings/ddev.asc\n" | sudo tee /etc/apt/sources.list.d/ddev.sources >/dev/null
sudo apt-get update -y && sudo apt-get install -y ddev
mkcert -install

Save attached librenms-setup.sh as new file and chmod +x librenms-setup.sh, run it in an empty directory. Ports are overridable: HTTP_PORT=9000 ./librenms-setup.sh.

Now start it with command ddev start.

Check that it all went well

# web, db, redis all OK
ddev describe
# should reply PONG
ddev redis-cli ping
ddev artisan migrate:status
curl -sk https://librenms.ddev.site/login | grep -o '<title>.*</title>'

Usage

Start / stop with: ddev start / ddev stop / ddev poweroff

Reset everything: ddev stop --remove-data && ddev start.

Useful commands

# web container logs
ddev logs -f
# open in browser
ddev launch
# db shell (db/db/db, root/root)
ddev mysql
# redis-cli
ddev redis-cli
# laravel cli
ddev artisan tinker
# LibreNMS CLI
ddev exec "php lnms list"

PHP and Blade changes need no rebuild. Frontend:

Tests and lint before a PR:

```bash
ddev artisan test
ddev exec "vendor/bin/phpstan analyse"
ddev exec "vendor/bin/php-cs-fixer fix --dry-run --diff"

Polling and SNMP

If SNMP support is needed, uncomment webimage_extra_packages in .ddev/config.yaml and ddev restart.

Simulated devices come from lnms dev:simulate, which serves one of the 1900+ .snmprec recordings in tests/snmpsim/ over a local snmpsim daemon and registers it as a device. snmpsim is Python, so install it first:

ddev exec "php lnms dev:simulate --setup-venv"

# start sim + add device 'snmpsim'
ddev exec "php lnms dev:simulate ios_c3560e"
ddev exec "php lnms device:discover snmpsim -vv"
ddev exec "php lnms device:poll snmpsim -vv"
ddev exec "snmpget -v2c -c ios_c3560e 127.1.6.1:1161 sysDescr.0"

# remove
ddev exec "php lnms dev:simulate ios_c3560e -r"
#!/usr/bin/env bash
# Bootstrap a LibreNMS dev environment with DDEV, bound to 127.0.0.1.
# Usage: ./librenms-setup.sh [git-url] [dir]
set -euo pipefail
REPO="${1:-https://github.com/librenms/librenms.git}"
DIR="${2:-librenms-dev}"
PROJECT="${PROJECT:-librenms}"
HTTP_PORT="${HTTP_PORT:-8888}"
HTTPS_PORT="${HTTPS_PORT:-8889}"
DB_PORT="${DB_PORT:-3388}"
ADMIN_PASS="${ADMIN_PASS:-admin}"
ADMIN_MAIL="${ADMIN_MAIL:-admin@example.com}"
BASE_URL="http://127.0.0.1:${HTTP_PORT}"
command -v ddev >/dev/null || { echo "ddev not installed"; exit 1; }
for p in "$HTTP_PORT" "$HTTPS_PORT" "$DB_PORT"; do
ss -ltn | grep -q ":$p " && { echo "port $p already in use"; exit 1; }
done
git clone "$REPO" "$DIR"
cd "$DIR"
git remote get-url upstream >/dev/null 2>&1 || \
git remote add upstream https://github.com/librenms/librenms.git
# docroot is html/, not public/ - LibreNMS predates the modern Laravel skeleton
ddev config --project-type=laravel --project-name="$PROJECT" --docroot=html \
--php-version=8.4 --database=mariadb:10.11 --nodejs-version=22 \
--host-webserver-port="$HTTP_PORT" \
--host-https-port="$HTTPS_PORT" \
--host-db-port="$DB_PORT"
# Redis is required for cache, sessions and locks
ddev add-on get ddev/ddev-redis
# The laravel project type already writes a webimage_extra_packages line.
# Append to it - a second key makes the YAML invalid and bricks the project.
# python3-venv is needed by `lnms dev:simulate --setup-venv`.
sed -i "s|^webimage_extra_packages: \[\(.*\)\]|webimage_extra_packages: [\1, rrdtool, snmp, fping, nmap, whois, python3-pip, python3-venv, 'php\${DDEV_PHP_VERSION}-gmp']|" \
.ddev/config.yaml
ddev start
# DDEV creates .env from .env.example with DB creds filled in. Add the rest.
# LIBRENMS_USER must match the container user or every artisan/lnms call aborts.
cat >> .env <<EOF
APP_URL="${BASE_URL}"
APP_ENV=local
APP_DEBUG=true
CACHE_STORE=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_CLIENT=predis
LIBRENMS_USER=$(ddev exec whoami | tr -d '\r\n')
EOF
ddev composer install
ddev composer run-script post-root-package-install
ddev composer run-script post-create-project-cmd # key:generate
ddev npm install
ddev npm run build
ddev artisan migrate --force
# LibreNMS builds its own base_url from SERVER_PORT, which is always 80 inside
# the container. Without this, relative links drop the port. See notes below.
ddev exec "php lnms config:set base_url ${BASE_URL}/"
ddev exec "php lnms user:add -r admin -p '$ADMIN_PASS' -e '$ADMIN_MAIL' admin" \
|| echo "admin user already exists, skipping"
echo "Done. ${BASE_URL} admin / $ADMIN_PASS"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment