• База знань
  • /
  • Блог
  • /
  • Wiki
  • /
  • ONLINE CHAT
+380 (44) 364 05 71

Стаття також доступна російською (перейти до перегляду).

Покрокова інструкція з очищення Docker: як видалити images, контейнери та volumes і звільнити місце на сервері

Зміст:

Багатьом знайома ситуація, коли на сервері раптом закінчується вільне місце за рахунок того, що Docker займає десятки гігабайт і постійно «розширюється». Перевірка системи за допомогою команд docker system df та df -h при цьому надає суперечливі результати, і тому користувач не розуміє, що саме потрібно видаляти. Сутність проблеми полягає у складній будові файлової системи (layered filesystem) та особливостях організації збереження даних у Docker. Володіючи базовою інформацією по механізмам зберігання даних у Docker, можна запобігти виникненню критичної ситуації та підвищити продуктивність системи. Розглянемо базові поняття, а також методи аналізу та очищення Docker від зайвих та / або невикористаних даних. 

Рекомендуємо ознайомитись зі статтею "Закінчується місце на VPS: як знайти, що займає диск в Ubuntu".     

Де Docker зберігає дані

У середовищі Linux стандартним місцем для зберігання всіх даних є кореневий каталог /var/lib/docker/. Каталог містить ряд підкаталогів для різних типів даних. Розглянемо ключові з них:

Overlay2 – стандартний драйвер сховища в Linux або storage driver, котрий керує зберіганням контейнерів та шаблонів на Docker-вузлі.

Containers – контейнери є автономними додатками або сервісами, тимчасово створеними на базі шаблонів image. У контексті Linux вони є ізольованими процесами, котрі можна у будь-який момент часу створити, запустити, зупинити або видалити.

Volumes – томи визначають місце зберігання даних (локальне або зовнішнє), незалежне від файлової системи контейнеру.

Buildkit – кеш збірки або Build Cache, котрий генерується під час процесу збирання шаблону.

Виходячи з наведених визначень, зокрема, можна зробити наступні висновки:

  • Видалення контейнеру не видаляє шаблону, на базі котрого він створений, а лише ліквідує тимчасово створений ізольований процес;

  • Видалення шаблону не видаляє volume, а лише ліквідовує дані та контекст збірки визначеного контейнерного середовища;

  • Під час роботи контейнерів, як і будь-яких інших процесів виконується логування, і, відповідно, логи контейнерів також займають на диску місце.  

Як перевірити, що саме займає місце

Для демонстрації та кращого розуміння процесу виявлення та видалення зайвих даних нам знадобиться власний Docker-шаблон. Створимо його за допомогою наведених нижче команд.

Створимо каталог, котрий у подальшому стане контекстом збірки для нашого шаблону:

$ mkdir dock
$ cd dock

У каталозі dock створимо файл із ім’ям dockerfile та розмістимо в ньому наведений нижче код:

$ sudo nano dockerfile

Після збереження внесених змін зберемо шаблон із ім’ям my_app:v1за допомогою команди:

$ sudo docker build . -t my_app:v1

Тут опція -t дозволяє вказати ім’я шаблону, а символ «.» перед нею вказує на поточний каталог у якості контексту збірки. .

Скорочений вихід команди:

[+] Building 79.9s (7/7) FINISHED                                                                                  docker:default
 => [internal] load build definition from dockerfile                                                                  0.7s
 => => transferring dockerfile: 137B                                                                                     0.0s
 => [internal] load metadata for docker.io/library/python:latest                                         3.4s
 => [internal] load .dockerignore                                                                                            0.6s
 => => transferring context: 2B                                                                                             0.0s
 => [1/3] FROM docker.io/library/python:latest@sha256:151ab3571dad616bb031052e86411e2165295c7f67ef27206852203e854bcd12                                                                                                     67.3s
 => => resolve
.....................................................................................................................................
....................................................................................................................................
sha256:48adf976412b12c3683dd37d9d0ccd7e8dc20a70e8a80f20d35ddd70bc088838    0.1s
 => => naming to docker.io/library/my_app:v1                                                                     0.0s
 => => unpacking to docker.io/library/my_app:v1                                                                0.4s

Переглянути список шаблонів, котрі є у нашій системі можна за допомогою команди: 

$ sudo docker image ls
IMAGE                 ID                              DISK USAGE   CONTENT SIZEEXTRA
hello-world:latest05813aedc15f          25.9kB           9.52kB               U
my_app:v1          48adf976412b          1.61GB             414MB

Окрім створеного нами my_app:v1 тут також присутній шаблон hello-world:latest.

Стовпці DISK USAGE та CONTENT SIZE надають інформацію про зайняте шаблонами місце на диску загалом та за розміром контенту.

Нерідко може стати корисною детальна інформація по кожному з шарів шаблону, зокрема, для визначення місця, котрі вони займають. Провести такий аналіз можна за допомогою команд docker history та docker inspect.

Продемонструємо це:

$ sudo docker history my_app:v1
IMAGE      CREATED       CREATED BY                       SIZE     COMMENT
48adf976412b   41 hours ago   CMD ["python" "main.py"]     0B    buildkit.dockerfile.v0
<missing>  41 hours ago   WORKDIR /usr/myproject/    4.1kB buildkit.dockerfile.v0
<missing>  41 hours ago   RUN /bin/sh -c mkdir -p /usr/myproject/ # bu…   12.3kBbuildkit.dockerfile.v0
<missing>  11 days agoCMD ["python3"]                     0B    buildkit.dockerfile.v0
<missing>  11 days agoRUN /bin/sh -c set -eux;  for src in idle3 p…   16.4kB    buildkit.dockerfile.v0
<missing>  11 days agoRUN /bin/sh -c set -eux;   savedAptMark="$(a…   82.2MB    buildkit.dockerfile.v0
<missing>  11 days agoENV PYTHON_SHA256=a97d5549e9ad81fe17159ed02c…   0B    buildkit.dockerfile.v0
<missing>  11 days agoENV PYTHON_VERSION=3.14.3                      0B    buildkit.dockerfile.v0
<missing>  11 days agoRUN /bin/sh -c set -eux;  apt-get update;  a…   19.9MBbuildkit.dockerfile.v0
<missing>  11 days agoENV PATH=/usr/local/bin:/usr/local/sbin:/usr…   0B    buildkit.dockerfile.v0
<missing>  13 days agoRUN /bin/sh -c set -ex;  apt-get update;  ap…   694MB buildkit.dockerfile.v0
<missing>  13 days agoRUN /bin/sh -c set -eux;  apt-get update;  a…   202MB buildkit.dockerfile.v0
<missing>  13 days agoRUN /bin/sh -c set -eux;  apt-get update;  a…   65MB  buildkit.dockerfile.v0
<missing>  2 weeks ago# debian.sh --arch 'amd64' out/ 'trixie' '@1…   134MB debuerreotype 0.17

За допомогою команди history можна отримати інформацію про ідентифікатор шаблону; час його створення; команди, котрі використовувались для кожного шару; розмір; повідомлення від драйвера кеша.

Іншу інформацію можна отримати за допомогою команди inspect:

$ sudo docker inspect --format '{{json .RootFS.Layers}}' my_app:v1

Тут ми форматували вихід команди за допомогою користувацького шаблону json. Результати виконання наведені нижче.

["sha256:d16566b6c5a6bd5c45da221a2fc94937d8d503c920c8627f154a2f8a57537da4","sha256:3dc84f17a3999c0ab5fc2ef9c360dde19a663f4c22cbcec9e1b507fa3ca4222d","sha256:222b6d2e7e9f54c3f0013d281f37408ecd1c690fba9b7230138187da42415cf6","sha256:05f2b78449c812b7301720f11a1a2e4c2b8fc0229e2433b9aa0b619f2cade10a","sha256:96fc0777a58100b18b903a7e88704df66e8e9272647a732271287def69586a9a","sha256:5b1da75dbec265d08f3518d63dc6ec9317d4196024302d4724ce775648b5b362","sha256:c2bc34f33e3a3d9fc75b76bc4bf8c29b62e7c9ccc26f0ce610487f7efa0eb1bc","sha256:d990813ef0375de95e633fc39b5ec62185a4594b42dcf4b3306c8e58e12ebe08","sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"]

Ми отримали дев’ять шарів шаблону my_app:v1 у вигляді хешей SHA256. Кожен шаблон має криптографічний хеш або дайджест, котрий заснований на вмісту його шарів. При відправленні або завантаженні шаблону дайджест використовується для контролю його цілісності.  

Продивитися споживання пам’яті Docker у файловій системі хоста можна так:

$ sudo docker system df 
TYPE              TOTAL      ACTIVE       SIZE           RECLAIMABLE
Images            2              1                  1.611GB           104.6kB (0%)
Containers      1              0                 4.096kB            4.096kB (100%)
Local Volumes 0              0                     0B                     0B
Build Cache   11            0                 1.611GB          12.29kB

Команда надає інформацію про використання диску Docker у кількох категоріях: шаблони, контейнери, локальні томи та кеш збірки.

Із результатів можна зрозуміти, що більша частина дискового простору може бути відновлена та повернена хост-комп’ютеру, оскільки не всі ці дані потрібні Docker. Особливо це стосується вмісту Build Cache, котрий займає стільки ж місця, скільки всі шаблони разом.

Та ж сама команда із опцією -v надає результати у більш розширеному форматі:

$ sudo docker system df -v
Images space usage:
REPOSITORYTAG   IMAGE ID   CREATED    SIZE  SHARED SIZE   UNIQUE SIZE   CONTAINERS
my_app    v1    48adf976412b   42 hours ago   1.61GB    0B        1.611GB   0
hello-world   latest05813aedc15f   6 months ago   25.9kB    0B        25.9kB    1
Containers space usage:
CONTAINER ID   IMAGE     COMMANDLOCAL VOLUMES   SIZE      CREATED   STATUS               NAMES
e9420d894d77   hello-world   "/hello"   0           4.1kB 12 days ago   Exited (0) 12 days ago   cool_cray
Local Volumes space usage:
VOLUME NAME   LINKS SIZE
Build cache usage: 1.611GB
CACHE ID  CACHE TYPE  SIZE               CREATED    LAST USED USAGE     SHARED
ocbvf7mtbt5v   regular             183MB 42 hours ago   42 hours ago 1            true
h0ybalxd04nz   regular             90.6MB42 hours ago   42 hours ago 1            true
s7vqc0xwa076   regular           270MB 42 hours ago   42 hours ago  1            true
3264z8l74jf5regular             930MB 42 hours ago   42 hours ago   1           true
y73i1rof03sxregular                       26MB    42 hours ago   42 hours ago   1           true
v6j7jnhvxxa2   regular                       112MB             42 hours ago   42 hours ago    1            true
som9zatjipwv   regular                    16.5kB           42 hours ago   42 hours ago      1           true
a7bkawsvjwdh   regular                  4.13kB          42 hours ago   42 hours ago      1           true
u2hirnr07j61   source.local             8.19kB            42 hours ago   42 hours ago      1           false
xa5bfnuj4lpg   source.local           4.1kB              42 hours ago   42 hours ago        1          false
dfyl3902roiu   regular                  16.6kB            42 hours ago   42 hours ago       1          true

Також корисною може стати команда, котра виводить інформацію про використання дискового простору стандартними та монтованими каталогами Linux:

