Как удалить старые контейнеры Docker

Этот вопрос связан с тем, должен ли я беспокоиться о лишних, не запущенных контейнерах Docker?,

Мне интересно, как удалить старые контейнеры. docker rm 3e552code34a позволяет удалить один, но у меня уже есть много. docker rm --help не дает возможность выбора (как все, или по имени изображения).

Может быть, есть каталог, в котором хранятся эти контейнеры, где я могу легко удалить их вручную?

67 ответов

Решение

В Docker 1.13.x появилась новая функция, называемая Docker контейнера Prune:docker container prune

Это будет делать то, что вы хотите, и должно работать на всех платформах одинаково.

Существует также черновая система Docker: docker system prune, который очистит контейнеры, образы, тома и сети в одну команду.

Оригинальный ответ:

Ходили разговоры о команде очистки Docker. Вы можете найти информацию по этому билету: Выполните команду "clean" (#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.

Другой метод, который я получил от Гийома Ж. Шармса (кредит, где он должен):

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

удалит все контейнеры элегантным способом.

И Бартош Билицки, для Windows:

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

Для PowerShell:

docker rm @(docker ps -aq)

Обновление с Docker 1.13 (4 квартал 2016 г.), кредит VonC ( далее в этой теме):

docker system prune удалит ВСЕ неиспользуемые данные (т. е. по порядку: контейнеры остановлены, тома без контейнеров и изображения без контейнеров).

См. PR 26108 и commit 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

Обновленный ответ Использование docker system prune или же docker container prune сейчас. Смотрите обновленный ответ VonC.

Предыдущий ответ Составляя несколько разных советов, приведенных выше, наиболее элегантный способ удаления всех неработающих контейнеров выглядит так:

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

  • -q печатает только идентификаторы контейнера (без заголовков столбцов)
  • -f позволяет фильтровать список распечатанных контейнеров (в этом случае мы фильтруем только отображаемые контейнеры)

Официальный способ:

docker rm `docker ps -aq`

Сопровождающие Docker указали, что для этого не будет никаких команд - и вы составляете команды так:

Мы обсуждали это раньше и предпочитаем, чтобы пользователи использовали приведенную выше строку без добавления дополнительного кода в Docker.

С Docker 1.13 (4 квартал 2016 года) у вас теперь есть:

docker system prune -a удалит ВСЕ неиспользуемые данные (т. е. по порядку: контейнеры остановлены, тома без контейнеров и изображения без контейнеров).

docker system prune без -a удалит (для изображений) только свисающие изображения или изображения без тега, как прокомментировал smilebomb.

См. PR 26108 и commit 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

Как комментарии wjv,

Существует также docker {container,image,volume,network} prune, который может быть использован для удаления неиспользуемых экземпляров только одного типа объекта.

Представлено в коммите 913e5cb, только для Docker 1.13+.

docker container prune

ОБНОВЛЕНО 2017 (НОВИНКА)

docker container prune

Это - 2017 (СТАРЫЙ) путь

Удалить ВСЕ ОСТАНОВЛЕННЫЕ КОНТЕЙНЕРЫ

docker rm $(docker ps -a -q)

Чтобы удалить ВСЕ КОНТЕЙНЕРЫ (ОСТАНОВЛЕННЫЕ И НЕ ОСТАНОВЛЕННЫЕ)

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

Теперь можно использовать фильтрацию с docker ps:

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

И для изображений:

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

Тем не менее, любой из них приведет к docker rm или же docker 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
}

Изменить: как отмечено ниже, оригинальный ответ был для удаления изображений, а не контейнеров. Обновлено, чтобы ответить на оба, в том числе новые ссылки на документацию. Спасибо Адриану (и ответу Райана) за упоминание нового ps фильтрация.

Удалить все остановленные контейнеры:

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

Из комментария pauk960:

Начиная с версии 1.3.0 вы можете использовать фильтры с docker ps, вместо grep Exited использование docker ps -a -f status=exited, И если вы используете -q с его помощью вы можете получить только идентификаторы контейнера вместо полного вывода, для этого не нужно использовать awk.

Если вам не нравится удалять все контейнеры, вы можете выбрать все контейнеры, созданные до или после определенного контейнера с помощью docker ps --before <container-ID> или с docker ps --since <container-ID>, Эта функция по крайней мере в версии Docker 0.6.5.

Допустим, вы разработали свою систему, и теперь она работает, но осталось несколько контейнеров. Вы хотите удалить контейнеры, созданные до этой рабочей версии. Определите идентификатор рабочего контейнера с помощью docker ps,

