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

Зміст:
- Де Docker зберігає дані
- Як перевірити, що саме займає місце
- Видалення контейнерів
- Видалення шаблонів
- Видалення volume
- Очищення build cache
- Повне очищення Docker
- Docker Compose
- Логи контейнерів
- Рекомендації для VPS
- Висновки
Багатьом знайома ситуація, коли на сервері раптом закінчується вільне місце за рахунок того, що 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 Автор: Олександр Ровник
|
|
Рекомендовані статті на тему:
- Рішення для підвищення продуктивності роботи PHP-додатку
- Організація централізованого зберігання журналів вузлів під управлінням ОС Ubuntu
- Мовні конструкції та внутрішні змінні Bash
- Debian 10. Состоялся официальный релиз
- Чому один і той самий сайт може працювати швидко на одному VDS, але повільно – на іншому

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