diff --git a/.gitignore b/.gitignore
index e2a3e9346c070336a189a33c39c09130942da8fe..01699bf8df9e74459303584f5390d95e6ad0d10e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,7 @@ htmlcov
 dist
 docs/build
 .coverage*
+bom.json
 
 # logs
 *.log
diff --git a/Jenkinsfile b/Jenkinsfile
index bd5177efe9649b374c8215df5aa560d2a6e68f3d..47f5288712ff8b913af6bed3786427322fee8a52 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -7,6 +7,6 @@ library 'SWDPipeline'
 // python_test_versions (list of python versions, resolving to docker tags, to test against)
 String name = 'brian-dashboard-manager'
 List<String> extraRecipients = ['bjarke@nordu.net', 'erik.reid@geant.org', 'sam.roberts@geant.org', 'pelle.koster@geant.org']
-List<String> pythonTestVersions = ['3.6', '3.11']
+List<String> pythonTestVersions = ['3.11']
 
 SimplePythonBuild(name, extraRecipients, pythonTestVersions)
diff --git a/brian_dashboard_manager/dashboards/region_eap.json b/brian_dashboard_manager/dashboards/region_eap.json
index 8897ba6bd2e33aab8e7a60f19bafd502f7b9b9fb..42efd783752b9990e18d189ec998fb988e243516 100644
--- a/brian_dashboard_manager/dashboards/region_eap.json
+++ b/brian_dashboard_manager/dashboards/region_eap.json
@@ -90,6 +90,7 @@
   "schemaVersion": 26,
   "style": "dark",
    "tags": [
+    "customers"
   ],
   "templating": {
     "list": []
diff --git a/brian_dashboard_manager/grafana/provision.py b/brian_dashboard_manager/grafana/provision.py
index 6cfafec124540725db385d03e084b2caea418c42..941346e117cb20d4af35fd950b59eb130ec06e21 100644
--- a/brian_dashboard_manager/grafana/provision.py
+++ b/brian_dashboard_manager/grafana/provision.py
@@ -942,7 +942,12 @@ def provision(config):
     """
 
     start = time.time()
-    all_orgs = _provision_orgs(config)
+    try:
+        all_orgs = _provision_orgs(config)
+    except Exception:
+        logger.exception('Error when provisioning orgs')
+        return
+
     request = AdminRequest(**config)
     try:
         # needed for older versions of grafana (<11.0)
@@ -961,9 +966,13 @@ def provision(config):
             return None
 
     orgs = list(filter(lambda t: t[1] is not None, [(org, _find_org_config(org)) for org in all_orgs]))
-    interfaces = get_interfaces(config['inventory_provider'])
-    services = fetch_services(config['reporting_provider'])
-    regions = get_nren_regions(config['inventory_provider'])
+    try:
+        interfaces = get_interfaces(config['inventory_provider'])
+        services = fetch_services(config['reporting_provider'])
+        regions = get_nren_regions(config['inventory_provider'])
+    except Exception:
+        logger.exception('Error when fetching interfaces:')
+        return
     for org, org_config in orgs:
         _provision_org(config, org, org_config, interfaces, services, regions)
 
diff --git a/brian_dashboard_manager/inventory_provider/interfaces.py b/brian_dashboard_manager/inventory_provider/interfaces.py
index c342817842d6ad70c766ef90dd4381f162ea9473..df6ba6559b4900b1105d059117255a9d3cb08486 100644
--- a/brian_dashboard_manager/inventory_provider/interfaces.py
+++ b/brian_dashboard_manager/inventory_provider/interfaces.py
@@ -322,7 +322,7 @@ def _get_ip_info(host):
 
         return prev
     try:
-        r = requests.get(f'{host}/data/interfaces')
+        r = requests.get(f'{host}/data/interfaces', timeout=5)
         r.raise_for_status()
         interfaces = r.json()
     except HTTPError:
@@ -341,7 +341,7 @@ def get_interfaces(host):
     :return: A list of interfaces with IP information added, if present.
     """
 
-    r = requests.get(f'{host}/poller/interfaces')
+    r = requests.get(f'{host}/poller/interfaces', timeout=5)
     try:
         r.raise_for_status()
         interfaces = r.json()
@@ -415,7 +415,7 @@ def get_gws_direct(host):
     :return: GWS direct data
     """
 
-    r = requests.get(f'{host}/poller/gws/direct')
+    r = requests.get(f'{host}/poller/gws/direct', timeout=5)
     try:
         r.raise_for_status()
         interfaces = r.json()
@@ -435,7 +435,7 @@ def get_gws_indirect(host):
     :return: GWS Indirect data
     """
     try:
-        r = requests.get(f'{host}/poller/gws/indirect')
+        r = requests.get(f'{host}/poller/gws/indirect', timeout=5)
         r.raise_for_status()
         interfaces = r.json()
     except HTTPError:
@@ -452,7 +452,7 @@ def get_eumetsat_multicast_subscriptions(host):
     :return: EUMETSAT multicast subscriptions
     """
     try:
-        r = requests.get(f'{host}/poller/eumetsat-multicast')
+        r = requests.get(f'{host}/poller/eumetsat-multicast', timeout=5)
         r.raise_for_status()
         data = r.json()
     except HTTPError:
diff --git a/brian_dashboard_manager/routes/update.py b/brian_dashboard_manager/routes/update.py
index 5c81c011f400dde670fa7551a54571f71dfe7999..c5cd92368286154eaee415c5165b7376325707fb 100644
--- a/brian_dashboard_manager/routes/update.py
+++ b/brian_dashboard_manager/routes/update.py
@@ -38,7 +38,7 @@ def provision_maybe():
         and the timestamp of the last provisioning, respectively.
     """
 
-    global provision_state
+    global provision_state  # noqa: F824
 
     now = datetime.datetime.now(datetime.timezone.utc)
     timestamp = provision_state['time']
diff --git a/brian_dashboard_manager/templating/helpers.py b/brian_dashboard_manager/templating/helpers.py
index e3f58ac01649a948830268f28eaf933fe23a5374..649179452a6de94805496aa2f00a9eda9d396fd0 100644
--- a/brian_dashboard_manager/templating/helpers.py
+++ b/brian_dashboard_manager/templating/helpers.py
@@ -24,6 +24,18 @@ PANEL_WIDTH = 24
 logger = logging.getLogger(__file__)
 
 
+def endpoint_sort_key(endpoint):
+    # sort by equipment/port if exists, otherwise host/interface
+    if 'equipment' in endpoint:
+        equipment = endpoint['equipment']
+        port = endpoint['port']
+        return equipment, port
+    else:
+        hostname = endpoint['hostname']
+        interface = endpoint['interface']
+        return hostname, interface
+
+
 def num_generator(start=30):
     """
     Generator for numbers starting from the value of `start`
@@ -223,7 +235,7 @@ def get_re_peer_interface_data(interfaces):
 
 def get_service_aggregate_targets(services):
     for service in services:
-        _interfaces = service.get('endpoints')
+        _interfaces = sorted(service.get('endpoints', []), key=endpoint_sort_key)
         name = service.get('name')
         sid = service.get('sid')
         scid = service.get('scid')
@@ -309,7 +321,7 @@ def get_nren_interface_data(services, interfaces, excluded_dashboards, region_cu
             dashboard['AGGREGATES'].append(target)
 
         for service in services:
-            _interfaces = service.get('endpoints')
+            _interfaces = sorted(service.get('endpoints', []), key=endpoint_sort_key)
             name = service.get('name')
             sid = service.get('sid')
             scid = service.get('scid')
@@ -450,7 +462,7 @@ def get_service_data(service_type, services, interfaces, excluded_dashboards):
         })
 
         for service in services:
-            _interfaces = service.get('endpoints')
+            _interfaces = sorted(service.get('endpoints', []), key=endpoint_sort_key)
             name = service.get('name')
             sid = service.get('sid')
             scid = service.get('scid')
diff --git a/changelog.md b/changelog.md
index 6110d8663e866c95215c3300ed245c53614e5738..946c263da51b3fe1e296af14c221c9e95affa1f5 100644
--- a/changelog.md
+++ b/changelog.md
@@ -2,6 +2,10 @@
 
 All notable changes to this project will be documented in this file.
 
+## [0.79] - 2025-05-30
+- POL1-898: Unify logic for selecting interface between poller-udf and brian-dashboard-manager
+- Add EAP Nren dashboard to NREN Access dropdown
+
 ## [0.78] - 2025-02-06
 - Add Router VLANs dropdown for staff
 - Add VLAN dashboard skeleton
diff --git a/docker-setup/Dockerfile b/docker-setup/Dockerfile
deleted file mode 100644
index 2fc46ac50f52de38a61aa9a60c55d96f7dea76c9..0000000000000000000000000000000000000000
--- a/docker-setup/Dockerfile
+++ /dev/null
@@ -1,30 +0,0 @@
-FROM alpine:3.8
-
-# Build arguments
-## The database user name
-ARG DBUSER
-## The user's password
-ARG DBPASS
-## The database name
-ARG DBNAME
-
-
-# Forward the args to the container
-ENV DBUSER=${DBUSER}
-ENV DBPASS=${DBPASS}
-ENV DBNAME=${DBNAME}
-
-ENV PGDATA "/var/lib/postgresql"
-
-RUN apk update && \
-    apk add postgresql postgresql-contrib
-
-RUN mkdir -p /run/postgresql && chmod a+w /run/postgresql
-
-ADD entrypoint.sh /entrypoint.sh
-RUN chmod +x /entrypoint.sh
-USER postgres
-
-VOLUME $PGDATA
-CMD ["/entrypoint.sh"]
-EXPOSE 5432
diff --git a/setup.py b/setup.py
index 9662590526bd6c11dcfdd548da29f63a9755e67d..45bd43677c7784d951e7d6d845faafbf581e9bbf 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
 
 setup(
     name='brian-dashboard-manager',
-    version="0.78",
+    version="0.79",
     author='GEANT',
     author_email='swd@geant.org',
     description='',
diff --git a/tox.ini b/tox.ini
index 3d311c9638bc099a522e82a04acc1d90be9a4ebe..65321cbc6d912821ddfc42a3acb3db3e5a826bd0 100644
--- a/tox.ini
+++ b/tox.ini
@@ -10,12 +10,15 @@ concurrency = multiprocessing,thread
 
 [testenv]
 deps =
+    pytest-xdist
     pytest-cov
     flake8
+    cyclonedx-py
     -r requirements.txt
 
 commands =
     coverage erase
-    pytest --cov brian_dashboard_manager --cov-fail-under=75 --cov-report html --cov-report xml --cov-report term -p no:checkdocs
+    pytest -n auto --cov brian_dashboard_manager --cov-fail-under=75 --cov-report html --cov-report xml --cov-report term -p no:checkdocs
     flake8
     sphinx-build -M html docs/source docs/build
+    cyclonedx-py environment --output-format json -o bom.json