Слои, или почему образы качаются быстрее, чем кажется:
Образ Docker это не один большой файл, а стопка слоёв, доступных только для чтения. Каждый слой хранит набор изменений файловой системы относительно предыдущего: поставили пакеты, скопировали файлы, поменяли конфиг. Драйвер хранения overlay2 склеивает слои в единую файловую систему, а при запуске контейнера сверху добавляется тонкий слой для записи.
Главная выгода в том, что слои переиспользуются. Если десять образов построены на debian:bookworm, базовые слои лежат на диске в одном экземпляре. То же самое при скачивании:
Код: Выделить всё
$ docker pull python:3.12-slim
3.12-slim: Pulling from library/python
8a628cdd7ccc: Already exists
71f0b9ab95c2: Pull complete
c57a1ad5ed9c: Pull complete
...
Код: Выделить всё
docker history python:3.12-slim
Теги, или что на самом деле значит latest:
Полное имя образа выглядит так: реестр/пространство/имя:тег. Когда вы пишете docker pull nginx, Docker молча разворачивает это в docker.io/library/nginx:latest. Здесь library это пространство официальных образов, а latest просто тег по умолчанию. Никакой магии "самой свежей версии" в нём нет: это обычная метка, которую автор образа может двигать куда угодно или вообще не обновлять.
Отсюда правило: везде, где конфигурация переживёт сегодняшний вечер, указывайте конкретный тег. nginx:1.27-alpine, postgres:16.4, node:22-slim. Тег latest годится для разового эксперимента в консоли, не больше.
Навесить на существующий образ ещё один тег можно командой docker tag, при этом ничего не копируется, создаётся просто ссылка. А если нужна железная гарантия неизменности, есть digest, хэш содержимого: docker pull nginx@sha256:... притянет ровно тот образ, байт в байт, даже если теги уехали.
Docker Hub:
Docker Hub это реестр по умолчанию, склад образов. Там лежат официальные образы (nginx, postgres, redis), за которыми следит команда Docker, и миллионы пользовательских в формате username/image. Чтобы выложить свой, нужен бесплатный аккаунт:
Код: Выделить всё
docker login
docker tag myapp:latest vasya/myapp:1.0.0
docker push vasya/myapp:1.0.0
У бесплатного доступа к Docker Hub есть лимиты на количество pull за период, и для анонимных запросов они считаются по IP. В офисе за общим NAT это всплывает внезапно посреди рабочего дня. Лечится авторизацией через docker login или зеркалом: в /etc/docker/daemon.json есть параметр registry-mirrors, ряд облачных провайдеров в СНГ держит публичные зеркала Docker Hub. Это же спасает, когда сам Hub из России открывается через раз.
Типичные грабли:
Первое. Тянуть образы по latest на сервере. Сегодня там одна версия, после очередного pull другая, и приложение падает. Фиксируйте версии тегом.
Второе. Считать, что docker pull обновит работающий контейнер. Нет, pull только скачивает образ, контейнер продолжает жить на старом. Контейнер нужно пересоздать: docker rm и docker run заново, в главе 8 за нас это будет делать Compose.
Третье. Путать тег и image ID. docker rmi myapp:1.0.0 удаляет только тег, и если на образ указывают другие теги, сам образ останется на диске. Сверяйтесь с колонкой IMAGE ID в docker image ls.
Четвёртое. Заливать в публичный реестр образ с секретами. Всё, что попало в слой, остаётся в истории, даже если удалить файл следующей инструкцией. Подробно об этом в главе 11.
Что усвоили: образ это стопка read-only слоёв, тег это подвижная метка, latest не значит свежий, а Docker Hub раздаёт и принимает образы послойно и с лимитами. В следующей главе напишем свой первый Dockerfile и увидим, как каждая инструкция превращается в слой.