首页 文章

如何删除旧的Docker容器

提问于
浏览
1040

这个问题与Should I be concerned about excess, non-running, Docker containers?有关 .

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

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

30 回答

  • 3

    我总是使用 docker rmi $(docker ps -a -q) 删除所有图像 .

    docker rmi 失败时,您可以删除目录 /var/lib/docker/graph .

  • 595

    现在可以将filteringdocker ps 一起使用:

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

    对于images

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

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

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

    # 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
    }
    

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

  • 49

    UPDATED 2017 (最新)

    docker container prune
    

    这 - 2017 (OLD)方式

    删除 ALL STOPPED CONTAINERS

    docker rm $(docker ps -a -q)
    

    删除 ALL CONTAINERS (STOPPED AND NON STOPPED)

    docker rm  -f $(docker ps -a -q)
    
  • 31
    docker rm --force `docker ps -qa`
    
  • 91

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

    docker rm $(sudo docker ps -a | grep Exit | cut -d ' ' -f 1)
    

    以下是删除docker上旧图像的完整要点:Gist to remove old Docker containers and images .

  • 11

    Updated Answer 现在使用 docker system prunedocker container prune . 见VonC's updated answer .

    Previous Answer 在上面编写了几个不同的提示,删除所有非运行容器的最优雅方法似乎是:

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

    • -q 只打印容器ID(没有列 Headers )

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

  • 3

    删除5个最旧的容器:

    docker rm `docker ps -aq | tail -n 5`
    

    查看剩余的容器数量:

    docker ps -aq | wc -l
    
  • 5

    要在不哭的情况下移除所有容器:

    sudo docker ps -a | grep -v CONTAINER | awk '{print $1}' | xargs --no-run-if-empty sudo docker rm -f
    
  • 103

    对于任何有兴趣的人,我从qkrijger那里拿了一个例子并把它变成一个清晰的全部(停止并删除全部)

    docker stop `docker ps --no-trunc -aq` ; docker rm `docker ps --no-trunc -aq`
    
  • 2

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

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

    Remove containers created before an other container

    docker rm $(docker ps --before 9c49c11c8d21 -q)
    

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

    Remove containers created after a certain container

    docker rm $(docker ps --since a6ca4661ec7f -q)
    

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

  • 2

    这是我的 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
    

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

  • 6

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

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

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

    Original Answer:

    有一些关于Docker清理命令的讨论 . 你可以在这张票上找到这些信息:Implement a 'clean' command(#928)

    在该命令可用之前,您可以将Docker命令与其他Unix命令组合在一起以获得所需的信息 . 以下是如何清理旧周的旧容器的示例:

    $ docker ps --filter "status=exited" | grep 'weeks ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm
    

    为了给予信任,它应该到期,这个例子来自https://twitter.com/jpetazzo/status/347431091415703552 .

  • 2

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

    Docker清理

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

    • 超过一天前运行的容器

    • 不属于任何剩余容器的图像

    打算作为crontab作业运行

    功能

    • 它将删除所有 <none>:<none> 图像

    • 如果图像有多个repo:tag引用它,除了运行容器外,它将删除所有repo:标记 . 实际上这是"docker rmi"的性质 .

    • 屏幕上将显示许多错误消息,您可以决定是否 2>/dev/null

    • 从docker-gc学习一些东西,并修复它的问题(它不能删除有多个repo:tag的图像)

  • 5
    • 删除所有docker进程:
    docker rm $(docker ps -a -q)
    
    • 删除特定容器:
    $ docker ps -a (lists all old containers)
    
    $ docker rm container-Id
    
  • 115

    因此,我个人建议将此作为图像和容器的部署脚本的一部分,仅保留最近的n个容器和图像 . 我使用与 git tag 相同的版本控制模式标记我的Docker镜像,并始终使用"latest."标记最新的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
    

    现在,我当然不是最好的朋友.137223_这是你最好的朋友 . 由于 docker imagesdocker ps 都按日期排序,我们可以使用 tail 来选择除前三个之外的所有内容并将其删除:

    docker rmi $(docker images -q | tail -n +4)
    

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

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

    docker rm $(docker ps -aq | tail -n +4)
    

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

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

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

  • 394

    您只能删除已停止的容器 . 在开始时停止所有这些

    docker stop $(docker ps -a -q)

    然后你可以删除

    docker rm $(docker ps -a -q)

  • 245

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

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

    docker system prune 没有-a将删除(对于图像)仅悬空图像或没有标记的图像,如smilebombsmilebomb .

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

    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
    

    正如wjv评论,

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

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

    docker container prune
    
  • 33

    使用:

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

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

  • 21

    删除从特定图像创建的所有容器:

    docker rm  $(docker ps -a | awk '/myimage:mytag/{print $1}')
    
  • 13

    The official way是:

    docker rm `docker ps -aq`
    

    Docker维护者已经表示不会有这样的命令 - 你可以编写这样的命令:

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

  • 9

    Remove all stopped containers.

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

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

    Remove all untagged images

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

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

  • 8

    New way: spotify / docker-gc发挥作用 .

    docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /etc:/etc spotify/docker-gc
    
    • 已删除超过一小时前退出的容器 .

    • 删除之后不属于任何剩余容器的图像

    它支持环境设置

    Forcing deletion of images that have multiple tags

    FORCE_IMAGE_REMOVAL=1
    

    Forcing deletion of containers

    FORCE_CONTAINER_REMOVAL=1
    

    Excluding Recently Exited Containers and Images From Garbage Collection

    GRACE_PERIOD_SECONDS=86400
    

    此设置还可以防止删除创建的帧数小于GRACE_PERIOD_SECONDS秒前的图像 .

    Dry run

    DRY_RUN=1
    

    Cleaning up orphaned container volumes CLEAN_UP_VOLUMES = 1

    参考:docker-gc

    Old way to do:

    delete old, non-running containers

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

    delete all images associated with non-running docker containers

    docker images -q | xargs --no-run-if-empty docker rmi
    

    cleanup orphaned docker volumes for docker version 1.10.x and above

    docker volume ls -qf dangling=true | xargs -r docker volume rm
    

    Based on time period

    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
    
  • 7
    #!/bin/bash
    # docker-gc --- Remove stopped docker containers
    
    RUNNING=$(docker ps -q)
    ALL=$(docker ps -a -q)
    
    for container in $ALL ; do
        [[ "$RUNNING" =~ "$container" ]] && continue
        echo Removing container: $(docker rm $container)
    done
    
  • 5

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

    docker rm `docker ps --no-trunc -aq`
    

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

    对于Windows,由Bartosz Bilicki撰写:

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

    对于PowerShell:

    docker rm @(docker ps -aq)
    

    使用Docker 1.13(2016年第4季度)更新,归功于VonClater in this thread):

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

    请参阅PR 26108commit 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
    
  • 4

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

    删除正在运行的容器

    docker rm $(docker stop -t=1 $(docker ps -q))
    

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

    Note: 尝试停止容器会出错:

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

    删除所有容器

    docker rm $(docker ps -a -q)
    
  • 4

    从Windows shell中删除所有容器:

    FOR /f "tokens=*" %i IN ('docker ps -a -q') DO docker rm %i
    
  • 3

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

    docker system prune
    

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

    docker ps -aq -f status=exited | xargs docker rm
    

    同样,如果你正在清理docker的东西,你可以摆脱未标记的,未命名的图像办法:

    docker images -q --no-trunc -f dangling=true | xargs docker rmi
    
  • 2

    尝试使用此命令清理容器和悬空图像 .

    docker system prune -f
    
  • 1174

    停止/删除所有容器和图像的基本步骤

    • 列出所有容器

    docker ps -aq

    • 停止所有正在运行的容器

    docker stop $(docker ps -aq)

    • 删除所有容器

    docker rm $(docker ps -aq)

    • 删除所有图像

    docker rmi $(docker images -q)

    Note: 首先,您必须先停止所有正在运行的容器,然后再将其删除 . 在删除图像之前,您必须停止并删除其依赖容器 .

  • 3

    删除所有已停止的容器

    docker rm $(docker ps -a | grep Exited | awk '{print $1}')
    

    来自pauk960的评论:

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

相关问题