<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Labs · Network Doodles</title><link>https://networkdoodles.com/labs/</link><description>Hands-on companions to the posts. Open one in Codespaces (or on your own laptop) and let `make check` tell you when you've got it right.</description><language>en-us</language><managingEditor>David Henderson</managingEditor><lastBuildDate>Thu, 12 Nov 2026 09:00:00 -0500</lastBuildDate><atom:link href="https://networkdoodles.com/labs/index.xml" rel="self" type="application/rss+xml"/><item><title>Meet the lab</title><link>https://networkdoodles.com/labs/basics/</link><pubDate>Thu, 12 Nov 2026 09:00:00 -0500</pubDate><dc:creator>David Henderson</dc:creator><guid>https://networkdoodles.com/labs/basics/</guid><description>New to dev containers, VS Code or the terminal? Open a lab in Codespaces, learn the editor, run your first commands, edit a file, run it and prove it works.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Every lab here runs the same way: same editor, same terminal, same <code>make</code> commands, same checker. This page walks
through all of it once, slowly, so the labs themselves don&rsquo;t have to. Each lab&rsquo;s <strong>first task</strong> then covers only
what&rsquo;s specific to that lab: its network, its logins, its tools.</p>
<p>If you already live in VS Code and a terminal, skim it. If you&rsquo;ve never opened either, read it all; every lab task
also has a <strong>new to this? step by step</strong> panel for the slow version of just that task.</p>

<p>You don&rsquo;t need to know Ansible, Python, NetBox or containerlab yet. That&rsquo;s what the labs are for. The screenshots
come from the <span class="link-soon">NetBox lab</span>; every lab looks the same apart from the file names.</p>
<h2 id="the-big-picture">What you&rsquo;re about to run</h2>
<p>The whole lab lives in <strong>one container</strong>, called a <em>dev container</em>. Inside it is everything: the editor, the
tools, and its own Docker engine running whatever that lab needs, such as switches in containerlab, NetBox,
Batfish or Grafana. The easy way runs that container on GitHub&rsquo;s machines with <strong>Codespaces</strong>, so you install
nothing at all. If you&rsquo;d rather run it on your own laptop, that&rsquo;s the <a href="#laptop">advanced setup</a> at the end.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">a codespace  (or your laptop: see the advanced setup)
</span></span><span class="line"><span class="cl">└── dev container  (the lab: editor + tools + its own Docker)
</span></span><span class="line"><span class="cl">    ├── the lab app     in your browser: the guide, VS Code and the lab&#39;s tools side by side
</span></span><span class="line"><span class="cl">    ├── VS Code         the lab app&#39;s editor tab
</span></span><span class="line"><span class="cl">    ├── Python, Ansible or Terraform, containerlab, git, make   (whatever this lab uses)
</span></span><span class="line"><span class="cl">    └── Docker inside the container
</span></span><span class="line"><span class="cl">        ├── the switches          containerlab: Nokia SR Linux or CapeOS
</span></span><span class="line"><span class="cl">        └── the lab&#39;s services    NetBox, Batfish, Grafana ... (each lab&#39;s first task lists them)
</span></span></code></pre></div><h2 id="open">1 · Open the lab</h2>
<p>All you need is a browser and a free <a href="https://github.com/signup">GitHub account</a>.</p>
<ol>
<li>
<p>On the lab&rsquo;s page, click <strong>Open the lab</strong> and sign in with GitHub. The first time, GitHub asks you to let
<em>Network Doodles Labs</em> manage your codespaces: that&rsquo;s how the button creates, starts, stops and deletes the
lab&rsquo;s codespace for you. It&rsquo;s still your codespace, on your account and its free hours.</p>
</li>
<li>
<p>A page shows your codespace starting, with a bar that fills as it goes. The first start takes <strong>3 to 5
minutes</strong>; coming back to it takes about one.</p>

   <figure class="shot">
     <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">labs.networkdoodles.com</span></div>
     <a href="/images/labs/basics/lab-starting.png" target="_blank" rel="noopener" title="Open full size">
       <img src="/images/labs/basics/lab-starting_hu_e0d84601eb63adf3.webp" width="1526" height="898" alt="The starting page: a spinning ring, a bar at 96 percent, and three steps: your codespace on GitHub (done), the lab&#39;s network and app (in progress), into the lab" loading="lazy" decoding="async">
     </a><figcaption>Starting the lab: the bar fills as your codespace starts, then the lab&rsquo;s network and app. You can leave the page open and come back.</figcaption>
   </figure>