$ sudo df -h
Filesystem  Size     UsedAvail Use%    Mounted on
udev           2.4G 0         2.4G  0%         /dev
tmpfs         480M1.8M   478M 1%    /run
/dev/vda2   38G      7.7G   29G    22%      /
tmpfs         2.4G 0          2.4G   0%   /dev/shm
tmpfs         5.0M 0          5.0M  0%  /run/lock
tmpfs         480M 0         480M 0%  /run/user/0

Видалення контейнерів

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

В цьому можна легко переконатися. Наприклад, після створення нами двох контейнерів на базі наявних шаблонів, місця на диску для них стало витрачатися більше. Перевірити це можна за допомогою вже відомої нам команди:

$ sudo docker system df
TYPE              TOTAL      ACTIVE       SIZE           RECLAIMABLE
Images            2            2                  1.611GB      1.611(100%)
Containers      3              0                 86.02kB       86.02kB (100%)
Local Volumes 0              0                 0B               0B
Build Cache   11            0                 1.611GB     12.29kB

Першого разу контейнери займали лише 4.096 kB, а тепер 86.02 kB, тобто, в 20 разів більше. Видаливши зайві, ми звільнимо місце на диску. Але для цього ми повинні знати ID або ім’я контейнеру.

Вивести список всіх наявних у системі контейнерів (активних і зупинених) можна за допомогою команди: 

$ sudo docker ps -a

CONTAINER ID   IMAGE         COMMAND        CREATED      STATUS                  PORTS NAMES

074b6bc4f4a0my_app:v1 "python main.py"   17 minutes ago   Exited (2) 17 minutes ago         focused_jemison

bd59f1999239   hello-world   "/hello"       24 minutes ago   Exited (0) 24 minutes ago         hardcore_shirley

e9420d894d77   hello-world   "/hello"       12 days ago  Exited (0) 4 minutes ago          cool_cray

Також можна відфільтрувати контейнери по потрібному статусу, наприклад, exited (виконаний вихід). У такому разі команда ps буде виглядати наступним чином:

$ sudo docker ps -a -f status=exited

Тут ми використали опцію -f для виконання операції фільтрування.

Тепер ми зможемо контролювати ситуацію.

Наприклад, видалимо контейнер із статусом exited, створений на базі шаблону my_app:v1.

Зупиняємо його:

$ sudo docker stop 074b6bc4f4a0

У разі успішного виконання на виході отримаємо його ідентифікатор: 

074b6bc4f4a0

Видаляємо:

$ sudo docker rm 074b6bc4f4a0
074b6bc4f4a0

Видалити всі зупинені контейнери можна за допомогою команди:

$ sudo docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
5e34c067f59c27fe8eb196ee3d5fba09d87b246ebcf00368db51c7f62d749602
6e3f084c1f8097afe82e5241f11811476b7a488f3b1059d1d644ee9e87ad0a8a
00a688034a328c410cb02ea2ee48e800d97e5251aed221c465bb663c9414a3f3
bd59f19992393c4365f3514adc86a657ea940e7618412061616e3d7fb46aaca6
e9420d894d775e01ae0a041d2f11a083987d2f93256fecc458916db1977c7725
Total reclaimed space: 94.21kB

Одним із шляхів оптимізації витрат дискового простору може стати використання опції –rm при запуску контейнерів, котра забезпечує їх автоматичне видалення на виході.

Приклад команди. 

$ docker run --rm <ім’я шаблону>

Видалення шаблонів

З часом у процесі роботи накопичується чимало шаблонів, котрі не використовуються (unused) та тих, котрі знаходяться у підвішеному стані або, як кажуть, завислі шаблони (dangling).

Перші з них не використовуються жодним контейнером (активним або зупиненим). Другі не мають тегу та ім’я репозиторію і у списках шаблонів відображаються як <none>:<none>. Всі вони разом можуть займати значний об’єм дискового простору і тому потребують видалення.  

Слід зазначити, що видалення будь-яких шаблонів повинно відбуватися лише після видалення контейнерів, котрі їх використовують. У іншому випадку операція не буде виконана.

Наведемо приклади деяких команд.

Видалення dangling-шаблонів: 

$ docker images -f dangling=true
$ docker image prune

Видалення визначеного шаблону за його ID:

$ docker rmi <image id>

Видалення всіх шаблонів, до котрих не прив’язаний жодний контейнер (dangling + unused):

$ docker image prune –a 

При цьому команда видасть наступне повідомлення:

WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N]

Після підтвердження своєї згоди на видалення операція буде виконана.

Пошук та видалення за визначеним шаблоном за допомогою оператору grep:

$ docker images -a | grep "pattern"

Видалення volume

Томи є місцем зберігання даних та можуть бути декількох типів: анонімні, іменовані та Bind Mounts (пов’язані з хостом). Наведемо основні команди для роботи з томами.

Вивести список всіх зареєстрованих в системі томів. 

$ sudo docker volume ls

Результат може бути наступним:

#DRIVER        VOLUME NAME>
#local               b45436c7f8bab37c0bfe998f

Видалення одного або декількох томів за їх ім’ям, при умові, якщо вони не використовуються жодним контейнером:

$ docker volume rm [OPTIONS] VOLUME [VOLUME...]

Видалення всіх локальних томів, котрі не використовуються (Unused):

$ docker volume prune

Слід зазначити, що томи містять реальні дані, і тому їх видалення означає видалення даних проекту. Зокрема, вони можуть містити БД.

Очищення build cache

Переглядаючи результати виконання команди docker system df , ми вже звертали увагу, що вміст Build Cache займає на диску не менше місця, ніж всі наявні у системі шаблони (Build cache usage: 1.611GB). І це зрозуміло, оскільки кеш використовується для оптимізації продуктивності роботи Docker за рахунок кешування даних шаблонів. З іншого боку, це може перезавантажити диск, що особливо відчутно при частому виконанні операцій збірки. І тому необхідно періодично виконувати його очищення.

Розглянемо використання декількох команд.

Перша команда: 

$ sudo docker builder prune
WARNING! This will remove all dangling build cache. Are you sure you want to continue? [y/N]

Команда пропонує видалити всі dangling-дані кеша, котрі не прив’язані до жодного шаблону з тегом. Для їх видалення достатньо підтвердити операцію. 

Друга команда:

$ sudo docker builder prune -a

WARNING! This will remove all build cache. Are you sure you want to continue? [y/N] y

Команда виконує повне очищення кеша у разі підтвердження операції.

Повне очищення Docker

Продемонструємо використання декількох команд для повного очищення системи.  

$ sudo docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - unused build cache 
Are you sure you want to continue? [y/N] 

Команда видаляє всі зупинені контейнери; завислі шаблони; мережі, котрі не прив’язані до жодного контейнеру; дані кеша, котрі не використовуються. 

$ sudo docker system prune -a 
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all anonymous volumes not used by at least one container
  - all images without at least one container associated to them
  - all build cache 
Are you sure you want to continue? [y/N] 

Команда видаляє всі зупинені контейнери; всі мережі та шаблони, котрі не прив’язані до жодного контейнеру; увесь кеш збірки.

$ sudo docker system prune -a --volumes
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all anonymous volumes not used by at least one container
  - all images without at least one container associated to them
  - all build cache
Are you sure you want to continue? [y/N]

Команда видаляє всі зупинені контейнери; всі мережі, анонімні томи та шаблони, котрі не прив’язані до жодного контейнеру; увесь кеш збірки. 

Звертаємо увагу, що вказані команди, особливо останню, можна використовувати лише при умові чіткого розуміння наслідків їх виконання.

Docker Compose

Розглянемо ефективний інструмент для коректного завершення роботи та очищення мереж, контейнерів, томів та шаблонів Docker. Це команда docker Compose Down. На відміну від неї, команда docker Compose Stop лише зупиняє контейнери, не чіпаючи їх вмісту.

