如何删除旧的Docker容器

qkr*_*ger 1162 docker

这个问题与我是否应该关注多余的,非运行的Docker容器有关?.

我想知道如何删除旧容器.将docker rm 3e552code34a让你删除一个,但我有很多了.docker rm --help不提供选择选项(如全部或图像名称).

也许有一个存储这些容器的目录,我可以手动轻松删除它们?

Ken*_*ane 1359

Docker 1.13.x中有一个名为Docker container prune的新功能: __CODE__

这将做你想要的,并且应该以相同的方式在所有平台上工作.

还有一个Docker系统prune : __CODE__,它将在一个命令中清理容器,图像,卷和网络.

原答案:

有一些关于Docker清理命令的讨论.您可以在此票证中找到相关信息:实施"清洁"命令(#928)

在该命令可用之前,您可以将Docker命令与其他Unix命令结合使用以获得所需的命令.这是一个关于如何清理数周之久的旧容器的示例:

docker container prune
Run Code Online (Sandbox Code Playgroud)

为了给予应有的信用,这个例子来自https://twitter.com/jpetazzo/status/347431091415703552.

  • 删除所有未标记图像的类似命令:`docker images | grep"<无>"| awk'{print $ 3}'| xargs码头工人rmi` (91认同)
  • @MichelMüller在从dockerfile构建映像时,您可以指定`-rm`选项,以在成功构建后删除中间容器. (7认同)
  • 如果你想使用awk这个,请考虑这个命令,如果你想做rm所有停止的容器(因为第一行没有错误):`docker ps -a | awk'NR> 1 {打印$ 1}'| xargs docker rm` (7认同)
  • @MichelMüller图像是用于缓存的图像,因此删除容器不会影响它. (3认同)
  • 如果你得到权限被拒绝的错误,在最后一个命令的docker之前添加`sudo`:`$ sudo docker ps -a | grep'周前'| awk'{print $ 1}'| xargs --no-run-if-empty sudo docker rm -f` (2认同)
  • 值得注意的是,您可以替换`grep ... | awk`只是`awk`. (2认同)
  • 这应该是用于删除未标记图像的更新命令`docker rmi $(docker images -q -f dangling = true) (2认同)

qkr*_*ger 623

我从Guillaume J. Charmes获得的另一种方法(信用到期):

docker rm `docker ps --no-trunc -aq`
Run Code Online (Sandbox Code Playgroud)

将以优雅的方式移除所有容器.

对于Windows,由Bartosz Bilicki撰写:

FOR /f "tokens=*" %i IN ('docker ps -a -q') DO docker rm %i
Run Code Online (Sandbox Code Playgroud)

对于PowerShell:

docker rm @(docker ps -aq)
Run Code Online (Sandbox Code Playgroud)

使用Docker 1.13(2016年第4季度)的更新,归功于VonC(本主题后面的内容):

docker system prune 将删除所有未使用的数据(即按顺序:容器停止,没有容器的卷和没有容器的图像).

请参阅PR 26108提交86de7c0,它们引入了一些新命令,以帮助显示Docker守护程序数据在磁盘上占用的空间,并允许轻松清理"不需要的"多余空间.

docker system prune

WARNING! This will remove:
    - all stopped containers
    - all volumes not used by at least one container
    - all images without at least one container associated to them
Are you sure you want to continue? [y/N] y
Run Code Online (Sandbox Code Playgroud)

  • 怎么样`docker rm $(docker ps -a -q)`? (85认同)
  • 这对我来说不起作用,但是`docker ps -a -q | xargs docker rm` works,(可能需要sudo) (11认同)
  • @qkrijger,除了添加bashism之外,这不会改变你原来的答案.问题在于命令行溢出.xargs变种以一种很好的方式处理它.我还要添加--no-trunk到docker ps以避免(不太可能)id冲突. (8认同)
  • 请注意,如果您使用仅数据容器,它也会删除它们 (8认同)
  • 我没有看到`--no-trunc`这一点,因为`docker rm`无论如何都不需要完整的ID. (4认同)
  • @Pithikos的重点是两个哈希以相同的8个字母数字字符开始的可能性非常小:).重点是,无论如何,在编写脚本时都没有使用整个哈希值 (3认同)
  • @maxschlepzig,我不记得在撰写评论时我到底在想什么,所以让我们认为这是一个错误.绝不是`$()`是一种基础,而且IIRC反引号被认为是弃用的,而$()是推荐的方式. (2认同)

Rya*_*lls 408

更新的答案 使用docker system prunedocker container prune现在.请参阅VonC的更新答案.

上一个答案根据 上面的几个不同提示,删除所有非运行容器的最优雅方法似乎是:

docker rm $(docker ps -q -f status=exited)

  • -q 只打印容器ID(没有列标题)
  • -f 允许您过滤打印容器列表(在这种情况下,我们过滤只显示已退出的容器)

  • 您可能希望添加`-v`以避免悬空卷:`docker rm -v $(docker ps -q -f status = exited)`.有关悬空卷的详细信息,请参阅https://docs.docker.com/userguide/dockervolumes/#creating-and-mounting-a-data-volume-container. (18认同)
  • 这应该是正确的答案,因为它依赖于docker来告诉您哪些容器不再使用,而不是假设$(docker images)的文本输出格式不会改变.仅产生一个额外过程而不是两个额外过程的奖励积分. (7认同)

Mic*_*ale 253

官方的方式是:

docker rm `docker ps -aq`
Run Code Online (Sandbox Code Playgroud)

Docker维护者已经指出没有命令 - 你编写这样的命令:

我们之前已经讨论过这个问题,并且希望用户使用上面的代码而无需向Docker添加其他代码.

  • 你是什​​么意思"存储容器"?如果您指的是曾经一度用于保留对数据卷的引用的仅数据容器,则由于"docker volume"子命令和命名卷的可用性,不再需要这些容器. (8认同)
  • 这是一个糟糕的解决方案,因为它还会删除存储容器. (6认同)

Von*_*onC 127

使用Docker 1.13(2016年第4季度),您现在拥有:

docker system prune -a 将删除所有未使用的数据(即按顺序:容器停止,没有容器的卷和没有容器的图像).

docker system prune而不-a将删除(对于图像)仅悬空的图像,或图像,而无需标记,作为评价smilebomb.

请参阅PR 26108提交86de7c0,它们引入了一些新命令,以帮助显示Docker守护程序数据在磁盘上占用的空间,并允许轻松清理"不需要的"多余空间.

docker system prune -a

WARNING! This will remove:
    - all stopped containers
    - all volumes not used by at least one container
    - all images without at least one container associated to them
Are you sure you want to continue? [y/N] y
Run Code Online (Sandbox Code Playgroud)

作为wjv评论,

还有docker {container,image,volume,network} prune,可用于删除仅一种类型对象的未使用实例.

commit 913e5cb中引入,仅适用于Docker 1.13+.

docker container prune
Run Code Online (Sandbox Code Playgroud)

  • 应该被标记为现在正确的答案,上面的大部分时间都是正确的,但是今天过于复杂 (3认同)

cak*_*tux 103

现在可以使用过滤docker ps:

docker rm $(docker ps -q -f status=exited)
Run Code Online (Sandbox Code Playgroud)

对于图像:

docker rmi $(docker images -q -f "dangling=true")
Run Code Online (Sandbox Code Playgroud)

但是,当没有匹配的容器时,任何这些都将导致docker rmdocker rmi抛出错误.较旧的docker rm $(docker ps -aq)技巧甚至更糟,因为它试图移除任何正在运行的容器,每个容器都失败了.

这是一个更清晰的脚本,可以添加到您的~/.bashrc~/.profile:

# Use `docker-cleanup --dry-run` to see what would be deleted.

function docker-cleanup {
  EXITED=$(docker ps -q -f status=exited)
  DANGLING=$(docker images -q -f "dangling=true")

  if [ "$1" == "--dry-run" ]; then
    echo "==> Would stop containers:"
    echo $EXITED
    echo "==> And images:"
    echo $DANGLING
  else
    if [ -n "$EXITED" ]; then
      docker rm $EXITED
    else
      echo "No containers to remove."
    fi
    if [ -n "$DANGLING" ]; then
      docker rmi $DANGLING
    else
      echo "No images to remove."
    fi
  fi
}
Run Code Online (Sandbox Code Playgroud)

编辑:如下所述,原始答案是删除图像,而不是容器.更新以回答这两个问题,包括文档的新链接.感谢Adrian(和Ryan的回答)提到新的ps过滤.

  • 注意这个的真正优势 - 你不会意外地杀掉`storage` conatiner. (2认同)
  • 您还可以使用`status = created`来获取未运行且从未运行的那些. (2认同)

lev*_*evi 92

2017年更新(最新)

docker container prune
Run Code Online (Sandbox Code Playgroud)

这 - 2017(旧)方式

删除所有停止的容器

docker rm $(docker ps -a -q)
Run Code Online (Sandbox Code Playgroud)

删除所有容器 (停止和未停止)

docker rm  -f $(docker ps -a -q)
Run Code Online (Sandbox Code Playgroud)

  • 因为a)这个答案来自2016年,并且b)许多人没有跑出边缘,所以投票反击了downvote. (6认同)
  • downvoted,因为这肯定是_not_你在2017年那样做的方式 - whis会是`docker volume/container/image prune`,请参阅/sf/answers/2790246581/ (3认同)

mon*_*lls 49

删除所有已停止的容器

docker rm $(docker ps -a | grep Exited | awk '{print $1}')
Run Code Online (Sandbox Code Playgroud)

来自pauk960的评论:

从版本1.3.0您可以使用过滤器以docker ps代替grep Exited使用docker ps -a -f status=exited.如果你使用-q它,你只能获得容器ID而不是完整的输出,不需要使用awk.


小智 33

如果你不喜欢删除所有容器,您可以选择前或在特定容器后创建的所有容器docker ps --before <container-ID>docker ps --since <container-ID>.此功能至少在Docker版本0.6.5中.

假设您已经开发了系统,现在它正在运行,但是还有许多容器.您想要删除在该工作版本之前创建的容器.确定工作容器的ID docker ps.

删除在其他容器之前创建的容器

docker rm $(docker ps --before 9c49c11c8d21 -q)
Run Code Online (Sandbox Code Playgroud)

另一个例子.您的数据库已经在Docker容器上运行.您已经开发了应用程序以在另一个容器上运行,现在您有许多不需要的容器.

删除在某个容器后创建的容器

docker rm $(docker ps --since a6ca4661ec7f -q)
Run Code Online (Sandbox Code Playgroud)

Docker将容器存储/var/lib/docker/containers在Ubuntu中.我认为额外的容器不会造成其他伤害,但会占用磁盘空间.


L0j*_*j1k 32

更新:从Docker 1.13版(2017年1月发布)开始,您可以发出以下命令来清理已停止的容器,未使用的卷,悬空图像和未使用的网络:

docker system prune
Run Code Online (Sandbox Code Playgroud)

如果您想确保只删除具有exited状态的容器,请使用以下命令:

docker ps -aq -f status=exited | xargs docker rm
Run Code Online (Sandbox Code Playgroud)

同样,如果你正在清理docker的东西,你可以用这种方式摆脱未标记的,未命名的图像:

docker images -q --no-trunc -f dangling=true | xargs docker rmi
Run Code Online (Sandbox Code Playgroud)


blu*_*yed 22

这是我的docker-cleanup脚本,它删除未标记的容器和图像.请检查来源以获取任何更新.

#!/bin/sh
# Cleanup docker files: untagged containers and images.
#
# Use `docker-cleanup -n` for a dry run to see what would be deleted.

untagged_containers() {
  # Print containers using untagged images: $1 is used with awk's print: 0=line, 1=column 1.
  docker ps -a | awk '$2 ~ "[0-9a-f]{12}" {print $'$1'}'
}

untagged_images() {
  # Print untagged images: $1 is used with awk's print: 0=line, 3=column 3.
  # NOTE: intermediate images (via -a) seem to only cause
  # "Error: Conflict, foobarid wasn't deleted" messages.
  # Might be useful sometimes when Docker messed things up?!
  # docker images -a | awk '$1 == "<none>" {print $'$1'}'
  docker images | tail -n +2 | awk '$1 == "<none>" {print $'$1'}'
}

# Dry-run.
if [ "$1" = "-n" ]; then
  echo "=== Containers with uncommitted images: ==="
  untagged_containers 0
  echo

  echo "=== Uncommitted images: ==="
  untagged_images 0

  exit
fi

# Remove containers with untagged images.
echo "Removing containers:" >&2
untagged_containers 1 | xargs --no-run-if-empty docker rm --volumes=true

# Remove untagged images
echo "Removing images:" >&2
untagged_images 3 | xargs --no-run-if-empty docker rmi
Run Code Online (Sandbox Code Playgroud)

资料来源:https://github.com/blueyed/dotfiles/blob/master/usr/bin/docker-cleanup

  • 由于`xargs --no-run-if-empty`选项,在OSX上不起作用 (3认同)

Uli*_*ses 13

首先,在尝试删除容器之前停止运行容器

删除正在运行的容

docker rm $(docker stop -t=1 $(docker ps -q))
Run Code Online (Sandbox Code Playgroud)

你可以用kill而不是stop.在我的情况下,我更喜欢,stop因为我倾向于重新运行它们而不是每次创建一个新的,所以我试图将它们很好地关闭.

注意:尝试停止容器会出错:

错误:无法移除正在运行的容器,请先停止它

删除所有容器

docker rm $(docker ps -a -q)
Run Code Online (Sandbox Code Playgroud)


Bar*_*cki 11

从Windows shell中删除所有容器:

FOR /f "tokens=*" %i IN ('docker ps -a -q') DO docker rm %i
Run Code Online (Sandbox Code Playgroud)


Har*_*son 9

https://github.com/HardySimpson/docker-cleanup

Docker清理

一个很小的一体化外壳,可以删除:

  • 没有超过一天运行的容器
  • 不属于任何剩余容器的图像

打算作为crontab作业运行

特征

  • 它将删除所有<none>:<none>图像
  • 如果图像有多个repo:tag引用,它将删除所有repo:标记,但运行容器除外.实际上它是"docker rmi"的本质.
  • 屏幕上会显示许多错误消息,您可以决定2>/dev/null与否
  • 从docker-gc学习一些东西,并修复它的问题(它不能删除有多个repo:tag的图像)


Md.*_*sen 9

查看所有现有图像:

docker images -a
Run Code Online (Sandbox Code Playgroud)

查看所有现有容器:

docker ps -a
Run Code Online (Sandbox Code Playgroud)

删除单张图像:

docker images -a
docker rmi <IMAGE_ID>
Run Code Online (Sandbox Code Playgroud)

停止单个容器:

docker ps -a
docker stop <CONTAINER_ID>
Run Code Online (Sandbox Code Playgroud)

停止多个容器:

docker ps -a
docker stop <CONTAINER_ID1> <CONTAINER_ID2>
Run Code Online (Sandbox Code Playgroud)

删除单个容器:

docker ps -a
docker rm <CONTAINER_ID>
Run Code Online (Sandbox Code Playgroud)

删除多张图像:

docker images -a
docker rmi <IMAGE_ID1> <IMAGE_ID2>
Run Code Online (Sandbox Code Playgroud)

删除多个停止的容器:

docker ps -a
docker rm <CONTAINER_ID1> <CONTAINER_ID2>
Run Code Online (Sandbox Code Playgroud)

仅在单个命令中删除图像:

docker rmi -f $(docker images -a -q)
Run Code Online (Sandbox Code Playgroud)

在一个命令中删除容器和镜像:

docker rm $(docker ps -a -q) && docker rmi -f $(docker images -a -q)
Run Code Online (Sandbox Code Playgroud)

要修剪所有容器:

docker container prune
Run Code Online (Sandbox Code Playgroud)


Sha*_*k G 8

使用:

docker rm -f $(docker ps -a -q)
Run Code Online (Sandbox Code Playgroud)

它强制停止并移除当地存在的所有容器.


Eli*_*Eli 7

因此,我个人建议将此作为图像和容器的部署脚本的一部分,仅保留最近的n个容器和图像.我用我使用的相同版本模式标记我的Docker镜像,git tag并始终使用"最新"标记最新的Docker镜像.这意味着在没有清理任何东西的情况下,我的Docker图像看起来像:

REPOSITORY              TAG       IMAGE ID        CREATED         VIRTUAL SIZE
some_repo/some_image    0.0.5     8f1a7c7ba93c    23 hours ago    925.4 MB
some_repo/some_image    latest    8f1a7c7ba93c    23 hours ago    925.4 MB
some_repo/some_image    0.0.4     0beabfa514ea    45 hours ago    925.4 MB
some_repo/some_image    0.0.3     54302cd10bf2    6 days ago      978.5 MB
some_repo/some_image    0.0.2     0078b30f3d9a    7 days ago      978.5 MB
some_repo/some_image    0.0.1     sdfgdf0f3d9a    8 days ago      938.5 MB
Run Code Online (Sandbox Code Playgroud)

现在,我当然不想让我的所有图像(或容器)在我的所有生产盒上都保持永久性.我只想要最后的3或4回滚并摆脱其他一切.Unix tail是你最好的朋友.由于按日期docker imagesdocker ps按日期排序,我们可以使用tail除了前三个之外的所有选项并将其删除:

docker rmi $(docker images -q | tail -n +4)
Run Code Online (Sandbox Code Playgroud)

与您的部署脚本(或本地)一起运行它以始终保持足够的图像以舒适地回滚,而不会占用太多空间或使旧图像混乱.

就个人而言,我在任何时候都只在我的生产箱上放置一个容器,但是如果你想要更多,你可以用容器做同样的事情:

docker rm $(docker ps -aq | tail -n +4)
Run Code Online (Sandbox Code Playgroud)

最后,在我的简化示例中,我们一次只处理一个存储库,但如果您有更多,则可以使用相同的想法获得更复杂的功能.假设我只想保留some_repo/some_image中的最后三个图像.我可以混合进去grep,awk并在我的路上:

docker rmi $(docker images -a | grep 'some_repo/some_image' | awk '{print $3}' | tail -n +4)
Run Code Online (Sandbox Code Playgroud)

同样,同样的想法也适用于容器,但是到目前为止你得到了它,所以我将停止给出例子.


小智 7

删除所有已停止的容器

sudo docker rm $(sudo docker ps -a -q)

这将通过使用docker ps -a -q获取所有容器的列表并将其id传递给docker rm来删除所有已停止的容器.这不应该删除任何正在运行的容器,它会告诉你它无法删除正在运行的图像.

删除所有未标记的图像

现在您要清理旧图像以节省一些空间.

sudo docker rmi $(sudo docker images -q --filter"dangling = true")


ede*_*bin 7

我想添加这个简单的答案,因为我没有看到它,而且问题特别是“旧”而不是“全部”。

sudo docker container prune --filter "until=24h"

根据您想要删除旧容器的时间跨度调整 24 小时。


pad*_*dak 6

  1. 删除所有docker进程:

    docker rm $(docker ps -a -q)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 删除特定容器:

    $ docker ps -a (lists all old containers)
    
    $ docker rm container-Id
    
    Run Code Online (Sandbox Code Playgroud)


Pit*_*kos 6

删除5个最旧的容器:

docker rm `docker ps -aq | tail -n 5`
Run Code Online (Sandbox Code Playgroud)

查看剩余的容器数量:

docker ps -aq | wc -l
Run Code Online (Sandbox Code Playgroud)


f-s*_*ety 6

新方法: spotify/docker-gc发挥作用.

 docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /etc:/etc spotify/docker-gc
Run Code Online (Sandbox Code Playgroud)
  • 退出一个多小时前的容器将被删除.
  • 之后不属于任何剩余容器的图像将被删除

它支持环境设置

强制删除具有多个标记的图像

 FORCE_IMAGE_REMOVAL=1
Run Code Online (Sandbox Code Playgroud)

强制删除容器

 FORCE_CONTAINER_REMOVAL=1 
Run Code Online (Sandbox Code Playgroud)

从垃圾收集中排除最近退出的容器和图像

 GRACE_PERIOD_SECONDS=86400
Run Code Online (Sandbox Code Playgroud)

此设置还可以防止删除创建的GRACE_PERIOD_SECONDS秒之前的图像.

干运行

 DRY_RUN=1
Run Code Online (Sandbox Code Playgroud)

清理孤立的容器卷 CLEAN_UP_VOLUMES = 1

参考:docker-gc

旧方法:

删除旧的,未运行的容器

 docker ps -a -q -f status=exited | xargs --no-run-if-empty docker rm
             OR 
 docker rm $(docker ps -a -q)
Run Code Online (Sandbox Code Playgroud)

删除与未运行的docker容器关联的所有图像

 docker images -q | xargs --no-run-if-empty docker rmi
Run Code Online (Sandbox Code Playgroud)

清理docker版本1.10.x及更高版本的孤立docker卷

 docker volume ls -qf dangling=true | xargs -r docker volume rm
Run Code Online (Sandbox Code Playgroud)

根据时间段

 docker ps -a | grep "weeks ago" | awk "{print $1}" | xargs --no-run-if-empty docker rm
 docker ps -a | grep "days ago" | awk "{print $1}" | xargs --no-run-if-empty docker rm
 docker ps -a | grep "hours ago" | awk "{print $1}" | xargs --no-run-if-empty docker rm
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以使用以下命令删除退出的容器:

docker rm $(sudo docker ps -a | grep Exit | cut -d ' ' -f 1)
Run Code Online (Sandbox Code Playgroud)

以下是删除 docker上旧图像的完整要点:删除旧 Docker 容器和图像的要点