</li>
<li>
<p>The <strong>lab app</strong> opens: the lab&rsquo;s guide on the left, <strong>VS Code</strong> in a tab on the right (most labs; some have
a <a href="#topology">Topology tab</a> instead), and any other tool
the lab uses, such as Wireshark, in a tab of its own. The top bar shows the network starting, then
<strong>network up</strong>. That&rsquo;s you in.</p>
</li>
</ol>

<figure class="shot">
  <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">the lab app</span></div>
  <a href="/images/labs/basics/lab-app.png" target="_blank" rel="noopener" title="Open full size">
    <img src="/images/labs/basics/lab-app_hu_4cd19517d51ba221.webp" width="800" height="478" alt="The lab app: the guide on the left at task 1.1 with the task picker above it and Check task below, the VS Code tab on the right with the Lab status terminal, and network up in the top bar" loading="lazy" decoding="async">
  </a><figcaption>The guide on the left, with the task picker above it and <strong>Check task</strong> below. VS Code on the right. The top bar: the lab&rsquo;s tabs, <strong>network up</strong>, and your progress.</figcaption>
</figure>

<p>The guide in the lab is the same guide as on this site. Pick a task from the list above it, or follow its
links. <strong>Check task</strong>, under the guide, runs the checker for the task you&rsquo;re on (<a href="#run">step 7</a>). Everything
else on this page happens in the <strong>VS Code</strong> tab.</p>
<h3 id="topology">Labs with a Topology tab</h3>
<p>Some labs, like <a href="/labs/networking-101-lab/">Networking 101</a>, have no VS Code tab. Their first tab is
<strong>Topology</strong>, a drawing of the lab&rsquo;s network, and you do everything from there and the guide:</p>

<figure class="shot">
  <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">the lab app · Topology</span></div>
  <a href="/images/labs/basics/topology-overview.png" target="_blank" rel="noopener" title="Open full size">
    <img src="/images/labs/basics/topology-overview_hu_923c26bb75467b0e.webp" width="1600" height="1000" alt="The lab app for Networking 101: the guide at task 1.1 on the left, with Your answers, Solve it for me and Check task under it, and the Topology tab on the right drawing the laptop, printer and broken-pc, the switch sw1, routers r1 and r2, and the web and dns servers" loading="lazy" decoding="async">
  </a><figcaption>The guide on the left, with <strong>Your answers</strong>, <strong>Solve it for me</strong> and <strong>Check task</strong> under it. The network on the right. The top bar: <strong>network up</strong>, <strong>Reset network</strong> and your progress.</figcaption>
</figure>

<ul>
<li>
<p><strong>Hover</strong> over a device to see what it is, what it runs, where each of its ports is cabled, and whether
it&rsquo;s running.</p>

  <figure class="shot">
    <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">the lab app · Topology</span></div>
    <a href="/images/labs/basics/topology-hover.png" target="_blank" rel="noopener" title="Open full size">
      <img src="/images/labs/basics/topology-hover_hu_b498ae78b4b18c81.webp" width="1600" height="1000" alt="Hovering over r1 shows a card: running, the home network&#39;s router, it runs CapeOS Bolt, its ports eth1 to sw1 and eth2 to r2, and click for a terminal on r1" loading="lazy" decoding="async">
    </a>
  </figure>

