Concepts
Four pages that explain why the lab is shaped the way it is. Read Architecture first; the rest can be read in any order.
In this section
-
Every container, which compose file declares it, which network it is on, which port it publishes. Why the lab uses two compose files combined through
COMPOSE_FILE, and how the devices end up on the same bridge as the worker. -
topology.jsonholds every device, management IP, vendor, loopback and interface.gen_clab_topologyrenders the containerlab topology, the per-device configs and three of the four discovery parameter files from it. Nothing else is authored by hand. -
The workflow, the function block it dispatches to, and the parameter contract: subnets, platforms, and how credentials are scoped. Also: the function block lives in the worker image, not in this repo.
-
The repo is bind-mounted read-only at
/app/labinside the worker, which is why in-container paths keep alab/prefix while host paths never do. The single most confusing thing about this repo, explained once.
The one-paragraph version
topology.json describes 15 devices. gen_clab_topology turns that into a containerlab topology plus per-device configs plus discovery parameters. containerlab deploys the devices onto the lab-net bridge at fixed management IPs. Docker compose runs the NeOps control plane, with the worker attached to both the default network (to reach the engine) and lab-net (to reach the devices). A one-shot bootstrap container registers the workflow definitions with the engine. Running the discovery workflow dispatches a function block onto the worker, which SSHes to every management IP and writes Device and Interface rows into the CMS.