Удалить контейнеры, созданные до другого контейнера

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

Другой пример. Ваша база данных уже запущена в контейнере Docker. Вы разработали свое приложение для запуска в другом контейнере, и теперь у вас есть ряд ненужных контейнеров.

Удалить контейнеры, созданные после определенного контейнера

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

Докер хранит контейнеры в /var/lib/docker/containers в убунту. Я думаю, что дополнительные контейнеры не наносят никакого другого вреда, но занимают место на диске.

Обновление: начиная с версии 1.13 Docker (выпущено в январе 2017 г.), вы можете выполнить следующую команду для очистки остановленных контейнеров, неиспользуемых томов, висячих образов и неиспользуемых сетей:

docker system prune

Если вы хотите убедиться, что вы удаляете только те контейнеры, которые имеют exited статус, используйте это:

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

Точно так же, если вы чистите докер, вы можете избавиться от немаркированных, неназванных изображений следующим образом:

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

Вот мой 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

Во-первых, прекратите запуск контейнеров, прежде чем пытаться их удалить

Удалить работающие контейнеры

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

Вы могли бы использовать kill вместо stop, В моем случае я предпочитаю stop так как я склонен перезапускать их вместо создания нового каждый раз, поэтому я стараюсь их аккуратно отключить.

Примечание. Попытка остановить контейнер приведет к ошибке:

Ошибка: невозможно удалить работающий контейнер, сначала остановите его

Удалить все контейнеры

docker rm $(docker ps -a -q)

Удаление всех контейнеров из оболочки Windows:

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

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

Очистка докера

Крошечная универсальная оболочка, которая удаляет:

  • Контейнеры, которые не работают более одного дня назад
  • Изображения, которые не принадлежат ни одному оставшемуся контейнеру

Намерены работать как задание crontab

Особенность

  • Это удалит все <none>:<none> изображений
  • Если изображение имеет несколько ссылок на тег repo: к нему, оно удалит все теги repo: кроме запуска контейнера. На самом деле это природа "Docker RMI".
  • Многие сообщения об ошибках будут отображаться на экране, и вы можете решить 2>/dev/null или нет
  • Изучите что-нибудь из docker-gc и исправьте его проблему (он не может удалить изображение, имеющее mutliple repo:tag)

Поэтому лично я рекомендую сделать это как часть вашего сценария развертывания для образов и контейнеров, сохраняя только самые последние 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

Теперь, конечно, я не хочу, чтобы все мои изображения (или контейнеры) возвращались к вечности на всех моих производственных коробках. Я просто хочу последние 3 или 4 для отката и избавления от всего остального. Unix-х tail твой лучший друг здесь поскольку docker images а также docker ps оба порядка по дате, мы можем просто использовать tail выделить все, кроме первых трех, и удалить их:

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

Запустите его вместе со своими сценариями развертывания (или локально), чтобы всегда сохранять достаточно изображений для удобного отката, не занимая слишком много места и не загромождая старые изображения.

Лично я могу хранить только один контейнер на своей производственной коробке в любое время, но вы можете сделать то же самое с контейнерами, если хотите больше:

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

Наконец, в моем упрощенном примере мы имеем дело только с одним репозиторием за раз, но если бы у вас было больше, вы можете просто немного сложнее с той же идеей. Скажем, я просто хочу сохранить последние три изображения из some_repo / some_image. Я могу просто смешаться grep а также awk и быть на моем пути:

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

Опять же, та же идея применима и к контейнерам, но вы получите ее к этому моменту, поэтому я перестану приводить примеры.

Посмотреть все существующие изображения:

      docker images -a

Посмотреть все существующие контейнеры:

      docker ps -a

Удалить одно изображение:

      docker images -a
docker rmi <IMAGE_ID>

Остановить один контейнер:

      docker ps -a
docker stop <CONTAINER_ID>

Остановить несколько контейнеров:

      docker ps -a
docker stop <CONTAINER_ID1> <CONTAINER_ID2>

Удалить один контейнер:

      docker ps -a
docker rm <CONTAINER_ID>

Удалить несколько изображений:

      docker images -a
docker rmi <IMAGE_ID1> <IMAGE_ID2>

Удалить несколько остановленных контейнеров:

      docker ps -a
docker rm <CONTAINER_ID1> <CONTAINER_ID2>

Удалите контейнеры и образы одной командой:

      docker rm $(docker ps -a -q) && docker rmi -f $(docker images -a -q)