</li>
<li>
<p><strong>Click</strong> a device to open a terminal on it, in a tab of its own named after it. Click it again to go back
to that tab. Several can be open side by side; close one with its <strong>×</strong>. (Typing <code>exit</code> ends that
device&rsquo;s session; press <kbd>Enter</kbd> in the tab to reconnect.)</p>

  <figure class="shot">
    <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">the lab app · laptop</span></div>
    <a href="/images/labs/basics/topology-terminal.png" target="_blank" rel="noopener" title="Open full size">
      <img src="/images/labs/basics/topology-terminal_hu_5de4244b5775c6.webp" width="1600" height="1000" alt="The laptop tab: a terminal on the laptop showing ip addr show eth1, with its MAC address aa:aa:aa:11:11:11 and IP address 192.168.1.100/24" loading="lazy" decoding="async">
    </a>
  </figure>

</li>
<li>
<p><strong>Your answers</strong> sit under the guide: a box for each question in the current task. Type an answer, then
press <kbd>Enter</kbd> or click away and it&rsquo;s saved. <strong>Check task</strong> saves them too, before it checks.
Fold the box with its arrow when you want the guide back.</p>
</li>
<li>
<p><strong>Check task</strong>, under the guide, runs the checker. <strong>Solve it for me</strong>, next to it, fills in the task for
you. <strong>Reset network</strong>, in the top bar, puts the network back how it started (it asks first; your answers
stay).</p>

  <figure class="shot">
    <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">the lab app · Check task</span></div>
    <a href="/images/labs/basics/topology-answers.png" target="_blank" rel="noopener" title="Open full size">
      <img src="/images/labs/basics/topology-answers_hu_87fd729eceaa09e7.webp" width="1600" height="1000" alt="Your answers filled in for task 1.1, and Check task&#39;s result below: every answer with a green tick" loading="lazy" decoding="async">
    </a><figcaption>Answers in, <strong>Check task</strong> clicked: a green tick for each one. Close the result with its <strong>×</strong>.</figcaption>
  </figure>

</li>
</ul>
<p>The rest of this page, from the editor to <code>make</code>, is for labs with a VS Code tab. In a Topology lab, the
guide&rsquo;s own steps say which device tab each command goes in.</p>
<p>Walk away and the codespace stops itself after <strong>20 minutes</strong> without you using the lab, so it doesn&rsquo;t eat your
free hours. Click <strong>Open the lab</strong> again to pick up where you were: your files are still there. Done with the
lab? <strong>Finish lab</strong>, top right, deletes the codespace and everything in it, and brings you back here.</p>
<p><a id="lab-app"></a></p>
<h3 id="codespaces">How Codespaces is paid for</h3>
<p>It runs on <strong>your own GitHub account</strong>, not anyone else&rsquo;s, and every account gets a free monthly allowance:
120 core-hours and 15 GB of storage (180 and 20 with GitHub Pro). The lab&rsquo;s 4-core machine uses 4 core-hours
an hour, so the allowance is about 30 hours a month. Most labs take 4 to 10 (each lab&rsquo;s page says how long).</p>
<ul>
<li>The lab stops its codespace after 20 minutes without you using it, so a forgotten tab doesn&rsquo;t eat your
hours.</li>
<li>A stopped codespace still uses storage. When you&rsquo;ve finished the lab, click <strong>Finish lab</strong> in the lab app.
If you don&rsquo;t come back, the codespace is deleted for you a week after it stops. You can also see and delete
it at <a href="https://github.com/codespaces">github.com/codespaces</a>. Want to keep your work? Commit and push first;
Codespaces offers to fork the repo for you.</li>
<li>Used up this month&rsquo;s allowance? GitHub won&rsquo;t start a codespace until it resets, unless you add a payment
method and a budget (a 4-core machine costs $0.36 an hour). Or use the <a href="#laptop">advanced setup</a>: your
laptop never runs out.</li>
</ul>
<h2 id="editor">2 · Find your way round the editor</h2>
<p>It&rsquo;s VS Code, running in your browser, in the lab app&rsquo;s <strong>VS Code</strong> tab. The screenshots on this page come from the laptop setup&rsquo;s browser
editor (code-server), and it&rsquo;s the same editor: every menu, shortcut and extension works the same way.</p>