При застосуванні команди на практиці можна отримати наступний результат:

$ docker-compose down
Stopping docker-compose-mydemo_cont ... done
Removing docker-compose-mydemo_cont ... done
Removing network docker-compose-mydemo_def
Network testnet is external, skipping 

За результатами її виконання можна зробити наступні висновки:

  • Зупиняються та видаляються всі контейнери, визначені у файлі Docker Compose;

  • Видаляються всі внутрішні мережі, створені Docker Compose;

  • Томи з даними не видаляються.

Тепер застосуємо її з опцією --volumes (-v): 

$ docker-compose down --volumes
Stopping docker-compose-mydemo_cont ... done
Removing docker-compose-mydemo_cont ... done
Removing network docker-compose-mydemo_def
Network testnet is external, skipping
Removing volume docker-compose-mydemo_data

На відміну від попереднього варіанту, тепер також видаляються томи volume з даними, що робить команду більш кардинальною, і тому застосовувати її можна лише з великою обережністю..

Логи контейнерів

 

Як вже зазначалося, здійснюється логування кожного контейнеру, причому, як всередині, так і зовні на VPS-хості. Стандартний шлях для їх зберігання: /var/lib/docker/containers/.log.

З часом файли логів можуть значно збільшуватися в розмірах. Docker не має влаштованого механізму для їх очищення, а лише надає інструменти для їх перегляду, і тому необхідно застосовувати допоміжні механізми. Розглянемо декотрі з них. 

Вивести логи із визначеного контейнеру можна за допомогою команди:

$ docker logs -f <container ID>

При цьому контейнер може бути як активним, так і зупиненим.

Знайти файл логів на хості можна за допомогою команди:

$ docker container inspect <container ID> | grep LogPath

Вивести його вміст:

$ cat $(docker inspect --format "{{.LogPath}}" <container ID>)

Виконати очищення журналу логів без його видалення можна за допомогою команди:

$ sudo sh -c 'echo "" > $(docker inspect --format="{{.LogPath}}" <container ID>)'

Більшість драйверів логування Docker підтримують ротацію логів. Її можна увімкнути глобально або окремо для кожного контейнеру. Стандартно її глобальне включення та налаштування можна виконати у файлі /etc/docker/daemon.json. Приклад коду наведений нижче. 

{
"log-opts": {
    "max-size": "7m",
    "max-file": "3"
}
}

Тут логи контейнерів ротуються одразу після досягнення ними розміру 7 МБ. У кожний момент часу може зберігатися до трьох файлів. 

Після збереження внесених змін слід перезапустити головний процес Docker: 

$ systemctl restart docker

Рекомендації для VPS

Надамо основні рекомендації для запобігання забрудненню Docker-середовища вашого хоста:

  • Регулярно перевіряти docker system df;

  • Увімкнути лог-ротацію;

  • Використовувати --rm для тимчасових контейнерів;

  • Виносити дані на окремий диск;

  • Не видаляти вручу каталог /var/lib/docker

Висновки

Основні висновки по темі:

 Docker зберігає дані шарами;

  • Контейнери, шаблони та volumes – різні сутності;

  • Очищення повинно бути свідомим;

  • Важливо розуміти, що саме видаляється.

Підписуйтесь на наш Telegram-канал https://t.me/freehostua, щоб бути в курсі нових корисних матеріалів.

Дивіться наш канал YouTube на https://www.youtube.com/freehostua.

Ми у чомусь помилилися, чи щось пропустили?

Напишіть про це у коментарях, ми з задоволенням відповімо та обговорюємо Ваші зауваження та пропозиці

 

 
Дата: 20.02.2026
Автор: Олександр Ровник
Голосування

Авторам статті важлива Ваша думка. Будемо раді його обговорити з Вами:

comments powered by Disqus
navigate
go
exit
Дякуємо, що обираєте FREEhost.UA