build: add svg diagrams to cache docs

Also adds the graphviz generation code.

Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
Justin Chadwell 2022-09-12 10:35:46 +01:00
parent 55ebeda0cc
commit c42962dc87
8 changed files with 286 additions and 10 deletions

View File

@ -180,6 +180,11 @@ body.night {
img.white-bg {
background-color: white;
}
/* apply to images that support being inverted */
img.invertible {
filter: invert(100%) hue-rotate(180deg);
}
/* accordion */
.panel {

View File

@ -23,7 +23,7 @@ might be used to create a C/C++ program:
```dockerfile
FROM ubuntu:latest
RUN apt-get update && apt-get upgrade -y build-essentials
RUN apt-get update && apt-get install -y build-essentials
COPY . /src/
WORKDIR /src/
RUN make build
@ -33,27 +33,22 @@ Each instruction in this Dockerfile (roughly) translates into a layer in your
final image. You can think of layers in a stack, with each layer adding more
content to the filesystem on top of the layer before it:
```
stack diagram
```
![Image layer diagram showing the above commands chained together one after the other](../images/cache-stack.svg){:.invertible}
Now, if one of the layers changes, somewhere - for example, suppose you make a
change to your C/C++ program in `main.c`. After this change, the `COPY` command
will have to run again, so that the layer changes, so the cache for that layer
has been invalidated.
```
stack diagram with COPY layer cache invalidated
```
![Image layer diagram, but now with the link between COPY and WORKDIR marked as invalid](../images/cache-stack-invalidate-copy.svg){:.invertible}
But since we have a change to that file, we now need to run our `make build`
step again, so that those changes are built into our program. So since our
cache for `COPY` was invalidated, we also have to invalidate the cache for all
the layers after it, including our `RUN make build`, so that it will run again:
```
stack diagram with COPY + other layer cache invalidated
```
![Image layer diagram, but now with all links after COPY marked as invalid](../images/cache-stack-invalidate-rest.svg){:.invertible}
That's pretty much all there is to understand the cache - once there's a change
in a layer, then all the layers after it will need to be rebuilt as well (even

View File

@ -0,0 +1,19 @@
// dot -Tsvg ./cache-invalidate-copy.dot > ./cache-invalidate-copy.svg
digraph {
rankdir="LR";
nodesep=0.3;
edge[minlen=0];
bgcolor="#00000000";
node [ shape=rect, width=5, height=0.4, fontname=monospace, fontsize=10 ];
from [ label = <<B>FROM </B>ubuntu:latest> ];
deps [ label = <<B>RUN </B>apt-get update &amp;&amp; \\<br/>apt-get install -y build-essentials> ];
copy [ label = <<B>COPY </B>. /src/>, color = "red" ];
workdir [ label = <<B>WORKDIR </B>/src/> ];
build [ label = <<B>RUN </B>make build> ];
from -> deps;
deps -> copy;
copy -> workdir [ color = "red", label = " ❌ " ];
workdir -> build;
}

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 5.0.0 (0)
-->
<!-- Pages: 1 -->
<svg width="368pt" height="256pt"
viewBox="0.00 0.00 368.00 256.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 252)">
<polygon fill="transparent" stroke="transparent" points="-4,4 -4,-252 364,-252 364,4 -4,4"/>
<!-- from -->
<g id="node1" class="node">
<title>from</title>
<polygon fill="none" stroke="black" points="360,-248 0,-248 0,-219 360,-219 360,-248"/>
<text text-anchor="start" x="125" y="-232" font-family="monospace" font-weight="bold" font-size="10.00">FROM </text>
<text text-anchor="start" x="156" y="-232" font-family="monospace" font-size="10.00">ubuntu:latest</text>
</g>
<!-- deps -->
<g id="node2" class="node">
<title>deps</title>
<polygon fill="none" stroke="black" points="360,-197 0,-197 0,-168 360,-168 360,-197"/>
<text text-anchor="start" x="110" y="-185.5" font-family="monospace" font-weight="bold" font-size="10.00">RUN </text>
<text text-anchor="start" x="135" y="-185.5" font-family="monospace" font-size="10.00">apt&#45;get update &amp;&amp; \</text>
<text text-anchor="start" x="74.5" y="-175.5" font-family="monospace" font-size="10.00">apt&#45;get install &#45;y build&#45;essentials</text>
</g>
<!-- from&#45;&gt;deps -->
<g id="edge1" class="edge">
<title>from&#45;&gt;deps</title>
<path fill="none" stroke="black" d="M180,-218.77C180,-214.96 180,-211.15 180,-207.33"/>
<polygon fill="black" stroke="black" points="183.5,-207.24 180,-197.24 176.5,-207.24 183.5,-207.24"/>
</g>
<!-- copy -->
<g id="node3" class="node">
<title>copy</title>
<polygon fill="none" stroke="red" points="360,-146 0,-146 0,-117 360,-117 360,-146"/>
<text text-anchor="start" x="143" y="-130" font-family="monospace" font-weight="bold" font-size="10.00">COPY </text>
<text text-anchor="start" x="174" y="-130" font-family="monospace" font-size="10.00">. /src/</text>
</g>
<!-- deps&#45;&gt;copy -->
<g id="edge2" class="edge">
<title>deps&#45;&gt;copy</title>
<path fill="none" stroke="black" d="M180,-167.77C180,-163.96 180,-160.15 180,-156.33"/>
<polygon fill="black" stroke="black" points="183.5,-156.24 180,-146.24 176.5,-156.24 183.5,-156.24"/>
</g>
<!-- workdir -->
<g id="node4" class="node">
<title>workdir</title>
<polygon fill="none" stroke="black" points="360,-80 0,-80 0,-51 360,-51 360,-80"/>
<text text-anchor="start" x="140" y="-64" font-family="monospace" font-weight="bold" font-size="10.00">WORKDIR </text>
<text text-anchor="start" x="189" y="-64" font-family="monospace" font-size="10.00">/src/</text>
</g>
<!-- copy&#45;&gt;workdir -->
<g id="edge3" class="edge">
<title>copy&#45;&gt;workdir</title>
<path fill="none" stroke="red" d="M180,-116.89C180,-109.12 180,-99.36 180,-90.43"/>
<polygon fill="red" stroke="red" points="183.5,-90.15 180,-80.15 176.5,-90.15 183.5,-90.15"/>
<text text-anchor="middle" x="169.5" y="-94.8" font-family="Times,serif" font-size="14.00">&#160;</text>
</g>
<!-- build -->
<g id="node5" class="node">
<title>build</title>
<polygon fill="none" stroke="black" points="360,-29 0,-29 0,0 360,0 360,-29"/>
<text text-anchor="start" x="137" y="-13" font-family="monospace" font-weight="bold" font-size="10.00">RUN </text>
<text text-anchor="start" x="162" y="-13" font-family="monospace" font-size="10.00">make build</text>
</g>
<!-- workdir&#45;&gt;build -->
<g id="edge4" class="edge">
<title>workdir&#45;&gt;build</title>
<path fill="none" stroke="black" d="M180,-50.77C180,-46.96 180,-43.15 180,-39.33"/>
<polygon fill="black" stroke="black" points="183.5,-39.24 180,-29.24 176.5,-39.24 183.5,-39.24"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -0,0 +1,19 @@
// dot -Tsvg ./cache-invalidate-rest.dot > ./cache-invalidate-rest.svg
digraph {
rankdir="LR";
nodesep=0.3;
edge[minlen=0];
bgcolor="#00000000";
node [ shape=rect, width=5, height=0.4, fontname=monospace, fontsize=10 ];
from [ label = <<B>FROM </B>ubuntu:latest> ];
deps [ label = <<B>RUN </B>apt-get update &amp;&amp; \\<br/>apt-get install -y build-essentials> ];
copy [ label = <<B>COPY </B>. /src/>, color = "red" ];
workdir [ label = <<B>WORKDIR </B>/src/>, color = "red" ];
build [ label = <<B>RUN </B>make build>, color = "red" ];
from -> deps;
deps -> copy;
copy -> workdir [ color = "red", label = " ❌ " ];
workdir -> build [ color = "red", label = " ❌ " ];
}

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 5.0.0 (0)
-->
<!-- Pages: 1 -->
<svg width="368pt" height="271pt"
viewBox="0.00 0.00 368.00 271.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 267)">
<polygon fill="transparent" stroke="transparent" points="-4,4 -4,-267 364,-267 364,4 -4,4"/>
<!-- from -->
<g id="node1" class="node">
<title>from</title>
<polygon fill="none" stroke="black" points="360,-263 0,-263 0,-234 360,-234 360,-263"/>
<text text-anchor="start" x="125" y="-247" font-family="monospace" font-weight="bold" font-size="10.00">FROM </text>
<text text-anchor="start" x="156" y="-247" font-family="monospace" font-size="10.00">ubuntu:latest</text>
</g>
<!-- deps -->
<g id="node2" class="node">
<title>deps</title>
<polygon fill="none" stroke="black" points="360,-212 0,-212 0,-183 360,-183 360,-212"/>
<text text-anchor="start" x="110" y="-200.5" font-family="monospace" font-weight="bold" font-size="10.00">RUN </text>
<text text-anchor="start" x="135" y="-200.5" font-family="monospace" font-size="10.00">apt&#45;get update &amp;&amp; \</text>
<text text-anchor="start" x="74.5" y="-190.5" font-family="monospace" font-size="10.00">apt&#45;get install &#45;y build&#45;essentials</text>
</g>
<!-- from&#45;&gt;deps -->
<g id="edge1" class="edge">
<title>from&#45;&gt;deps</title>
<path fill="none" stroke="black" d="M180,-233.77C180,-229.96 180,-226.15 180,-222.33"/>
<polygon fill="black" stroke="black" points="183.5,-222.24 180,-212.24 176.5,-222.24 183.5,-222.24"/>
</g>
<!-- copy -->
<g id="node3" class="node">
<title>copy</title>
<polygon fill="none" stroke="red" points="360,-161 0,-161 0,-132 360,-132 360,-161"/>
<text text-anchor="start" x="143" y="-145" font-family="monospace" font-weight="bold" font-size="10.00">COPY </text>
<text text-anchor="start" x="174" y="-145" font-family="monospace" font-size="10.00">. /src/</text>
</g>
<!-- deps&#45;&gt;copy -->
<g id="edge2" class="edge">
<title>deps&#45;&gt;copy</title>
<path fill="none" stroke="black" d="M180,-182.77C180,-178.96 180,-175.15 180,-171.33"/>
<polygon fill="black" stroke="black" points="183.5,-171.24 180,-161.24 176.5,-171.24 183.5,-171.24"/>
</g>
<!-- workdir -->
<g id="node4" class="node">
<title>workdir</title>
<polygon fill="none" stroke="red" points="360,-95 0,-95 0,-66 360,-66 360,-95"/>
<text text-anchor="start" x="140" y="-79" font-family="monospace" font-weight="bold" font-size="10.00">WORKDIR </text>
<text text-anchor="start" x="189" y="-79" font-family="monospace" font-size="10.00">/src/</text>
</g>
<!-- copy&#45;&gt;workdir -->
<g id="edge3" class="edge">
<title>copy&#45;&gt;workdir</title>
<path fill="none" stroke="red" d="M180,-131.89C180,-124.12 180,-114.36 180,-105.43"/>
<polygon fill="red" stroke="red" points="183.5,-105.15 180,-95.15 176.5,-105.15 183.5,-105.15"/>
<text text-anchor="middle" x="169.5" y="-109.8" font-family="Times,serif" font-size="14.00">&#160;</text>
</g>
<!-- build -->
<g id="node5" class="node">
<title>build</title>
<polygon fill="none" stroke="red" points="360,-29 0,-29 0,0 360,0 360,-29"/>
<text text-anchor="start" x="137" y="-13" font-family="monospace" font-weight="bold" font-size="10.00">RUN </text>
<text text-anchor="start" x="162" y="-13" font-family="monospace" font-size="10.00">make build</text>
</g>
<!-- workdir&#45;&gt;build -->
<g id="edge4" class="edge">
<title>workdir&#45;&gt;build</title>
<path fill="none" stroke="red" d="M180,-65.89C180,-58.12 180,-48.36 180,-39.43"/>
<polygon fill="red" stroke="red" points="183.5,-39.15 180,-29.15 176.5,-39.15 183.5,-39.15"/>
<text text-anchor="middle" x="169.5" y="-43.8" font-family="Times,serif" font-size="14.00">&#160;</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,19 @@
// dot -Tsvg ./cache-stack.dot > ./cache-stack.svg
digraph {
rankdir="LR";
nodesep=0.3;
edge[minlen=0];
bgcolor="#00000000";
node [ shape=rect, width=5, height=0.4, fontname=monospace, fontsize=10 ];
from [ label = <<B>FROM </B>ubuntu:latest> ];
deps [ label = <<B>RUN </B>apt-get update &amp;&amp; \\<br/>apt-get install -y build-essentials> ];
copy [ label = <<B>COPY </B>. /src/> ];
workdir [ label = <<B>WORKDIR </B>/src/> ];
build [ label = <<B>RUN </B>make build> ];
from -> deps;
deps -> copy;
copy -> workdir;
workdir -> build;
}

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 5.0.0 (0)
-->
<!-- Pages: 1 -->
<svg width="368pt" height="241pt"
viewBox="0.00 0.00 368.00 241.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 237)">
<polygon fill="transparent" stroke="transparent" points="-4,4 -4,-237 364,-237 364,4 -4,4"/>
<!-- from -->
<g id="node1" class="node">
<title>from</title>
<polygon fill="none" stroke="black" points="360,-233 0,-233 0,-204 360,-204 360,-233"/>
<text text-anchor="start" x="125" y="-217" font-family="monospace" font-weight="bold" font-size="10.00">FROM </text>
<text text-anchor="start" x="156" y="-217" font-family="monospace" font-size="10.00">ubuntu:latest</text>
</g>
<!-- deps -->
<g id="node2" class="node">
<title>deps</title>
<polygon fill="none" stroke="black" points="360,-182 0,-182 0,-153 360,-153 360,-182"/>
<text text-anchor="start" x="110" y="-170.5" font-family="monospace" font-weight="bold" font-size="10.00">RUN </text>
<text text-anchor="start" x="135" y="-170.5" font-family="monospace" font-size="10.00">apt&#45;get update &amp;&amp; \</text>
<text text-anchor="start" x="74.5" y="-160.5" font-family="monospace" font-size="10.00">apt&#45;get install &#45;y build&#45;essentials</text>
</g>
<!-- from&#45;&gt;deps -->
<g id="edge1" class="edge">
<title>from&#45;&gt;deps</title>
<path fill="none" stroke="black" d="M180,-203.77C180,-199.96 180,-196.15 180,-192.33"/>
<polygon fill="black" stroke="black" points="183.5,-192.24 180,-182.24 176.5,-192.24 183.5,-192.24"/>
</g>
<!-- copy -->
<g id="node3" class="node">
<title>copy</title>
<polygon fill="none" stroke="black" points="360,-131 0,-131 0,-102 360,-102 360,-131"/>
<text text-anchor="start" x="143" y="-115" font-family="monospace" font-weight="bold" font-size="10.00">COPY </text>
<text text-anchor="start" x="174" y="-115" font-family="monospace" font-size="10.00">. /src/</text>
</g>
<!-- deps&#45;&gt;copy -->
<g id="edge2" class="edge">
<title>deps&#45;&gt;copy</title>
<path fill="none" stroke="black" d="M180,-152.77C180,-148.96 180,-145.15 180,-141.33"/>
<polygon fill="black" stroke="black" points="183.5,-141.24 180,-131.24 176.5,-141.24 183.5,-141.24"/>
</g>
<!-- workdir -->
<g id="node4" class="node">
<title>workdir</title>
<polygon fill="none" stroke="black" points="360,-80 0,-80 0,-51 360,-51 360,-80"/>
<text text-anchor="start" x="140" y="-64" font-family="monospace" font-weight="bold" font-size="10.00">WORKDIR </text>
<text text-anchor="start" x="189" y="-64" font-family="monospace" font-size="10.00">/src/</text>
</g>
<!-- copy&#45;&gt;workdir -->
<g id="edge3" class="edge">
<title>copy&#45;&gt;workdir</title>
<path fill="none" stroke="black" d="M180,-101.77C180,-97.96 180,-94.15 180,-90.33"/>
<polygon fill="black" stroke="black" points="183.5,-90.24 180,-80.24 176.5,-90.24 183.5,-90.24"/>
</g>
<!-- build -->
<g id="node5" class="node">
<title>build</title>
<polygon fill="none" stroke="black" points="360,-29 0,-29 0,0 360,0 360,-29"/>
<text text-anchor="start" x="137" y="-13" font-family="monospace" font-weight="bold" font-size="10.00">RUN </text>
<text text-anchor="start" x="162" y="-13" font-family="monospace" font-size="10.00">make build</text>
</g>
<!-- workdir&#45;&gt;build -->
<g id="edge4" class="edge">
<title>workdir&#45;&gt;build</title>
<path fill="none" stroke="black" d="M180,-50.77C180,-46.96 180,-43.15 180,-39.33"/>
<polygon fill="black" stroke="black" points="183.5,-39.24 180,-29.24 176.5,-39.24 183.5,-39.24"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB