Skip to content

Instantly share code, notes, and snippets.

@lassebenni
Created March 10, 2026 22:31
Show Gist options
  • Select an option

  • Save lassebenni/21739186b9a344067d79a7bf5cdc865c to your computer and use it in GitHub Desktop.

Select an option

Save lassebenni/21739186b9a344067d79a7bf5cdc865c to your computer and use it in GitHub Desktop.
Visual for: Docker layer caching
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Docker Layer Caching</title>
<style>
body {
margin: 0;
padding: 20px;
background: #1a1a2e;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
svg {
max-width: 800px;
width: 100%;
height: auto;
}
</style>
</head>
<body>
<svg viewBox="0 0 750 420" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5"
markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#8892b0"/>
</marker>
<marker id="arrow-red" viewBox="0 0 10 10" refX="9" refY="5"
markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#ff6b6b"/>
</marker>
</defs>
<!-- Title -->
<text x="375" y="30" text-anchor="middle" fill="#ccd6f6" font-size="18" font-weight="bold">Docker Layer Caching: What Rebuilds When Source Changes?</text>
<!-- Column headers -->
<text x="170" y="65" text-anchor="middle" fill="#8892b0" font-size="13" font-weight="bold">DOCKERFILE LAYERS</text>
<text x="540" y="65" text-anchor="middle" fill="#8892b0" font-size="13" font-weight="bold">ON SOURCE CODE CHANGE</text>
<!-- Layer 1: FROM -->
<rect x="50" y="80" width="240" height="44" rx="6" fill="#1e3a5f" stroke="#64ffda" stroke-width="1.5"/>
<text x="170" y="100" text-anchor="middle" fill="#64ffda" font-size="11" font-weight="bold">FROM</text>
<text x="170" y="115" text-anchor="middle" fill="#a8b2d1" font-size="11">python:3.12-slim</text>
<!-- Layer 2: COPY requirements -->
<rect x="50" y="134" width="240" height="44" rx="6" fill="#1e3a5f" stroke="#64ffda" stroke-width="1.5"/>
<text x="170" y="154" text-anchor="middle" fill="#64ffda" font-size="11" font-weight="bold">COPY</text>
<text x="170" y="169" text-anchor="middle" fill="#a8b2d1" font-size="11">requirements.txt .</text>
<!-- Layer 3: RUN install -->
<rect x="50" y="188" width="240" height="44" rx="6" fill="#1e3a5f" stroke="#64ffda" stroke-width="1.5"/>
<text x="170" y="208" text-anchor="middle" fill="#64ffda" font-size="11" font-weight="bold">RUN</text>
<text x="170" y="223" text-anchor="middle" fill="#a8b2d1" font-size="11">pip install -r requirements.txt</text>
<!-- Layer 4: COPY src -->
<rect x="50" y="242" width="240" height="44" rx="6" fill="#1e3a5f" stroke="#ff6b6b" stroke-width="2"/>
<text x="170" y="262" text-anchor="middle" fill="#ff6b6b" font-size="11" font-weight="bold">COPY</text>
<text x="170" y="277" text-anchor="middle" fill="#a8b2d1" font-size="11">. .</text>
<!-- Layer 5: CMD -->
<rect x="50" y="296" width="240" height="44" rx="6" fill="#1e3a5f" stroke="#ff6b6b" stroke-width="2"/>
<text x="170" y="316" text-anchor="middle" fill="#ff6b6b" font-size="11" font-weight="bold">CMD</text>
<text x="170" y="331" text-anchor="middle" fill="#a8b2d1" font-size="11">["python", "main.py"]</text>
<!-- Arrows from layers to status -->
<line x1="290" y1="102" x2="410" y2="102" stroke="#8892b0" stroke-width="1.5" marker-end="url(#arrow)"/>
<line x1="290" y1="156" x2="410" y2="156" stroke="#8892b0" stroke-width="1.5" marker-end="url(#arrow)"/>
<line x1="290" y1="210" x2="410" y2="210" stroke="#8892b0" stroke-width="1.5" marker-end="url(#arrow)"/>
<line x1="290" y1="264" x2="410" y2="264" stroke="#ff6b6b" stroke-width="1.5" marker-end="url(#arrow-red)"/>
<line x1="290" y1="318" x2="410" y2="318" stroke="#ff6b6b" stroke-width="1.5" marker-end="url(#arrow-red)"/>
<!-- Status boxes -->
<!-- Cached -->
<rect x="415" y="80" width="240" height="44" rx="6" fill="#0d3320" stroke="#64ffda" stroke-width="1.5"/>
<text x="535" y="106" text-anchor="middle" fill="#64ffda" font-size="13" font-weight="bold">✓ CACHED</text>
<rect x="415" y="134" width="240" height="44" rx="6" fill="#0d3320" stroke="#64ffda" stroke-width="1.5"/>
<text x="535" y="160" text-anchor="middle" fill="#64ffda" font-size="13" font-weight="bold">✓ CACHED</text>
<rect x="415" y="188" width="240" height="44" rx="6" fill="#0d3320" stroke="#64ffda" stroke-width="1.5"/>
<text x="535" y="214" text-anchor="middle" fill="#64ffda" font-size="13" font-weight="bold">✓ CACHED</text>
<!-- Rebuilt -->
<rect x="415" y="242" width="240" height="44" rx="6" fill="#3d1111" stroke="#ff6b6b" stroke-width="1.5"/>
<text x="535" y="268" text-anchor="middle" fill="#ff6b6b" font-size="13" font-weight="bold">⟳ REBUILDS</text>
<rect x="415" y="296" width="240" height="44" rx="6" fill="#3d1111" stroke="#ff6b6b" stroke-width="1.5"/>
<text x="535" y="322" text-anchor="middle" fill="#ff6b6b" font-size="13" font-weight="bold">⟳ REBUILDS</text>
<!-- Legend / explanation -->
<rect x="50" y="365" width="650" height="44" rx="6" fill="#16213e" stroke="#233554" stroke-width="1"/>
<text x="375" y="383" text-anchor="middle" fill="#a8b2d1" font-size="12">
<tspan font-weight="bold" fill="#64ffda">Key insight:</tspan> Copy dependency files first, install them, then copy source code.
</text>
<text x="375" y="400" text-anchor="middle" fill="#8892b0" font-size="11">A source code change only rebuilds the COPY . . layer and below — dependencies stay cached.</text>
</svg>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment