Conteúdo
Como liberar espaço em disco ocupado pelo Docker (comandos prune)
Depois de usar o Docker por algum tempo, imagens antigas, contêineres parados, cache de build e volumes sem uso vão se acumulando e podem ocupar dezenas de GB. Nesta seção, primeiro descubra o que está consumindo espaço e depois faça a limpeza com segurança. Todas as saídas são resultados de comandos executados em sequência no mesmo ambiente.
Confira o espaço usado
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 13 3 2.886GB 2.377GB (82%)
Containers 4 1 98.3kB 16.38kB (16%)
Local Volumes 4 1 40.61MB 40.61MB (100%)
Build Cache 151 0 3.554GB 2.954GB
| Campo | Significado |
|---|---|
TOTAL | Total |
ACTIVE | Quantidade em uso por contêineres |
SIZE | Espaço ocupado |
RECLAIMABLE | Parte que pode ser liberada (sem uso) |
Neste ambiente, há 13 imagens, mas apenas 3 estão em uso; 2.377 GB (82%) podem ser recuperados. O cache de build é ainda maior, com 2.954 GB. Adicione -v para ver os detalhes de cada imagem, contêiner e volume: docker system df -v.
Imagens e contêineres atuais:
$ docker images
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
adminer:latest 74f29c416e14 164MB 43.8MB
alpine:3.23 85fe1e81d675 26.6MB 8.21MB U
hello-node:latest 4063457524bb 245MB 62.2MB
myapp:latest 80cb5c41a286 54.9MB 24.8MB U
mysql:8.4 24989179f588 1.12GB 254MB
nginx:1.30 9bf97bd7714f 242MB 66.5MB
nginx:1.30-alpine 0985e772fb9f 93.7MB 27MB U
node:24-alpine ebfe2f904627 242MB 62MB
postgres:18 74935e722416 650MB 169MB
python:3.14-slim a2b82f3c4855 180MB 45.7MB
redis:8-alpine 3811787313eb 161MB 39.6MB
registry:3 ddf754342cfc 86.9MB 20.7MB
ubuntu:26.04 f144425ff09b 162MB 45.6MB
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc43746c9a29 alpine:3.23 "true" 7 seconds ago Exited (0) 6 seconds ago anon1
7e269fff858b nginx:1.30-alpine "/docker-entrypoint.…" 8 seconds ago Up 7 seconds 80/tcp web
bf5ff318eb63 alpine:3.23 "echo done" 8 seconds ago Exited (0) 7 seconds ago old2
b580380c1fd2 myapp "cat /version.txt" 9 seconds ago Exited (0) 8 seconds ago old1
O U na coluna EXTRA indica In Use (em uso por um contêiner). Entre os contêineres, apenas web está em execução; os outros três foram encerrados (Exited), mas ainda ocupam espaço.
Limpeza por categoria
| Comando | O que remove |
|---|---|
docker container prune | Todos os contêineres parados |
docker image prune | Imagens pendentes (sem nome, <none>) |
docker image prune -a | Todas as imagens que não estão em uso por nenhum contêiner |
docker builder prune | Cache de build |
docker volume prune | Volumes anônimos sem uso |
docker volume prune -a | Todos os volumes sem uso (inclusive os nomeados) |
docker network prune | Redes personalizadas sem uso |
Cada comando pede confirmação primeiro (Are you sure you want to continue? [y/N]). Adicione -f para ignorar a confirmação, o que é útil em scripts. Os exemplos a seguir usam -f.
Excluir contêineres parados
$ docker container prune -f
Deleted Containers:
cc43746c9a2993bda0fb21ab3f161b78603353714f396f86fa8c4b5caf90e25a
bf5ff318eb6331a05239ad7fa39420ff96dc1c8f84b9a3548ce38a0f71a2d63a
b580380c1fd2dc6cca2dc6e009bb877c3eb2df1cf388664a32c8932aff8169fa
Total reclaimed space: 16.38kB
Os três contêineres parados foram excluídos. O contêiner em execução web não foi afetado.
Se você usa o Docker Desktop, também pode selecionar os contêineres na tela Containers e clicar em Delete:

Docker 29: novas builds não deixam imagens <none>
Antes, ao reconstruir uma imagem com o mesmo nome (por exemplo, executando docker build -t myapp . várias vezes), a versão antiga ficava como uma “imagem pendente” chamada <none>, que precisava ser removida com docker image prune. Veja o teste no Docker 29:
$ docker build -q --build-arg VERSION=4 -t myapp:latest .
sha256:3f33bc33eb36171280e9b90d904e25c58b2dcf509390536580ffacafc35d4595
$ docker images --filter dangling=true
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
$ docker ps -a --filter name=old1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b580380c1fd2 80cb5c41a286 "cat /version.txt" 26 seconds ago Exited (0) 26 seconds ago old1
Após quatro builds seguidas de myapp:latest, o resultado de --filter dangling=true ficou vazio. Por padrão, o Docker 29 usa o armazenamento de imagens containerd. Quando uma nova imagem substitui a versão antiga, ela não é mais mantida como <none>. Para contêineres que ainda usam a versão antiga, como old1, a coluna IMAGE passa a mostrar o ID da imagem.
Por isso, no Docker 29, normalmente há pouco para limpar com docker image prune (sem -a). O que realmente ocupa espaço são as imagens sem uso, mas que ainda têm nome, e o cache de build.
Remover volumes anônimos
$ docker volume ls
DRIVER VOLUME NAME
local 6f6f8ce590c609d4f39b3a676282da88866c8ab20a064132f7746c3cf6717f2c
local 991c93cb6ebeac8570e9c15a89b4225c2bb5e20cbfde2f5bf665fa4dfa23a1aa
local 5396795eeeaab8415295814207a02f75f6ea136d5c34574ba9b16ecdc1b975f9
local cleanup-demo_pgdata
$ docker volume prune -f
Deleted Volumes:
5396795eeeaab8415295814207a02f75f6ea136d5c34574ba9b16ecdc1b975f9
991c93cb6ebeac8570e9c15a89b4225c2bb5e20cbfde2f5bf665fa4dfa23a1aa
6f6f8ce590c609d4f39b3a676282da88866c8ab20a064132f7746c3cf6717f2c
Total reclaimed space: 0B
$ docker volume ls
DRIVER VOLUME NAME
local cleanup-demo_pgdata
- Os três primeiros nomes longos são volumes anônimos. Por exemplo, o Dockerfile da imagem
postgresdeclaraVOLUME. Mesmo que você não monte um volume ao executar o contêiner, o Docker cria automaticamente um volume anônimo, que continua existindo depois que o contêiner é removido (consulte Volumes e persistência de dados). docker volume pruneremove apenas volumes anônimos que não estão em uso.cleanup-demo_pgdataé um volume nomeado do projeto Compose. Embora nenhum contêiner o esteja usando depois dedocker compose down, ele não foi removido.
Remover o cache de build
$ docker builder du | tail -n 3
Private: 2.996GB
Reclaimable: 3.596GB
Total: 3.596GB
$ docker builder prune -f --filter until=1h | tail -n 3
lv85kuv5xx5h65k941qjoxecz true 98.69kB About an hour ago
kc9tcgw8l1aq9dz1agx096se0 true 870kB About an hour ago
Total: 1.662GB
$ docker builder prune -f | tail -n 3
6os07ml167zpcfh09ushitk2b true 8.285kB 38 minutes ago
7ir7u28j6esk2x7pyu6q38kvk true 74.75MB 38 minutes ago
Total: 1.334GB
docker builder dumostra que o cache de build totaliza 3.596 GB, todos recuperáveis.--filter until=1hremove apenas o cache que não foi usado há mais de 1 hora, liberando 1.662 GB.- Sem o filtro, mais 1.334 GB são removidos.
Remover o cache de build significa que, na próxima compilação, todas as etapas terão que ser executadas novamente (por exemplo, rodar npm ci e pip install outra vez), o que será mais lento. Isso não afeta nenhuma imagem nem contêiner.
Limpeza de uma só vez: docker system prune
docker system prune
Remove: contêineres parados, redes não utilizadas, imagens dangling e cache de build.
docker system prune -a
Também remove todas as imagens que não estão em uso. Elas precisarão ser baixadas novamente quando forem usadas.
Teste prático: --volumes remove os dados do banco de dados?
Muitos tutoriais (incluindo uma versão anterior deste) alertam que docker system prune --volumes também remove o volume do banco de dados que fica “temporariamente sem uso” depois de docker compose down. Testamos no Docker 29:
$ docker system prune --volumes -f
Deleted Containers:
871f1c408d23dd413804105498b5520385dfafc9e558c02447ed940684bbc483
Deleted Volumes:
e5d0caa972c5323d5a64e9baf5fcb21d66ce7fbb4879bdcc7aa068a14fdbbf76
Total reclaimed space: 8.192kB
$ docker volume ls
DRIVER VOLUME NAME
local cleanup-demo_pgdata
--volumes removeu apenas um volume anônimo. O volume nomeado cleanup-demo_pgdata do banco de dados do Compose continua lá. Desde o Docker 23, volume prune e system prune --volumes tratam apenas volumes anônimos por padrão.
O comando que realmente remove volumes nomeados é docker volume prune -a:
$ docker volume prune -a -f
Deleted Volumes:
cleanup-demo_pgdata
Total reclaimed space: 40.61MB
$ docker volume ls
DRIVER VOLUME NAME
Desta vez, cleanup-demo_pgdata foi removido, e os 40.61 MB de arquivos do banco de dados que estavam nele também desapareceram, sem possibilidade de recuperação.
Use
docker volume prune -asomente quando tiver certeza de que não precisa de nenhum dado. Para remover um volume específico, é mais seguro usardocker volume rm nome; em um projeto Compose, usedocker compose down -v, que remove apenas os volumes desse projeto. Se você usa Docker 20.10 ou anterior,--volumesainda remove volumes nomeados.
Remover todas as imagens não utilizadas
$ docker image prune -a -f | grep -E "^untagged|^Total"
untagged: nginx:1.30
untagged: node:24-alpine
untagged: postgres:18
untagged: python:3.14-slim
untagged: myapp:latest
untagged: mysql:8.4
untagged: redis:8-alpine
untagged: registry:3
untagged: ubuntu:26.04
untagged: adminer:latest
untagged: alpine:3.23
untagged: hello-node:latest
Total reclaimed space: 2.665GB
$ docker images
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
nginx:1.30-alpine 0985e772fb9f 93.7MB 27MB U
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 93.66MB 0B (0%)
Containers 1 1 81.92kB 0B (0%)
Local Volumes 0 0 0B 0B
Build Cache 26 0 599.6MB 506.9MB
- Com exceção de
nginx:1.30-alpine, que está sendo usado pelo contêinerweb, as outras 12 imagens foram removidas, liberando 2.665 GB. - O
docker system dffinal mostra que restaram apenas 93.66 MB de imagens.
Essas imagens serão baixadas novamente automaticamente na próxima vez que você executar docker run ou fizer um build. Se a rede for lenta ou a imagem for muito grande (por exemplo, imagens relacionadas a modelos de IA podem facilmente ocupar vários GB), considere usar --filter para remover apenas as antigas:
docker image prune -a --filter "until=168h" # Remove apenas as imagens criadas há mais de 7 dias
Observe que until compara o horário de criação da imagem (quando o autor da imagem a compilou), e não o horário em que você a baixou.
Os logs dos contêineres também ocupam espaço
Por padrão, os logs json-file não têm limite de tamanho. Veja o teste prático com um contêiner que produz saída continuamente (o comando yes imprime uma grande quantidade de texto por segundo):
$ docker run -d --name noisy alpine:3.23 sh -c "timeout 3 yes hello-docker-log; sleep 600"
863ccacbc4bcf86a81cc3bf7603cef1d6ecc004553ac4b36dd7ef52172ed3dc6
$ docker inspect --format "{{.LogPath}}" noisy
/var/lib/docker/containers/863ccacbc4bcf86a81cc3bf7603cef1d6ecc004553ac4b36dd7ef52172ed3dc6/863ccacbc4bcf86a81cc3bf7603cef1d6ecc004553ac4b36dd7ef52172ed3dc6-json.log
$ du -h $(docker inspect --format "{{.LogPath}}" noisy)
69.3M /var/lib/docker/containers/863ccacbc4bcf86a81cc3bf7603cef1d6ecc004553ac4b36dd7ef52172ed3dc6/863ccacbc4bcf86a81cc3bf7603cef1d6ecc004553ac4b36dd7ef52172ed3dc6-json.log
$ docker rm -f noisy
noisy
O arquivo de log chegou a 69.3 MB com apenas 3 segundos de saída. Os arquivos de log de contêineres que ficam em execução por muito tempo e produzem muitos logs podem chegar a dezenas de GB. Eles não são removidos automaticamente; isso só acontece quando o contêiner é removido. Os arquivos de log ficam em /var/lib/docker/containers/ID_DO_CONTÊINER/. Em um host Linux, você pode encontrar os maiores arquivos de log assim:
sudo du -h /var/lib/docker/containers/*/*-json.log | sort -h | tail
Defina limites para um único contêiner
$ docker run -d --name noisy --log-opt max-size=10m --log-opt max-file=3 alpine:3.23 sh -c "timeout 3 yes hello-docker-log; sleep 600"
fab1c34ceecb955dc33c01f0e7aa0a60b4137e68d0fe465d52ce23b49ba66161
$ ls -lh $(dirname $(docker inspect --format "{{.LogPath}}" noisy)) | grep json
-rw------- 1 root root 3.2K Oct 13 01:07 config.v2.json
-rw-r----- 1 root root 7.2M Oct 13 01:07 fab1c34ceecb955dc33c01f0e7aa0a60b4137e68d0fe465d52ce23b49ba66161-json.log
-rw-r----- 1 root root 9.5M Oct 13 01:07 fab1c34ceecb955dc33c01f0e7aa0a60b4137e68d0fe465d52ce23b49ba66161-json.log.1
-rw-r----- 1 root root 9.5M Oct 13 01:07 fab1c34ceecb955dc33c01f0e7aa0a60b4137e68d0fe465d52ce23b49ba66161-json.log.2
-rw------- 1 root root 1.5K Oct 13 01:07 hostconfig.json
$ docker inspect --format '{{json .HostConfig.LogConfig}}' noisy
{"Type":"json-file","Config":{"max-file":"3","max-size":"10m"}}
$ docker rm -f noisy
noisy
max-size=10m significa que cada arquivo pode ter no máximo 10 MB; max-file=3 significa que até 3 arquivos serão mantidos. Os mais antigos são rotacionados para .1, .2. Com o mesmo volume de saída, os logs ocupam apenas cerca de 26 MB no total e não crescerão mais.
No Compose, a configuração fica assim:
services:
app:
image: myapp
logging:
options:
max-size: "10m"
max-file: "3"
Defina limites globais para os logs
Para aplicar limites a todos os novos contêineres: no Linux, edite /etc/docker/daemon.json; no Docker Desktop, edite o mesmo JSON em Settings → Docker Engine:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Depois de editar no Linux, execute sudo systemctl restart docker; no Docker Desktop, clique em Apply & restart. A configuração só será aplicada aos contêineres criados depois disso. Para os contêineres existentes, remova-os e crie-os novamente (no Compose, use docker compose up -d --force-recreate).
Docker Desktop: o espaço em disco não aumentou após a limpeza
No Windows e no macOS, todos os dados do Docker ficam em um arquivo de disco virtual. Quando você exclui imagens, o espaço dentro do disco virtual é liberado, mas o próprio arquivo pode não diminuir imediatamente.
- Docker Desktop: em Settings → Resources → Advanced, você pode ver e ajustar o limite do disco virtual. Clean / Purge data, na tela Troubleshoot, apaga todos os dados do Docker (imagens, contêineres e volumes). Use essa opção somente como último recurso.
- Windows (WSL 2): se o arquivo
.vhdxainda estiver grande, executewsl --shutdowne depois usecompact vdisknodiskpartpara compactar o arquivo.vhdxcorrespondente.
Limpeza periódica recomendada
Em um servidor, você pode usar o cron para executar a limpeza uma vez por semana:
docker container prune -f --filter "until=168h"
docker image prune -af --filter "until=168h"
docker builder prune -af --filter "until=168h"
Esses comandos não afetam nenhum volume, então os dados do banco de dados ficam seguros. Combinados com um limite global para os logs, eles ajudam a evitar que o uso de disco saia do controle.
Resumo
- Primeiro, consulte
docker system df; depois, decida o que limpar. image prune -aexclui todas as imagens que não estão em uso;builder prunelimpa o cache de build.volume pruneexclui apenas volumes anônimos;-atambém inclui os nomeados.- Defina limites para os logs com
max-sizeemax-file.
Exercícios
Exercício 1: escreva um conjunto de comandos que possa ser usado no cron sem afetar nenhum volume e que limpe apenas imagens e cache de build com mais de 7 dias.
Resposta
docker image prune -af --filter "until=168h"
docker builder prune -af --filter "until=168h"
Perguntas frequentes
O comando docker system prune é seguro?
Sem --volumes, ele não afeta nenhum volume; desde o Docker 23, mesmo com --volumes, ele só exclui volumes anônimos. O comando realmente perigoso é docker volume prune -a.
O espaço em disco do Windows não aumentou após a limpeza?
Os dados do Docker Desktop ficam em um arquivo de disco virtual. Depois de excluir imagens, o arquivo pode não diminuir imediatamente; consulte a última seção deste capítulo.
Posso excluir todo o cache de build?
Sim. Isso não afeta nenhuma imagem nem contêiner, mas a próxima build será mais lenta.
Atualizado 14 de outubro de 2026