<figure class="shot">
  <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">code-server · localhost:13337</span></div>
  <a href="/images/labs/basics/ide-tour.png" target="_blank" rel="noopener" title="Open full size">
    <img src="/images/labs/basics/ide-tour_hu_bd552eb864f2765c.webp" width="1600" height="956" alt="The lab open in code-server with the explorer, an editor tab, the containerlab panel and the Lab status terminal labelled 1 to 5" loading="lazy" decoding="async">
  </a><figcaption><strong>1</strong> Explorer: the repo&rsquo;s files. <strong>2</strong> The editor: click a file to open it here. <strong>3</strong> The containerlab icon: your switches and hosts. <strong>4</strong> The terminal, where you type commands. <strong>5</strong> The status bar.</figcaption>
</figure>

<ul>
<li><strong>Explorer</strong> (top icon on the left, <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>E</kbd>): the repo&rsquo;s files. Click one to open it.</li>
<li><strong>Search</strong> (<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>F</kbd>): search every file. Type <code>TODO 1.2</code> to find task 1.2&rsquo;s gaps.</li>
<li><strong>Quick open</strong> (<kbd>Ctrl</kbd>+<kbd>P</kbd>): type part of a file name, press <kbd>Enter</kbd>.</li>
<li><strong>Terminal</strong> (<kbd>Ctrl</kbd>+<kbd>`</kbd>, or <em>Terminal → New Terminal</em>): where you run commands.</li>
<li><strong>Containerlab</strong> (the flask-shaped icon on the left): the running switches and hosts.</li>
</ul>
<p>On a Mac, <kbd>Cmd</kbd> replaces <kbd>Ctrl</kbd>. In a browser, a few shortcuts belong to the browser itself
(<kbd>Ctrl</kbd>+<kbd>W</kbd> closes the tab, not the file), so when one surprises you, use the menu
(☰ top left) instead.</p>
<h2 id="status">3 · Read the lab&rsquo;s status</h2>
<p>The lab app&rsquo;s top bar sums it up: <strong>network up</strong>, or how many of the network&rsquo;s nodes are running so far. For
the detail, a terminal called <strong>Lab status</strong> in the VS Code tab runs <code>make status</code> for you. It&rsquo;s the lab&rsquo;s health check:
what&rsquo;s installed, what&rsquo;s running, and where to start. On the very first start it waits for the lab&rsquo;s services,
so give it a minute.</p>

<figure class="shot">
  <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">terminal · make status</span></div>
  <a href="/images/labs/basics/lab-status.png" target="_blank" rel="noopener" title="Open full size">
    <img src="/images/labs/basics/lab-status_hu_4a5b0f4362bf33f.webp" width="1600" height="691" alt="make status output listing tool versions, the lab&#39;s services up and its switches and hosts up" loading="lazy" decoding="async">
  </a>
</figure>

<p>Every line should have a green ✓. A grey <strong>·</strong> is something the lab starts later, when a chapter needs it. A red
✗ tells you the command that fixes it, usually <code>make up</code>. Run <code>make status</code> again any time.</p>
<h2 id="terminal">4 · Your first commands</h2>
<p>Open a terminal (<kbd>Ctrl</kbd>+<kbd>`</kbd>). The prompt shows the folder you&rsquo;re in. Type each command and
press <kbd>Enter</kbd>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python --version              <span class="c1"># Python, from the lab&#39;s own venv</span>
</span></span><span class="line"><span class="cl">containerlab version          <span class="c1"># the tool that runs the switches</span>
</span></span><span class="line"><span class="cl">docker ps                     <span class="c1"># every container running inside the lab</span>
</span></span><span class="line"><span class="cl">make <span class="nb">help</span>                     <span class="c1"># every shortcut this lab has</span>
</span></span></code></pre></div>
<figure class="shot">
  <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">terminal</span></div>
  <a href="/images/labs/basics/terminal-versions.png" target="_blank" rel="noopener" title="Open full size">
    <img src="/images/labs/basics/terminal-versions_hu_456515b3bcd8474a.webp" width="1600" height="659" alt="A terminal showing tool versions" loading="lazy" decoding="async">
  </a>
</figure>


<p>A few habits worth having from day one:</p>
<table>
  <thead>
      <tr>
          <th>Do this</th>
          <th>To</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><kbd>↑</kbd></td>
          <td>bring back the last command (keep pressing for older ones)</td>
      </tr>
      <tr>
          <td><kbd>Tab</kbd></td>
          <td>finish a file or command name for you: type <code>make he</code> then <kbd>Tab</kbd></td>
      </tr>
      <tr>
          <td><kbd>Ctrl</kbd>+<kbd>C</kbd></td>
          <td>stop whatever is running</td>
      </tr>
      <tr>
          <td><code>clear</code></td>
          <td>clear the screen</td>
      </tr>
      <tr>
          <td><code>pwd</code> / <code>ls</code> / <code>cd tools</code> / <code>cd ..</code></td>
          <td>where am I / what&rsquo;s here / go in / go back up</td>
      </tr>
      <tr>
          <td><code>cat README.md</code></td>
          <td>print a file</td>
      </tr>
  </tbody>
</table>
<h2 id="make">5 · Make is your remote control</h2>
<p>You won&rsquo;t type long commands in any lab. <code>make</code> runs them for you, and <code>make help</code> lists them all. These work
in every lab:</p>
<table>
  <thead>
      <tr>
          <th>Command</th>
          <th>What it does</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>make status</code></td>
          <td>what&rsquo;s installed and running</td>
      </tr>
      <tr>
          <td><code>make check T=1.2</code></td>
          <td>check task 1.2: your files, and the real network or service they talk to</td>
      </tr>
      <tr>
          <td><code>make check CH=2</code> / <code>make check</code></td>
          <td>a whole chapter / your progress across the whole lab</td>
      </tr>
      <tr>
          <td><code>make solve T=1.2</code></td>
          <td>stuck? copy in the finished files for task 1.2</td>
      </tr>
      <tr>
          <td><code>make up</code> / <code>make down</code></td>
          <td>start / stop everything the lab runs</td>
      </tr>
      <tr>
          <td><code>make ssh NODE=leaf1</code></td>
          <td>a command line on a switch (labs with switches)</td>
      </tr>
  </tbody>
</table>
<p>Most labs also have <code>make skip CH=4</code>: start at any chapter, with the finished files of the chapters before it.
The lab&rsquo;s page says which command it uses. A lab&rsquo;s own commands (<code>make run</code>, <code>make deploy</code>, <code>make graph</code> &hellip;) are
introduced in the task that needs them.</p>
<h2 id="edit">6 · Edit a file and save it</h2>
<p>Each task tells you which files you edit. The gaps are marked <code>TODO</code> with the task number:</p>
<ol>
<li>Press <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>F</kbd> and search for <code>TODO 1.2</code>.</li>
<li>Click a result. The file opens at that line.</li>
<li>Read the comment; it says what goes there.</li>
<li>Type your change, then save with <kbd>Ctrl</kbd>+<kbd>S</kbd>. An unsaved file has a <strong>●</strong> on its tab.</li>
</ol>

<figure class="shot">
  <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">code-server · search</span></div>
  <a href="/images/labs/basics/search-todo.png" target="_blank" rel="noopener" title="Open full size">
    <img src="/images/labs/basics/search-todo_hu_6e57de37f35f89fc.webp" width="1600" height="956" alt="The search panel listing TODO 1.2a and TODO 1.2b in playbooks/foundation.yml, with the file open at the first one" loading="lazy" decoding="async">
  </a>
