Урок 8 из 8 · 20 мин · обновлено
Отладка, уборка и хорошие привычки
Что делать, если контейнер не запускается или сразу завершается: логи, коды выхода, docker exec и inspect. Частые ошибки и их причины, как освободить место на диске, хорошие привычки работы с Docker и что изучать дальше.
Если что-то пошло не так
Контейнер не запускается, сразу завершается или работает не так, как ждали. Порядок действий почти всегда один.
1. Посмотрите статус и код выхода:
docker ps -a
NAMES IMAGE STATUS
db postgres:16 Exited (1) 5 seconds ago
Exited (0) — программа завершилась сама, без ошибки: так ведёт себя hello-world. Любое другое число — завершилась с ошибкой.
2. Прочитайте логи:
docker logs db
docker logs --tail 20 db # только последние 20 строк
В примере выше база сообщит, что не задан пароль: контейнер запустили без -e POSTGRES_PASSWORD. Логи отвечают на большинство вопросов.
3. Посмотрите настройки контейнера:
docker inspect db
Команда выводит всё о контейнере в формате JSON: образ, переменные окружения, тома, порты, сеть. Длинно, но удобно, когда нужно убедиться, что том подключился куда нужно, а переменная действительно передана.
Заглянуть в работающий контейнер
docker exec выполняет команду внутри уже работающего контейнера. Открыть в нём командную строку:
docker exec -it web sh
Внутри можно посмотреть файлы, проверить настройки, а потом выйти командой exit. В отличие от docker run --rm -it, контейнер после выхода продолжит работать.
Теперь понятна команда из урока 5:
docker exec -it db psql -U postgres -c "SELECT * FROM notes;"
Внутри контейнера db запустить клиент psql от пользователя postgres и выполнить запрос из -c. Без -c откроется интерактивный psql, выход из него — \q.
Как потребляют ресурсы работающие контейнеры, покажет docker stats: процессор, память и сеть в реальном времени. Выход — Ctrl + C.
Частые ошибки
| Сообщение | Что значит и что делать |
|---|---|
port is already allocated |
порт занят другим контейнером или программой: выберите другой или остановите занявший |
Conflict. The container name "/web" is already in use |
контейнер с таким именем уже есть: удалите его или дайте новому другое имя |
pull access denied или manifest unknown |
опечатка в имени образа или такого тега нет: проверьте на Docker Hub |
Cannot connect to the Docker daemon |
Docker не запущен: откройте Docker Desktop или запустите службу на Linux |
no space left on device |
закончилось место: почистите неиспользуемое, см. ниже |
Уборка: где кончилось место
Образы, остановленные контейнеры и тома незаметно занимают гигабайты. Посмотреть, сколько:
docker system df
Убрать неиспользуемое — остановленные контейнеры, неиспользуемые сети, образы без тега и кэш сборки:
docker system prune
Команда спросит подтверждение и не тронет работающие контейнеры, образы с тегами и тома. Флаги делают её мощнее и опаснее: -a удалит все образы, по которым не создан ни один контейнер, а --volumes — неподключённые тома без имени вместе с данными. Перед ними проверьте, что ничего нужного не потеряется.
Убрать за курсом:
docker compose down -v # в папке my-site
docker volume rm pgdata # том из уроков 5–6
docker system prune
Хорошие привычки
- Фиксируйте версии:
postgres:16, а неpostgres. Поведение не изменится внезапно. - Начинайте с официальных образов и лёгких вариантов вроде
alpine. - Не кладите пароли и ключи в образ: всё, что попало в образ, может прочитать любой, кто его скачал. Секреты передают через переменные окружения или
.env. - Держите .dockerignore рядом с Dockerfile.
- Один процесс — один контейнер: база отдельно, сайт отдельно. Так их проще обновлять и перезапускать.
- Данные — в томах: всё, что записано внутри контейнера, исчезнет вместе с ним.
- Описывайте проект в compose.yaml, а не в памяти и заметках.
Что дальше
Вы умеете запускать готовые программы, собирать свои образы, хранить данные и поднимать стенд из нескольких контейнеров. Этого хватает для повседневной работы разработчика и тестировщика. Следующие темы, если Docker понравился:
- многоэтапная сборка — как делать маленькие образы для продакшена;
- CI/CD — автоматическая сборка образов и запуск тестов при каждом изменении кода;
- Kubernetes — запуск сотен контейнеров на многих серверах. Это уже профессия DevOps-инженера.
Все команды курса собраны в шпаргалке — сохраните её в закладки.
Попробуйте сами. Запустите PostgreSQL без пароля: docker run -d --name broken postgres:16. Выясните по логам, почему контейнер остановился, исправьте запуск и откройте командную строку внутри работающей базы. Затем уберите за собой.
Решение
docker run -d --name broken postgres:16
docker ps -a # статус Exited (1)
docker logs broken # база просит задать POSTGRES_PASSWORD
docker rm broken
docker run -d --name fixed -e POSTGRES_PASSWORD=secret postgres:16
docker exec -it fixed sh
Внутри контейнера выполните psql -U postgres, затем \q и exit. Уборка:
docker rm -f fixed
У контейнера fixed нет тома с именем, поэтому Docker создал для данных анонимный том — у него вместо имени длинный ID. Такие тома убирает docker volume prune.
Мини-тест: проверьте себя
Закрепите урок: несколько вопросов, разбор ответов — в конце.
-
Контейнер запустился и сразу остановился. С чего начать?
Программа почти всегда пишет в журнал, почему завершилась. Код выхода подсказывает: 0 — завершилась сама, другое число — с ошибкой.
-
Чем docker exec отличается от docker run?
exec — способ заглянуть внутрь работающего контейнера: проверить файлы, выполнить запрос к базе.
-
Что опасного в команде docker system prune -a --volumes?
Без флагов prune убирает только явный мусор. С -a удаляются все образы без контейнеров, с --volumes — неподключённые тома без имени, вместе с данными.