Back to Learn

containerlab β€” spin up containerized network labs

Define multi-vendor network topologies as simple YAML and deploy them in seconds with Docker. Perfect for testing automation, learning protocols and running labs in CI.

Docker
Nokia SR Linux
Arista cEOS
FRR
Network labs
CI
Topologies are declarative YAML: nodes + links
Multi-vendor: SR Linux, Arista cEOS, FRR, Cisco and more
deploy / inspect / destroy drive the full lab lifecycle

Detailed setup

Prerequisites

  • A Linux host or VM (Ubuntu/Debian/RHEL) β€” or WSL2 / a Linux VM on Windows & macOS.
  • Docker Engine 20.10+ installed and running, with your user in the docker group.
  • x86_64/amd64 CPU, 2+ vCPU and 4 GB+ RAM (more for multi-node or cEOS labs).
  • Outbound internet access to pull the clab binary and container images.
  • sudo privileges β€” containerlab manages network namespaces and virtual links.

Install steps

1 β€” Install & verify Docker

containerlab needs a working Docker runtime. Install Docker, enable the service, and add your user to the docker group so you can run labs without root for every command.

1 β€” Install & verify Docker
bash
# Install Docker (convenience script)
curl -fsSL https://get.docker.com | sh

# Run docker without sudo, then re-login
sudo usermod -aG docker $USER

# Verify the daemon is up
sudo systemctl enable --now docker
docker run --rm hello-world
2 β€” Install containerlab

The official installer detects your distro and drops the clab/containerlab binary into your PATH. Pin a version in CI for reproducible labs.

2 β€” Install containerlab
bash
# Latest release
bash -c "$(curl -sL https://get.containerlab.dev)"

# Pin a specific version (reproducible CI)
bash -c "$(curl -sL https://get.containerlab.dev)" -- -v 0.59.0

# Confirm the install
containerlab version
3 β€” Pull a free NOS image

Nokia SR Linux is publicly available, so it's the quickest way to a first lab. Other NOSes (Arista cEOS, Cisco) need images you import yourself.

3 β€” Pull a free NOS image
bash
# Pull the free SR Linux image
docker pull ghcr.io/nokia/srlinux:latest

# List local images containerlab can use
docker images | grep -E "srlinux|ceos|frr"

First lab verification

Deploy your first lab

Save the two-node srl02.clab.yml topology above, then deploy it and watch the node table appear.

Deploy your first lab
bash
containerlab deploy -t srl02.clab.yml
Confirm the nodes are running

inspect lists each node with status 'running' and a management IP. docker ps should show two clab-srl02 containers.

Confirm the nodes are running
bash
containerlab inspect -t srl02.clab.yml
docker ps --filter "name=clab-srl02"
Connect and test reachability

SSH into srl1, configure the back-to-back link, then ping srl2 to prove the virtual wire works.

Connect and test reachability
bash
ssh admin@clab-srl02-srl1   # password: NokiaSrl1!
# In the SR Linux CLI, verify interfaces are up
show interface ethernet-1/1
Tear the lab down

When you're done, destroy removes the containers and links so nothing lingers on the host.

Tear the lab down
bash
containerlab destroy -t srl02.clab.yml --cleanup

Complete first lab β€” copy, apply, destroy

Everything you need for a working two-node lab in one place: a full topology YAML with management addressing, the exact commands to apply it, and the commands to tear it down.

1 β€” Sample topology YAML

first-lab.clab.yml
yaml
# first-lab.clab.yml
# A complete, self-contained two-node lab.
# srl1 <--- ethernet-1/1 ---> srl2 (back-to-back link)
name: first-lab

topology:
  nodes:
    srl1:
      kind: nokia_srlinux
      image: ghcr.io/nokia/srlinux:latest
      mgmt-ipv4: 172.20.20.11
    srl2:
      kind: nokia_srlinux
      image: ghcr.io/nokia/srlinux:latest
      mgmt-ipv4: 172.20.20.12

  links:
    - endpoints: ["srl1:e1-1", "srl2:e1-1"]

mgmt:
  network: clab-first-lab
  ipv4-subnet: 172.20.20.0/24

2 β€” Apply (deploy) the lab

apply
bash
# 1. Save the YAML above as first-lab.clab.yml in an empty directory
mkdir -p ~/labs/first-lab && cd ~/labs/first-lab
# (paste the topology into first-lab.clab.yml)

# 2. Deploy (apply) the lab β€” pulls images, creates nodes + links
sudo containerlab deploy -t first-lab.clab.yml

# 3. Confirm both nodes are running with their mgmt IPs
sudo containerlab inspect -t first-lab.clab.yml

# 4. Connect to a node and check the back-to-back interface
ssh admin@172.20.20.11        # password: NokiaSrl1!
# inside SR Linux:
show interface ethernet-1/1

3 β€” Topology diagram

Two SR Linux nodes on a shared management network, joined by a single back-to-back link.

topology (diagram)
text
        clab-first-lab  (mgmt 172.20.20.0/24)
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚                                              β”‚
   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
   β”‚   β”‚     srl1      β”‚ e1-1   β”‚     srl2      β”‚ β”‚
   β”‚   β”‚ nokia_srlinux β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€ nokia_srlinux β”‚ β”‚
   β”‚   β”‚ 172.20.20.11  β”‚  link  β”‚ 172.20.20.12  β”‚ β”‚
   β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
   β”‚                                              β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

4 β€” Expected device status

After deploy, containerlab inspect should show both nodes running with their management IPs.

containerlab inspect (expected)
text
+---+----------------------+--------------+-----------------------+---------------+---------+----------------+
| # |         Name         | Container ID |         Image         |     Kind      |  State  |  IPv4 Address  |
+---+----------------------+--------------+-----------------------+---------------+---------+----------------+
| 1 | clab-first-lab-srl1  | a1b2c3d4e5f6 | ghcr.io/nokia/srlinux | nokia_srlinux | running | 172.20.20.11/24|
| 2 | clab-first-lab-srl2  | f6e5d4c3b2a1 | ghcr.io/nokia/srlinux | nokia_srlinux | running | 172.20.20.12/24|
+---+----------------------+--------------+-----------------------+---------------+---------+----------------+
# Both nodes must show State = running with a /24 mgmt address.

5 β€” Destroy the lab

destroy
bash
# Tear the lab down (remove containers + virtual links)
sudo containerlab destroy -t first-lab.clab.yml

# Also delete the generated clab-first-lab/ directory (clean slate for CI)
sudo containerlab destroy -t first-lab.clab.yml --cleanup

Interactive runner β€” click to apply, inspect & destroy

A simulated containerlab session. Click a command to stream realistic output and watch the node status update live. No real containers are created β€” it's a safe way to see the lifecycle.

Nodes:srl1downsrl2down
containerlab β€” first-lab0 lines
Click a command above to start…

Troubleshooting β€” common first-lab issues

When a first lab misbehaves, work top to bottom: read the logs, find the matching symptom, apply the fix.

Deploy hangs or fails pulling the image

Likely cause: No internet access, wrong image ref, or not logged in to the registry.

Logs to check

logs
bash
# Watch the deploy with debug logging
sudo containerlab deploy -t first-lab.clab.yml --debug
# Try the pull manually to see the real error
docker pull ghcr.io/nokia/srlinux:latest

Fix: Confirm outbound HTTPS to ghcr.io, fix the image: field, then redeploy with --reconfigure.

Node stuck in 'created' / not 'running'

Likely cause: The container crash-looped on boot (often low memory or a bad startup config).

Logs to check

logs
bash
# Inspect status and the node's own logs
sudo containerlab inspect -t first-lab.clab.yml
docker logs clab-first-lab-srl1 --tail 50

Fix: Free up RAM (SR Linux needs ~1 GB/node), remove a broken startup-config, then redeploy.

'permission denied' talking to Docker

Likely cause: Your user is not in the docker group, or the daemon is not running.

Logs to check

logs
bash
systemctl status docker
groups $USER   # should list 'docker'

Fix: Run: sudo usermod -aG docker $USER, log out/in, and sudo systemctl enable --now docker.

SSH to a node is refused

Likely cause: The node is still booting, or you used the wrong management IP/name.

Logs to check

logs
bash
sudo containerlab inspect -t first-lab.clab.yml   # copy the exact IPv4
docker ps --filter "name=clab-first-lab"

Fix: Wait ~30–60s for the NOS to finish booting, then ssh admin@<mgmt-ip> (password NokiaSrl1!).

'network already exists' / address overlap

Likely cause: A previous lab was not cleaned up and left its docker network behind.

Logs to check

logs
bash
docker network ls | grep clab
sudo containerlab inspect --all

Fix: Run containerlab destroy --cleanup on the old lab (see cleanup step), then redeploy.

Cleanup & verification β€” confirm a clean slate

Destroy alone usually removes everything, but always verify: leftover containers or docker networks cause "already exists" errors on your next deploy. Each check below should return empty output.

cleanup & verify
bash
# 1. Destroy and remove the generated lab directory
sudo containerlab destroy -t first-lab.clab.yml --cleanup

# 2. Confirm NO lab containers remain (expect empty output)
docker ps -a --filter "name=clab-first-lab"

# 3. Confirm the management network is gone (expect empty output)
docker network ls | grep clab-first-lab

# 4. Double-check containerlab itself sees no running labs
sudo containerlab inspect --all

# 5. (Optional) prune dangling resources left by old labs
docker network prune -f

First-lab variants β€” tweak nodes & links

Same workflow, different topology. Copy a variant's YAML, then run its exact apply/destroy commands.

Variant A β€” Arista cEOS nodes
Different node image

Swap the SR Linux nodes for Arista cEOS. The image must be imported locally first (docker import cEOS-lab.tar.xz ceos:4.30). Only the kind/image change β€” links stay the same.