</figure>

<p><strong>YAML is picky about spaces.</strong> Indent with <strong>2 spaces</strong>, never tabs (the editor does this for you in <code>.yml</code>
files). Things at the same level line up exactly. A red squiggle means an extension has spotted a problem; hover
over it to see what. Python is the same: indentation is part of the code.</p>

<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl">- <span class="nt">name: Racks                       # a task</span><span class="p">:</span><span class="w"> </span><span class="l">a name...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">netbox.netbox.netbox_rack</span><span class="p">:</span><span class="w">        </span><span class="c"># ...the module it runs (2 spaces in)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">data</span><span class="p">:</span><span class="w">                           </span><span class="c"># the module&#39;s options (4 spaces in)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;{{ item.name }}&#34;</span><span class="w">       </span><span class="c"># {{ item }} is the current loop item</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">loop</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;{{ foundation.racks }}&#34;</span><span class="w">    </span><span class="c"># run once per rack (lines up with the module)</span><span class="w">
</span></span></span></code></pre></div><h2 id="run">7 · Run it, then prove it</h2>
<p>Each task page says what to run under <strong>run it</strong>: a playbook, a script, a test suite. Read what it prints. An
Ansible run ends in a <strong>PLAY RECAP</strong> (<code>failed=0</code> is what you want; scroll up to the first red <code>fatal:</code> line if it
isn&rsquo;t). A Python tool or pytest run ends with what passed and what didn&rsquo;t.</p>
<p>Then let the checker decide: click <strong>Check task</strong> under the guide, or run:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">make check <span class="nv">T</span><span class="o">=</span>1.2
</span></span></code></pre></div>
<figure class="shot">
  <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">terminal · make check</span></div>
  <a href="/images/labs/basics/make-check.png" target="_blank" rel="noopener" title="Open full size">
    <img src="/images/labs/basics/make-check_hu_c5ece02dea676cdf.webp" width="1600" height="531" alt="make check T=1.2 output: twelve green ticks and verified" loading="lazy" decoding="async">
  </a>
</figure>

<p>Green ✓ is done. A red ✗ says exactly what it expected and what it found (often with <code>(got ...)</code> at the end).
Fix that one thing and check again. The checker also tries your work on cases it hasn&rsquo;t seen, so code that only
works on the example won&rsquo;t pass. When it&rsquo;s all green, tick <strong>mark verified</strong> on the task page to track your
progress (the lab app keeps count too, top right).</p>
<h2 id="switches">8 · Meet the switches</h2>
<p>Most labs come with switches, run by containerlab inside the lab: <strong>Nokia SR Linux</strong> or <strong>CapeOS</strong>, a lab network
OS with the classic <code>show running-config</code> command line. Each lab&rsquo;s first task says which, and how they&rsquo;re wired.</p>

<figure class="shot">
  <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">containerlab · topology</span></div>
  <a href="/images/labs/basics/topoviewer.png" target="_blank" rel="noopener" title="Open full size">
    <img src="/images/labs/basics/topoviewer_hu_f8d45851a7ec9385.webp" width="1600" height="956" alt="The containerlab topology viewer showing two switches linked to each other, with two hosts attached" loading="lazy" decoding="async">
  </a><figcaption>In the containerlab panel (the hexagon icon on the left), click the lab and its topology opens. Right-click it for more: redeploy, SSH to every node, inspect.</figcaption>
</figure>

<p>Log in to one from the terminal (the names are on the lab&rsquo;s first task):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">make ssh <span class="nv">NODE</span><span class="o">=</span>leaf1
</span></span></code></pre></div><p>Then try <code>show version</code>, and <code>quit</code> or <code>exit</code> to come back. You can also right-click a node in the containerlab
panel and choose <strong>Connect (SSH)</strong>. Broke one? <code>make up</code> rebuilds the switches from the lab&rsquo;s files.</p>

<figure class="shot">
  <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">terminal · switch CLI</span></div>
  <a href="/images/labs/basics/srl-cli.png" target="_blank" rel="noopener" title="Open full size">
    <img src="/images/labs/basics/srl-cli_hu_88612ebd27a28108.webp" width="1600" height="1053" alt="A switch command line showing show version and an LLDP neighbor" loading="lazy" decoding="async">
  </a>
</figure>

<h2 id="git">9 · Git, just enough</h2>
<p>The repo is a Git repository, so you can always see what you changed and undo it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git status                       <span class="c1"># which files you changed</span>
</span></span><span class="line"><span class="cl">git diff                         <span class="c1"># exactly what changed, line by line</span>
</span></span><span class="line"><span class="cl">git restore &lt;file&gt;               <span class="c1"># throw away your changes to one file</span>
</span></span></code></pre></div>
<figure class="shot">
  <div class="shot-bar" aria-hidden="true"><i></i><i></i><i></i><span class="mono">code-server · source control</span></div>
  <a href="/images/labs/basics/source-control.png" target="_blank" rel="noopener" title="Open full size">
    <img src="/images/labs/basics/source-control_hu_5fb8fd87f89e0e28.webp" width="1600" height="956" alt="The Source Control panel listing changed files, with a side-by-side diff of a changed file" loading="lazy" decoding="async">
  </a><figcaption>The <strong>Source Control</strong> panel (<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>G</kbd>) shows the same thing: click a file for a side-by-side diff.</figcaption>
</figure>

<p>Stuck on a task? <code>make solve T=1.2</code> copies in the finished files and <code>git diff</code> shows you what the answer
changed. Read it, understand it, keep going. No shame; that&rsquo;s what it&rsquo;s for.</p>
<h2 id="trouble">10 · When something goes wrong</h2>
<table>
  <thead>
      <tr>
          <th>You see</th>
          <th>Try</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>The starting page sits on one step for more than 10 minutes</td>
          <td>Reload it. Still stuck? Open <a href="https://github.com/codespaces">github.com/codespaces</a>: if the codespace shows an error, delete it there and click <strong>Open the lab</strong> again for a fresh one</td>
      </tr>
      <tr>
          <td>The lab says <strong>This lab isn&rsquo;t running</strong></td>
          <td>It stopped after 20 idle minutes. Click <strong>Open it again</strong>: your files are still there</td>
      </tr>
      <tr>
          <td>The guide or VS Code tab is blank</td>
          <td>Click the <strong>reload</strong> arrow, top right in the lab app. VS Code takes a few seconds to load the first time</td>
      </tr>
      <tr>
          <td><code>make status</code> shows a red ✗</td>
          <td>run the command it suggests (usually <code>make up</code>) and wait a minute</td>
      </tr>
      <tr>
          <td><code>make ssh</code> says no such container</td>
          <td>the switches aren&rsquo;t started: <code>make up</code> (or the command the lab&rsquo;s first task gives)</td>
      </tr>
      <tr>
          <td>A login page says <strong>CSRF verification failed</strong></td>
          <td>open the service from its own tab in the lab app (or <code>localhost</code> on a laptop), not another address</td>
      </tr>
      <tr>
          <td>VS Code shows <strong>Restricted Mode</strong> and the terminal won&rsquo;t start</td>
          <td>Click <em>Restricted Mode</em> in the bottom-left corner and trust the folder</td>
      </tr>
      <tr>
          <td>Codespaces says you&rsquo;ve used your allowance</td>
          <td>Wait for next month, add a budget in GitHub&rsquo;s billing settings, or use the <a href="#laptop">advanced setup</a></td>
      </tr>
      <tr>
          <td><code>command not found</code> for a lab tool</td>
          <td>You&rsquo;re not in the lab. Run it in a terminal in the VS Code tab (on a laptop, the bottom-left corner says <em>Dev Container</em> when you&rsquo;re in).</td>
      </tr>
      <tr>
          <td>YAML error with a line number</td>
          <td>Look at that line and the one above it: usually indentation, or a missing <code>:</code></td>
      </tr>
      <tr>
          <td><code>NotImplementedError: TODO 2.1a is still open</code></td>
          <td>that&rsquo;s the gap you&rsquo;re meant to fill: search for <code>TODO 2.1a</code></td>
      </tr>
      <tr>
          <td>Everything is slow</td>
          <td><code>make down</code> stops what you&rsquo;re not using. On a laptop, give Docker more memory.</td>
      </tr>
  </tbody>
