<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Docker · Loosely Decoupled</title>
    <link>https://looselydecoupled.com/topics/docker/</link>
    <description>Answers to PowerShell, Windows Server and OpenSSH questions the docs skip, with the reasoning behind them. Answer first, discussion after.</description>
    <language>en-us</language>
    
    <copyright>© 2026 Emmanuel Tsouris</copyright>
    <lastBuildDate>Tue, 20 Oct 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://looselydecoupled.com/topics/docker/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Why Docker.raw Is Huge on a Mac, and How to Get Its Space Back</title>
      <link>https://looselydecoupled.com/docker-desktop-disk-space-mac/</link>
      <guid isPermaLink="true">https://looselydecoupled.com/docker-desktop-disk-space-mac/</guid>
      <pubDate>Tue, 20 Oct 2026 00:00:00 +0000</pubDate>
      <dc:creator>Emmanuel Tsouris</dc:creator>
      <category>macOS</category>
      <category>Docker</category>
      
      <description>Get the space in Docker.raw back on a Mac by pruning images no container uses, keeping the volumes that hold app data and the images stopped containers need.</description>
      <content:encoded><![CDATA[<div class="answer" data-answer="true">
  <p class="answer__label" data-pagefind-ignore>TL;DR</p>
  <p><code>Docker.raw</code> is a sparse file. <code>ls</code> reports its maximum size, the disk limit shown in Docker Desktop&rsquo;s Settings &gt; Resources &gt; Advanced (1.0T in the test), and <code>du</code> reports what it occupies: 15G, then 8.6G after pruning in the test. To get space back, run <code>docker image prune -a</code>, which removes every image that no container uses; plain <code>docker image prune</code> removes only dangling (untagged) images. Keep the volumes, because a volume holds an app&rsquo;s data. The space returns to the Mac minutes later, not at once, so wait several minutes and check <code>df</code> and <code>du</code> again before you decide the prune did nothing. Quitting, reopening or updating Docker Desktop freed nothing more in my runs.</p>
<div class="console"><div class="code-block code-block--wrap console__command" data-copyable data-copy-label="command">
    <div class="code-block__head"><span class="code-block__lang">Command</span></div>
    <div class="code-block__scroll"><pre data-copy-source><code><span class="line"><span class="prompt">$ </span><span class="console__token">ls</span> <span class="console__token">-lh</span> <span class="console__token">~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw</span>
</span><span class="line"><span class="prompt">$ </span><span class="console__token">du</span> <span class="console__token">-h</span> <span class="console__token">~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw</span>
</span><span class="line"><span class="prompt">$ </span><span class="console__token">docker</span> <span class="console__token">system</span> <span class="console__token">df</span>
</span><span class="line"><span class="prompt">$ </span><span class="console__token">docker</span> <span class="console__token">image</span> <span class="console__token">prune</span> <span class="console__token">-a</span></span></code></pre>
    </div>
  </div></div>
</div>

<p>I went looking for what was filling my Mac, and Docker&rsquo;s folder sat near the top of the list. <code>ls</code> read <code>Docker.raw</code> as 1.0T, which can&rsquo;t be what it occupies. I measured it, pruned, and watched how much of the space came back and when. This page is part of a series on <a href="https://looselydecoupled.com/series/developer-mac-disk-cleanup/">cleaning up a developer Mac&rsquo;s disk</a>. If you haven&rsquo;t yet found out that Docker is what fills your disk, <a href="https://looselydecoupled.com/mac-disk-full-developer-caches/">finding what is taking up the space</a> comes first; you don&rsquo;t need it to follow the steps here.</p>
<div class="tested" id="tested">
  <p class="label label--seam">Tested with</p><dl class="tested__rows">
    <div class="tested__row"><dt>Docker Desktop</dt> <dd>4.95.0, then 4.96.0</dd></div>
    <div class="tested__row"><dt>Docker engine</dt> <dd>29.8.2, then 29.9.1</dd></div>
    <div class="tested__row"><dt>macOS</dt> <dd>27.0.1, Apple silicon, APFS</dd></div>
    <div class="tested__row"><dt>Date</dt> <dd>October 2026</dd></div>
  </dl>
</div>
<p>The first prune run below was on an earlier engine, 29.6.2, before Docker Desktop was updated.</p>
<h2 id="read-the-real-size-of-dockerraw">Read the real size of <code>Docker.raw</code><a class="heading-anchor" href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#read-the-real-size-of-dockerraw"
     aria-label="Link to section: Read the real size of Docker.raw" data-pagefind-ignore></a>
</h2>
<p>Docker Desktop keeps its Linux containers and images in one disk image file, <code>Docker.raw</code> (<a href="https://docs.docker.com/desktop/troubleshoot-and-support/faqs/macfaqs/" rel="external noopener" target="_blank">Docker&rsquo;s Mac FAQ<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#i-external-link"/></svg><span class="visually-hidden"> (opens in a new tab)</span></a>). Compare what <code>ls</code> and <code>du</code> say about it:</p>
<div class="console"><div class="code-block code-block--wrap console__command" data-copyable data-copy-label="command">
    <div class="code-block__head"><span class="code-block__lang">Command</span></div>
    <div class="code-block__scroll"><pre data-copy-source><code><span class="line"><span class="prompt">$ </span><span class="console__token">ls</span> <span class="console__token">-lh</span> <span class="console__token">~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw</span>
</span><span class="line"><span class="prompt">$ </span><span class="console__token">du</span> <span class="console__token">-h</span> <span class="console__token">~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw</span></span></code></pre>
    </div>
  </div></div><p><code>ls</code> printed 1.0T in both runs, and <code>du</code> printed 15G on one day and 14G on another (<code>du -h</code> shows GiB as G). The file is sparse: its maximum size is the disk limit, 1.0T here, and it occupies only the blocks that have been written. <code>du</code> counts those blocks, so it is the figure that matters. Write it down; it is your before number.</p>
<p>Also write down the free space the Mac reports, because that is what the prune is for:</p>
<div class="console"><div class="code-block code-block--wrap console__command" data-copyable data-copy-label="command">
    <div class="code-block__head"><span class="code-block__lang">Command</span></div>
    <div class="code-block__scroll"><pre data-copy-source><code><span class="line"><span class="prompt">$ </span><span class="console__token">diskutil</span> <span class="console__token">info</span> <span class="console__token">/</span> <span class="console__token">|</span> <span class="console__token">grep</span> <span class="console__token">&#34;Container</span> <span class="console__token">Free</span> <span class="console__token">Space&#34;</span>
</span><span class="line"><span class="prompt">$ </span><span class="console__token">df</span> <span class="console__token">-h</span> <span class="console__token">/</span></span></code></pre>
    </div>
  </div></div><h2 id="see-what-docker-says-it-can-reclaim">See what Docker says it can reclaim<a class="heading-anchor" href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#see-what-docker-says-it-can-reclaim"
     aria-label="Link to section: See what Docker says it can reclaim" data-pagefind-ignore></a>
</h2>
<p>Docker Desktop has to be running for these commands. Start it with <code>open -a Docker</code> and wait until <code>docker info</code> succeeds.</p>
<p><code>docker system df</code> prints how much each kind of object uses and how much of it Docker thinks it could reclaim:</p>
<div class="console"><div class="code-block code-block--wrap console__command" data-copyable data-copy-label="command">
    <div class="code-block__head"><span class="code-block__lang">Command</span></div>
    <div class="code-block__scroll"><pre data-copy-source><code><span class="line"><span class="prompt">$ </span><span class="console__token">docker</span> <span class="console__token">system</span> <span class="console__token">df</span></span></code></pre>
    </div>
  </div></div><p>On October 16 it showed 7 images, 1 of them active, 13.61GB in total with 4.213GB (30%) reclaimable. On October 19 it showed 2 images, 12.06GB, with 5.548GB (46%) reclaimable.</p>
<p>Docker has no dry-run option for the image prune that I found; its help text lists <code>--all</code>, <code>--filter</code> and <code>--force</code> only. To preview, list the images and the containers, including stopped ones, and compare them by hand:</p>
<div class="console"><div class="code-block code-block--wrap console__command" data-copyable data-copy-label="command">
    <div class="code-block__head"><span class="code-block__lang">Command</span></div>
    <div class="code-block__scroll"><pre data-copy-source><code><span class="line"><span class="prompt">$ </span><span class="console__token">docker</span> <span class="console__token">images</span>
</span><span class="line"><span class="prompt">$ </span><span class="console__token">docker</span> <span class="console__token">ps</span> <span class="console__token">-a</span></span></code></pre>
    </div>
  </div></div><p>An image that no container in the second list uses is a candidate for <code>docker image prune -a</code>. An image that a stopped container uses is not.</p>
<h2 id="prune-images-with-no-container">Prune images with no container<a class="heading-anchor" href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#prune-images-with-no-container"
     aria-label="Link to section: Prune images with no container" data-pagefind-ignore></a>
</h2>
<p>Two commands look alike, and they remove different sets. According to <code>docker image prune --help</code>, <code>-a</code> removes all unused images, which is more than the dangling ones. Plain <code>docker image prune</code> removes only dangling images, meaning untagged ones, so a tagged image that no container uses stays unless you pass <code>-a</code>.</p>
<div class="admonition admonition--warning" role="note">
  <p class="admonition__label">
    <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#i-triangle-alert"/></svg>
    <span>Warning</span>
  </p>
  <p><code>docker image prune -a</code> deletes every image that no container uses, named or not. Pulling a registry image again takes a download. An image you built locally and never pushed is gone for good and has to be rebuilt. The prune keeps images that a container uses and does not touch volumes.</p>
</div><div class="console"><div class="code-block code-block--wrap console__command" data-copyable data-copy-label="command">
    <div class="code-block__head"><span class="code-block__lang">Command</span></div>
    <div class="code-block__scroll"><pre data-copy-source><code><span class="line"><span class="prompt">$ </span><span class="console__token">docker</span> <span class="console__token">image</span> <span class="console__token">prune</span> <span class="console__token">-a</span></span></code></pre>
    </div>
  </div></div><p>Without <code>-f</code>, Docker asks for confirmation first. On October 16 (run with <code>-f</code>) it removed the six images with no container and reported <code>Total reclaimed space: 7.104GB</code>. The images went from 13.61GB to 6.508GB. An image that a stopped container uses, that container and its volume stayed, because the container used the image.</p>
<p>I didn&rsquo;t run <code>docker volume prune</code> or <code>docker system prune</code>, and this page doesn&rsquo;t either. A volume holds an app&rsquo;s data, and <code>docker system df</code> showed one local volume of 1.408GB that I wanted to keep.</p>
<h2 id="prune-the-build-cache-with-all">Prune the build cache with &ndash;all<a class="heading-anchor" href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#prune-the-build-cache-with-all"
     aria-label="Link to section: Prune the build cache with –all" data-pagefind-ignore></a>
</h2>
<p>This section rests on my recollection of a run on October 15, not on a terminal transcript, so treat the numbers as my report. Plain <code>docker builder prune</code> reported 24.58kB reclaimed. After <code>docker builder prune --all</code>, Docker reported a total of 7GB, and <code>docker system df</code> showed the build cache at 0B. <a href="https://docs.docker.com/reference/cli/docker/builder/prune/" rel="external noopener" target="_blank">Docker&rsquo;s reference for <code>docker builder prune</code><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#i-external-link"/></svg><span class="visually-hidden"> (opens in a new tab)</span></a> describes <code>--all</code> as removing all unused build cache, not only the dangling part. On Docker Desktop 4.96.0 the command runs as <code>docker buildx prune</code>, and its <code>--help</code> describes <code>--all</code> as &ldquo;Include internal/frontend images&rdquo; instead. Check <code>docker builder prune --help</code> on your version before you run it. Free space read 44Gi before it and 43Gi after, with no record of how long after; given how late the space came back on October 16, that reading was probably taken too soon, but I can&rsquo;t show it. I didn&rsquo;t re-run this one, so I can&rsquo;t tell you what the same commands report on your version.</p>
<div class="console"><div class="code-block code-block--wrap console__command" data-copyable data-copy-label="command">
    <div class="code-block__head"><span class="code-block__lang">Command</span></div>
    <div class="code-block__scroll"><pre data-copy-source><code><span class="line"><span class="prompt">$ </span><span class="console__token">docker</span> <span class="console__token">builder</span> <span class="console__token">prune</span> <span class="console__token">--all</span></span></code></pre>
    </div>
  </div></div><h2 id="wait-before-judging-the-result">Wait before judging the result<a class="heading-anchor" href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#wait-before-judging-the-result"
     aria-label="Link to section: Wait before judging the result" data-pagefind-ignore></a>
</h2>
<p>Free space did not move right after the prune. On October 16, the reading straight after was unchanged at 66,071,195,648 bytes, and <code>Docker.raw</code> still read 15G. Five minutes later free space was 73,278,255,104 bytes (up 7.2 GB) and <code>Docker.raw</code> read 8.6G. At 15 minutes both were unchanged from the five-minute reading.</p>
<p>On October 19, the second run, the space came back within a minute. Free space rose from 80.63 GB to 83.62 GB by the one-minute reading, and <code>Docker.raw</code> read 14G at the start and 8.6G from the one-minute reading on. I took no readings inside that first minute, so I can&rsquo;t say when it moved.</p>
<p><a href="https://docs.docker.com/desktop/troubleshoot-and-support/faqs/macfaqs/" rel="external noopener" target="_blank">Docker&rsquo;s documentation<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#i-external-link"/></svg><span class="visually-hidden"> (opens in a new tab)</span></a> says the same thing: &ldquo;It might take a few minutes to reclaim space on the host.&rdquo; A <code>df</code> taken straight after the prune makes it look as if nothing happened. Wait, then read both again:</p>
<div class="console"><div class="code-block code-block--wrap console__command" data-copyable data-copy-label="command">
    <div class="code-block__head"><span class="code-block__lang">Command</span></div>
    <div class="code-block__scroll"><pre data-copy-source><code><span class="line"><span class="prompt">$ </span><span class="console__token">du</span> <span class="console__token">-h</span> <span class="console__token">~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw</span>
</span><span class="line"><span class="prompt">$ </span><span class="console__token">diskutil</span> <span class="console__token">info</span> <span class="console__token">/</span> <span class="console__token">|</span> <span class="console__token">grep</span> <span class="console__token">&#34;Container</span> <span class="console__token">Free</span> <span class="console__token">Space&#34;</span></span></code></pre>
    </div>
  </div></div><h2 id="check-the-reclaimed-figure-against-dockerraw">Check the reclaimed figure against <code>Docker.raw</code><a class="heading-anchor" href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#check-the-reclaimed-figure-against-dockerraw"
     aria-label="Link to section: Check the reclaimed figure against Docker.raw" data-pagefind-ignore></a>
</h2>
<p>Docker&rsquo;s printed total and the earlier estimate differed in one run and matched in the other:</p>
<div class="table-wrap" data-scrollable data-label="Table: Run">
  <table>
    <thead>
      <tr><th scope="col">Run</th><th scope="col"><code>docker system df</code> estimate</th><th scope="col">Prune reported</th><th scope="col"><code>Docker.raw</code> before, after</th></tr>
    </thead>
    <tbody>
      <tr><td>October 16</td><td>4.213GB</td><td>7.104GB (69% more)</td><td>15G, 8.6G</td></tr>
      <tr><td>October 19</td><td>5.548GB</td><td>5.548GB (equal)</td><td>14G, 8.6G</td></tr>
    </tbody>
  </table>
</div>
<p>On October 16 the printed 7.104GB came close to the 7.2 GB of free space the Mac gained. On October 19 it didn&rsquo;t: <code>Docker.raw</code> shrank by about 5.4G (about 5.8 GB) while free space rose about 3.0 GB. Other writes and frees on the Mac run at the same time, so free space moves less, or more, than the file does. Treat <code>Docker.raw</code> from <code>du</code>, and the free space after the wait, as the measure, and the printed total as approximate.</p>
<p>The listed image sizes also add up to more than the estimate. On October 16 the unused images&rsquo; listed sizes added to about 10 GB while Docker estimated 4.213GB reclaimable. Shared layers, which Docker stores once, are the likely cause; I did not check the SHARED SIZE column of <code>docker system df -v</code>.</p>
<h2 id="do-this-with-a-coding-agent">Do this with a coding agent<a class="heading-anchor" href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#do-this-with-a-coding-agent"
     aria-label="Link to section: Do this with a coding agent" data-pagefind-ignore></a>
</h2>
<p>Paste this prompt into your own local coding agent. It measures and reports, and it asks before anything is removed:</p>
<div class="code-block" data-copyable data-copy-label="Text">
  <div class="code-block__head"><span class="code-block__lang">Text</span>
  </div>
  <div class="code-block__scroll">
    <div data-copy-source><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Investigate Docker Desktop&#39;s disk use on this Mac. Measure and report only;
</span></span><span class="line"><span class="cl">change nothing yet.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">0. Docker Desktop has to be running. If it is not, start it with
</span></span><span class="line"><span class="cl">   open -a Docker and wait until docker info succeeds.
</span></span><span class="line"><span class="cl">1. Read Docker.raw two ways: ls -lh and du -h on
</span></span><span class="line"><span class="cl">   ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw.
</span></span><span class="line"><span class="cl">   Explain that ls shows the sparse maximum and du the real size.
</span></span><span class="line"><span class="cl">2. Report free space with diskutil info / (Container Free Space) and df -h /.
</span></span><span class="line"><span class="cl">3. Run docker system df and docker system df -v. Report each category&#39;s total
</span></span><span class="line"><span class="cl">   and reclaimable figure.
</span></span><span class="line"><span class="cl">4. List images that no container uses (compare docker images with docker ps -a,
</span></span><span class="line"><span class="cl">   including stopped containers), with each one&#39;s size. List the build cache
</span></span><span class="line"><span class="cl">   and its size. These two are the only removal candidates.
</span></span><span class="line"><span class="cl">5. Report every volume with its size. Never propose removing a volume, and do
</span></span><span class="line"><span class="cl">   not run docker volume prune or docker system prune.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Then stop and wait for my confirmation. For images, remove only the ones I
</span></span><span class="line"><span class="cl">name, with docker image rm &lt;image&gt;. Run docker image prune -a -f only if I
</span></span><span class="line"><span class="cl">confirm removing every image on the list. For the build cache, run
</span></span><span class="line"><span class="cl">docker builder prune --all -f only after I confirm.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">After the prunes, wait a few minutes. The space can take that long to return.
</span></span><span class="line"><span class="cl">Then read du on Docker.raw and the free space again with the same commands, and
</span></span><span class="line"><span class="cl">compare the change against the total reclaimed space Docker printed. Say how far
</span></span><span class="line"><span class="cl">apart they are. Do not conclude the prune failed from a reading taken right
</span></span><span class="line"><span class="cl">after it.</span></span></code></pre></div></div>
  </div>
</div><h2 id="common-failures">Common failures<a class="heading-anchor" href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#common-failures"
     aria-label="Link to section: Common failures" data-pagefind-ignore></a>
</h2>
<h3 id="space-doesnt-come-back-after-you-quit-and-reopen-the-app">Space doesn&rsquo;t come back after you quit and reopen the app<a class="heading-anchor" href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#space-doesnt-come-back-after-you-quit-and-reopen-the-app"
     aria-label="Link to section: Space doesn’t come back after you quit and reopen the app" data-pagefind-ignore></a>
</h3>
<p>After the prune, <code>Docker.raw</code> read 8.6G before and after I quit and reopened Docker Desktop, on October 16 and again on October 19. Free space read 75.5 GB after the first reopening, but <code>Docker.raw</code> did not change, so that rise came from something else on the Mac.</p>
<h3 id="space-doesnt-come-back-after-you-update-the-app">Space doesn&rsquo;t come back after you update the app<a class="heading-anchor" href="https://looselydecoupled.com/docker-desktop-disk-space-mac/#space-doesnt-come-back-after-you-update-the-app"
     aria-label="Link to section: Space doesn’t come back after you update the app" data-pagefind-ignore></a>
</h3>
<p>I updated Docker Desktop on October 16 and, with <code>docker desktop update</code>, on October 20, and <code>Docker.raw</code> did not shrink either time: on October 20 it read 9,020,776 KB before and 9,020,796 KB after, 20 KB more. That is what I ran, on those versions; I make no claim about other releases.</p>
<div class="console"><div class="code-block code-block--wrap console__command" data-copyable data-copy-label="command">
    <div class="code-block__head"><span class="code-block__lang">Command</span></div>
    <div class="code-block__scroll"><pre data-copy-source><code><span class="line"><span class="prompt">$ </span><span class="console__token">docker</span> <span class="console__token">desktop</span> <span class="console__token">update</span> <span class="console__token">--check-only</span>
</span><span class="line"><span class="prompt">$ </span><span class="console__token">docker</span> <span class="console__token">desktop</span> <span class="console__token">update</span> <span class="console__token">--quiet</span></span></code></pre>
    </div>
  </div></div>]]></content:encoded>
    </item>
    
  </channel>
</rss>
