docker volume prune:不要删除命名卷

San*_*idi 7 docker

我已经创建了一个卷

docker volume create postgresql_db
Run Code Online (Sandbox Code Playgroud)

现在我在 docker-compose.xml 中使用它

services:
  postgresql:
    image: "postgres:11-alpine"
    volumes:
      - type: volume
        source: postgresql_data
        target: /var/lib/postgresql/data
        volume:
          nocopy: true        
    environment:
      PGDATA: '/var/lib/postgresql/data/pgdata'
    networks:  # connect to the bridge
      - postgresql_network
    command: ["postgres", "-c", "log_statement=all","-c", "log_destination=stderr"]

volumes: 
  postgresql_data:
    external: true
Run Code Online (Sandbox Code Playgroud)

有时我想停止并清理 docker 系统。

所以我尝试跑步

docker stop $(docker ps -aq) # stop all containers 
docker rm $(docker ps -a -q) # remove all containers
docker container prune
docker image prune
docker network prune
docker volume prune  #<-- remove all dangling volumes also
Run Code Online (Sandbox Code Playgroud)

这也删除了postgresql_dataienamed volume

如何避免这种情况。

BMi*_*tch 6

从 Docker 23.0.0 开始,这是默认行为docker volume prune,它只会清理匿名卷。对于任何需要返回到旧行为并修剪命名卷的人,您需要添加一个过滤器以包含命名卷:

docker volume prune --filter all=true
Run Code Online (Sandbox Code Playgroud)

使用标签来控制清理的内容也很有用,例如,我使用测试标签在测试场景中创建卷,然后仅显式修剪那些:

docker volume create --label=preserve volume-to-keep
docker volume create --label=test volume-to-prune
# ... run tests
docker volume prune -f --filter label=test --filter all=true
Run Code Online (Sandbox Code Playgroud)

上述要求您显式创建每个卷并且不依赖匿名卷。然后,您将避免在要保留的卷上设置该标签。


23.xx 之前的 docker 版本的原始答案

该命令没有docker volume prune为此的选项。该卷上也没有元​​数据表明它是匿名卷,它只是具有随机十六进制名称的命名卷。我最好的做法是列出悬空卷并删除具有长十六进制名称的卷。只要您命名的卷不完全是 64 个十六进制字符,它们就不会包含在其中:

docker volume ls -qf dangling=true | egrep '^[a-z0-9]{64}$' | \
  xargs --no-run-if-empty docker volume rm
Run Code Online (Sandbox Code Playgroud)


vpa*_*ini 1

好吧,根据Docker 的文档,您可以简单地过滤卷(例如,通过标签):

docker volume prune --filter label!=postgresql_db
Run Code Online (Sandbox Code Playgroud)

那么所有(查看!)名为postgresql_db且未附加到 1 个或多个容器的卷都将被删除。

  • 哦,你的意思是“排除所有命名卷”**不被删除**,对吗?现在这是有道理的。关于这一点,我认为 Docker 没有原生的方法来做到这一点。实际上,[这个 Moby 的问题](https://github.com/moby/moby/issues/31757)对此有一个有趣的讨论。作为解决方法,您可以在命名卷中采用一种模式(使用“_”或前缀“volume”单词)并使用“grep”或“awk”进行过滤 (2认同)