</table>
<p>Still stuck? Each lab&rsquo;s first task has its own list for that lab. Otherwise open an issue on the lab repo with the
command you ran and what it printed.</p>
<h2 id="laptop">Advanced: run it on your laptop</h2>
<p>Same lab, same dev container, on your own machine instead of GitHub&rsquo;s. No allowance to run out, and it works
offline once it&rsquo;s built. You need a bit more setup and a laptop with memory to spare.</p>
<h3 id="install">Install three things</h3>
<ol>
<li><strong>Docker.</strong> Docker Desktop (Mac, Windows), OrbStack (Mac) or Docker Engine (Linux). Give it at least
as much memory as the lab&rsquo;s page asks for (6 to 16 GB).</li>
<li><strong>Git.</strong> Macs ask to install it the first time you type <code>git</code>. Windows: Git for Windows.</li>
<li><strong>One way to open the lab</strong>: VS Code with the <em>Dev Containers</em> extension, <strong>or</strong> Node.js (for the
<code>devcontainer</code> command, if you&rsquo;d rather use the editor in your browser).</li>
</ol>
<p>Check them from a terminal on your laptop (Terminal on a Mac, PowerShell on Windows):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker version
</span></span><span class="line"><span class="cl">git --version
</span></span></code></pre></div><p>Both should print a version. If <code>docker version</code> says it can&rsquo;t connect, Docker Desktop isn&rsquo;t running yet.</p>
<h3 id="open-laptop">Open the lab</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git clone https://gitlab.com/networkdoodles-labs/&lt;lab&gt;.git     <span class="c1"># the lab page has the exact address</span>
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> &lt;lab&gt;
</span></span></code></pre></div><p>Then pick <strong>one</strong>:</p>
<ul>
<li><strong>VS Code:</strong> <code>code .</code> (or <em>File → Open Folder</em>), then click <strong>Reopen in Container</strong> on the prompt in the
bottom right. No prompt? Press <kbd>F1</kbd>, type <code>reopen in container</code>, press <kbd>Enter</kbd>. The
bottom-left corner says <strong>Dev Container</strong> when you&rsquo;re in.</li>
<li><strong>Browser:</strong> <code>npx @devcontainers/cli up --workspace-folder .</code>, wait for it to finish, then open
<a href="http://localhost:8000">http://localhost:8000</a>. That&rsquo;s the lab app; its VS Code tab is code-server, the
editor in the screenshots above.</li>
</ul>
<p>The first build takes <strong>about 5 minutes</strong>; later starts take about a minute. From there, everything on this
page is the same, except the lab&rsquo;s web pages (NetBox, Grafana &hellip;) are on <code>localhost</code> at the ports its first task
lists.</p>
<p><strong>No Docker allowed on your work laptop?</strong> VS Code&rsquo;s <em>Remote - SSH</em> extension can open the dev container on
any Linux machine you can SSH to that has Docker: a homelab box or a small cloud VM.</p>
<h2 id="ready">Ready</h2>
<p>That&rsquo;s everything. Pick a lab on the <a href="/labs/">labs page</a> and start with its first task: it shows you what&rsquo;s in that
lab, and you&rsquo;ve already done the rest.</p>
]]></content:encoded></item></channel></rss>