Variant A β€” topology
yaml
# ceos-lab.clab.yml
name: ceos-lab
topology:
  nodes:
    ceos1:
      kind: arista_ceos
      image: ceos:4.30
    ceos2:
      kind: arista_ceos
      image: ceos:4.30
  links:
    - endpoints: ["ceos1:eth1", "ceos2:eth1"]
apply
bash
sudo containerlab deploy -t ceos-lab.clab.yml
sudo containerlab inspect -t ceos-lab.clab.yml
destroy
bash
sudo containerlab destroy -t ceos-lab.clab.yml --cleanup
Variant B β€” FRR + host link type
Different link type

Use the lightweight FRR image and attach a node interface to the host with a 'host' link type β€” handy for bridging a lab into your machine's networking.

Variant B β€” topology
yaml
# frr-host.clab.yml
name: frr-host
topology:
  nodes:
    frr1:
      kind: linux
      image: frrouting/frr:latest
  links:
    # link type: connect frr1 eth1 to a host interface
    - type: host
      endpoint:
        node: frr1
        interface: eth1
      host-interface: clab-frr1-eth1
apply
bash
sudo containerlab deploy -t frr-host.clab.yml
sudo containerlab inspect -t frr-host.clab.yml
destroy
bash
sudo containerlab destroy -t frr-host.clab.yml --cleanup
Variant C β€” three-node line (mgmt-only links)
More nodes

Scale to three SR Linux nodes wired in a line. Add nodes under topology.nodes and one more link entry β€” apply/destroy commands are identical aside from the file name.

Variant C β€” topology
yaml
# srl-line.clab.yml
name: srl-line
topology:
  nodes:
    srl1: { kind: nokia_srlinux, image: ghcr.io/nokia/srlinux:latest }
    srl2: { kind: nokia_srlinux, image: ghcr.io/nokia/srlinux:latest }
    srl3: { kind: nokia_srlinux, image: ghcr.io/nokia/srlinux:latest }
  links:
    - endpoints: ["srl1:e1-1", "srl2:e1-1"]
    - endpoints: ["srl2:e1-2", "srl3:e1-1"]
apply
bash
sudo containerlab deploy -t srl-line.clab.yml
sudo containerlab inspect -t srl-line.clab.yml
destroy
bash
sudo containerlab destroy -t srl-line.clab.yml --cleanup

Next steps β€” expand your topology

  • Add a third node and a second link to turn the line into a triangle (redundant paths).
  • Configure an IGP (OSPF/IS-IS) between nodes and verify adjacencies with show commands.
  • Add a startup-config per node so the lab boots pre-configured every time.
  • Introduce a Linux 'client' node on each side to test end-to-end reachability with ping.
  • Point Netmiko, Nornir or Ansible at the node mgmt IPs to automate the config.
  • Commit your .clab.yml to git and run containerlab deploy/destroy in a CI pipeline.

Setup, key lab examples & run commands

Step 0 β€” install
Setup

containerlab runs on Linux with Docker. The install script drops the clab binary in your PATH. You also need the container images for the NOSes you plan to lab (Nokia SR Linux is free to pull).

Step 0 β€” install
bash
# Docker must be installed and running first
bash -c "$(curl -sL https://get.containerlab.dev)"

# verify
containerlab version   # or: clab version
srl02.clab.yml β€” topology
Topology as YAML

A topology file declares nodes (by kind + image) and the links between them. This two-node Nokia SR Linux lab connects e1-1 on each switch back to back.

srl02.clab.yml β€” topology
yaml
name: srl02

topology:
  nodes:
    srl1:
      kind: nokia_srlinux
      image: ghcr.io/nokia/srlinux
    srl2:
      kind: nokia_srlinux
      image: ghcr.io/nokia/srlinux
  links:
    - endpoints: ["srl1:e1-1", "srl2:e1-1"]
deploy β€” bring the lab up
Deploy

Deploy reads the topology, pulls images if needed, creates the containers and wires up the links. The output table lists each node's name, container and management IP.

deploy β€” bring the lab up
bash
containerlab deploy -t srl02.clab.yml

# redeploy from scratch (destroy + deploy)
containerlab deploy -t srl02.clab.yml --reconfigure
inspect & connect
Operate

List running labs and node details with inspect, then SSH or open the NOS CLI on any node by its lab-prefixed name.

inspect & connect
bash
# list nodes, status and mgmt IPs
containerlab inspect -t srl02.clab.yml

# connect to the SR Linux CLI
ssh admin@clab-srl02-srl1
# or drop into the container shell
docker exec -it clab-srl02-srl1 sr_cli
destroy β€” tear down
Cleanup

Destroy removes all containers and the virtual links. Add --cleanup to also delete the generated lab directory β€” handy for CI pipelines that build a fresh topology each run.

destroy β€” tear down
bash
containerlab destroy -t srl02.clab.yml

# also remove the clab-srl02/ lab directory
containerlab destroy -t srl02.clab.yml --cleanup

containerlab pairs perfectly with automation tools β€” deploy a topology, then point Netmiko, Nornir or Ansible at the nodes to test configs and CI pipelines before touching real gear.