Чтобы обрезать все контейнеры:

      docker container prune

Использование:

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

Он принудительно останавливается и удаляет все имеющиеся на месте контейнеры.

Я хотел добавить этот простой ответ, так как не видел его, и вопрос конкретно «старый», а не «все».

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

Настройте 24 часа на любой промежуток времени, в который вы хотите удалить контейнеры старше.

Удалить 5 самых старых контейнеров:

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

Посмотрите, сколько контейнеров осталось:

docker ps -aq | wc -l

Удалить все остановленные контейнеры.

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

Это удалит все остановленные контейнеры, получив список всех контейнеров с помощью docker ps -a -q и передав их идентификаторы в docker rm. Это не должно удалять любые запущенные контейнеры, и оно скажет вам, что не может удалить запущенный образ.

Удалить все непомеченные изображения

Теперь вы хотите очистить старые изображения, чтобы сэкономить место.

sudo docker rmi $ (изображения sudo docker -q --filter "dangling=true")

Новый способ: spotify / docker-gc сыграет свою роль.

 docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /etc:/etc spotify/docker-gc
  • Контейнеры, вышедшие более часа назад, удаляются.
  • Изображения, которые не принадлежат ни одному оставшемуся контейнеру после этого, удаляются

Он поддерживает параметры окружающей среды

Принудительное удаление изображений с несколькими тегами

 FORCE_IMAGE_REMOVAL=1

Принудительное удаление контейнеров

 FORCE_CONTAINER_REMOVAL=1 

Исключая недавно вышедшие контейнеры и изображения из сборки мусора

 GRACE_PERIOD_SECONDS=86400

Этот параметр также предотвращает удаление изображений, которые были созданы менее чем GRACE_PERIOD_SECONDS секунд назад.

Пробный прогон

 DRY_RUN=1

Очистка томов потерянных контейнеров 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)

удалить все изображения, связанные с не запущенными контейнерами Docker

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

очистка потерянных томов докера для докера версии 1.10.x и выше

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

На основе периода времени

 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
  1. Удалить все процессы докера:

    docker rm $(docker ps -a -q)
    
  2. Удалить конкретный контейнер:

    $ docker ps -a (lists all old containers)
    
    $ docker rm container-Id
    

Вы можете использовать следующую команду для удаления вышедших контейнеров:

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

Вот полный список действий по удалению старых изображений в Docker: Суть удаления старых контейнеров Docker и изображений.

Вы можете удалить только остановленные контейнеры. Останови их всех в начале

docker stop $(docker ps -a -q)

Тогда вы можете удалить

docker rm $(docker ps -a -q)

Попробуйте эту команду для очистки контейнеров и свисающих изображений.

docker system prune -f
#!/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

Основные шаги, чтобы остановить / удалить все контейнеры и изображения

  1. Перечислите все контейнеры

    docker ps -aq

  2. Остановите все работающие контейнеры

    docker stop $(docker ps -aq)

  3. Удалить все контейнеры

    docker rm $(docker ps -aq)

  4. Удалить все изображения

    docker rmi $(docker images -q)

Примечание. Сначала необходимо остановить все работающие контейнеры, прежде чем удалять их. Также перед удалением изображения вы должны остановить и удалить зависимые контейнеры.

Я всегда использую docker rmi $(docker ps -a -q) удалить все изображения.

Вы можете удалить каталог /var/lib/docker/graph когда docker rmi не удалось.

Чтобы удалить ВСЕ остановленные контейнеры докеров, запустите:-

$ docker container prune

Вы должны быть осторожны с этой командой, поскольку она удаляет все остановленные контейнеры без разбора, поэтому убедитесь, что нет остановленных / неиспользуемых в настоящее время контейнеров, которые вы можете использовать.

Более точная альтернатива - удалить контейнер по идентификатору. Вам нужно сначала перечислить остановленные контейнеры, используя эту команду:-

docker ps --filter "status=exited"

Затем вы скопируете идентификатор контейнера, который хотите удалить. После этого выполните следующую команду, которая удаляет один контейнер,

docker container rm <container ID>

или один ниже, чтобы удалить сразу несколько контейнеров, запустив:-

docker container rm <container ID 1> <container ID 2> <container ID n>

Я использую следующие команды для удаления Exited и перезапуска Docker-контейнеров

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

Используя команду ниже, чтобы удалить изображения с именем none

docker image rm --force $(docker image ls  |grep none |awk '{print $3}')
Другие вопросы по тегам