Как заставить Docker выполнить чистую сборку без использования кэша?
Я собираю Docker образ с помощью следующей команды:
docker build -t u12_core -f u12_core .
Когда я пересобираю образ с той же командой, Docker использует кэш сборки, как показано в выводе ниже:
Step 1 : FROM ubuntu:12.04
---> eb965dfb09d2
Step 2 : MAINTAINER Pavan Gupta <pavan.gupta@gmail.com>
---> Using cache
---> 4354ccf9dcd8
Step 3 : RUN apt-get update
---> Using cache
---> bcbca2fcf204
Step 4 : RUN apt-get install -y openjdk-7-jdk
---> Using cache
---> 103f1a261d44
Step 5 : RUN apt-get install -y openssh-server
---> Using cache
---> dde41f8d0904
Step 6 : RUN apt-get install -y git-core
---> Using cache
---> 9be002f08b6a
Step 7 : RUN apt-get install -y build-essential
---> Using cache
---> a752fd73a698
Step 8 : RUN apt-get install -y logrotate
---> Using cache
---> 93bca09b509d
Step 9 : RUN apt-get install -y lsb-release
---> Using cache
---> fd4d10cf18bc
Step 10 : RUN mkdir /var/run/sshd
---> Using cache
---> 63b4ecc39ff0
Step 11 : RUN echo 'root:root' | chpasswd
---> Using cache
---> 9532e31518a6
Step 12 : RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
---> Using cache
---> 47d1660bd544
Step 13 : RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
---> Using cache
---> d1f97f1c52f7
Step 14 : RUN wget -O aerospike.tgz 'http://aerospike.com/download/server/latest/artifact/ubuntu12'
---> Using cache
---> bd7dde7a98b9
Step 15 : RUN tar -xvf aerospike.tgz
---> Using cache
---> 54adaa09921f
Step 16 : RUN dpkg -i aerospike-server-community-*/*.deb
---> Using cache
---> 11aba013eea5
Step 17 : EXPOSE 22 3000 3001 3002 3003
---> Using cache
---> e33aaa78a931
Step 18 : CMD /usr/sbin/sshd -D
---> Using cache
---> 25f5fe70fa84
Successfully built 25f5fe70fa84
Кэш указывает, что aerospike установлен, но я не могу найти его внутри контейнеров, созданных из этого образа. Как заставить Docker полностью пересобрать образ без использования кэша?
Чтобы заставить Docker выполнить полностью чистую сборку без использования кэша, можно использовать флаг --no-cache. Просто добавьте этот флаг к вашей существующей команде:
docker build --no-cache -t u12_core -f u12_core .
Это заставит Docker пересобрать каждый слой с нуля, игнорируя любые закэшированные слои, что должно решить вашу проблему с aerospike, который не был установлен должным образом, несмотря на то, что кэш указывал на это.
Содержание
- Использование флага --no-cache
- Понимание кэша сборки Docker
- Альтернативные методы для чистых сборок
- Устранение проблем, связанных с кэшем
- Лучшие практики для сборок Docker
Использование флага --no-cache
Самый прямой способ заставить Docker выполнить чистую сборку - это использование флага --no-cache с вашей командой docker build:
docker build --no-cache -t u12_core -f u12_core .
Этот флаг указывает Docker полностью игнорировать кэш и пересобрать каждый слой с нуля. При использовании этого флага в выводе сборки вы не увидите сообщений “Using cache” - каждый шаг будет выполняться так, будто это первая сборка.
Важные моменты:
- Время сборки: Чистые сборки занимают значительно больше времени, так как Docker должен выполнить каждую команду в вашем Dockerfile
- Использование сети: Каждая команда RUN, которая загружает пакеты (например,
apt-get update), будет повторно загружать всё - Хранилище: Контекст сборки и промежуточные образы будут использовать больше временного хранилища
Вот как будет отличаться вывод с --no-cache:
Step 1/18 : FROM ubuntu:12.04
---> eb965dfb09d2
Step 2/18 : MAINTAINER Pavan Gupta <pavan.gupta@gmail.com>
---> Running in a5f8c3d2e1f4
---> 4354ccf9dcd8
Step 3/18 : RUN apt-get update
---> Running in b7c9d4e5f6g7
---> bcbca2fcf204
Обратите внимание, что вместо сообщений “Using cache” вы увидите сообщения “Running in [container-id]” для каждого шага, который использует кэш.
Понимание кэша сборки Docker
Docker использует кэш сборки для ускорения сборок, сохраняя промежуточные результаты. Понимание того, как это работает, помогает понять, почему может возникать ваша проблема с aerospike и как правильно её решить.
Как работает кэш Docker
Docker собирает образы слой за слоем. Для каждого шага в вашем Dockerfile Docker проверяет, может ли он использовать закэшированный слой вместо пересборки:
- Поиск в кэше: Docker ищет соответствующий слой в кэше
- Расчёт контрольной суммы: Docker рассчитывает контрольную сумму для контекста сборки и Dockerfile
- Попадание в кэш: Если контрольная сумма совпадает, Docker использует закэшированный слой
- Пропуск кэша: Если что-то отличается, Docker пересобирает этот слой
Почему может возникать ваша проблема с Aerospike
Проблема, которую вы описываете - когда кэш указывает на то, что aerospike установлен, но на самом деле он недоступен в контейнерах - обычно возникает при:
- Частичной сборке: Предыдущая сборка завершилась с ошибкой на полпути, оставив частичную установку
- Несоответствии в кэше: Кэш повреждён или несогласован
- Изменениях в контексте сборки: Что-то в контексте сборки изменилось без обновления Dockerfile
Альтернативные методы для чистых сборок
Хотя --no-cache является наиболее прямым подходом, существуют и другие методы для достижения чистых сборок в разных сценариях.
Метод 1: Изменение Dockerfile
Иногда можно запустить чистую сборку, сделав небольшое, незначительное изменение в Dockerfile:
# Добавьте комментарий или измените комментарий
# Это заставит Docker пересобрать с этого момента
RUN echo "Время сборки: $(date)" > /dev/null && \
apt-get update && \
apt-get install -y openjdk-7-jdk
Метод 2: Ручная очистка кэша
Вы можете полностью очистить кэш сборки Docker:
# Очистка всех неиспользуемых объектов, включая кэш сборки
docker system prune -a
# Или специфическая очистка кэша сборки
docker builder prune -a
Предупреждение: Это удаляет все неиспользуемые объекты и значительно увеличит время последующих сборок.
Метод 3: Многоэтапные сборки
Для сложных сборок рассмотрите использование многоэтапных сборок, чтобы избежать проблем с кэшем между разными фазами сборки:
# Этап сборки
FROM ubuntu:12.04 as builder
RUN apt-get update && apt-get install -y build-essential
COPY . /app
RUN cd /app && make build
# Финальный этап
FROM ubuntu:12.04
COPY --from=builder /app/dist /app/dist
# ... остальная конфигурация
Устранение проблем, связанных с кэшем
Конкретное решение для вашей проблемы с Aerospike
Поскольку вы сталкиваетесь с проблемами с aerospike, который не установлен должным образом, несмотря на то, что кэш указывает на это, вот систематический подход:
- Выполните чистую сборку с
--no-cache - Внимательно проверьте лог сборки на наличие сообщений об ошибках на этапах установки aerospike
- Проверьте установку внутри контейнера сборки:
# Сборка с --no-cache
docker build --no-cache -t u12_core_fixed -f u12_core .
# Запустите контейнер и проверьте, установлен ли aerospike
docker run -it --rm u12_core_fixed bash -c "which aerospike-server && dpkg -l | grep aerospike"
- Проверьте финальный образ, чтобы убедиться, что все файлы присутствуют:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock alpine docker run --rm -v $(pwd):/target u12_core bash -c "ls -la /opt/aerospike* 2>/dev/null || echo 'Aerospike не найден'"
Распространенные проблемы с кэшем и их решения
| Проблема | Решение |
|---|---|
| Поврежденный кэш | Используйте --no-cache или docker builder prune |
| Частичные сборки | Всегда проверяйте логи сборки на полное завершение |
| Отсутствующие файлы в финальном образе | Используйте команды RUN для проверки установки в процессе сборки |
| Недействительность кэша | Изменяйте Dockerfile или используйте аргументы сборки с метками времени |
Лучшие практики для сборок Docker
Когда использовать --no-cache
Используйте --no-cache, когда:
- Вы отлаживаете проблемы сборки
- Вы подозреваете повреждение кэша
- Вы внесли значительные изменения в Dockerfile или контекст сборки
- Вам необходимо обеспечить полностью свежую сборку
Оптимизация сборок при сохранении надёжности
Чтобы избежать ненужных чистых сборок при сохранении надёжности:
-
Используйте конкретные версии пакетов в вашем Dockerfile:
dockerfileRUN apt-get install -y aerospike-server-community=3.12.1 -
Добавьте этапы проверки сборки:
dockerfileRUN dpkg -l | grep aerospike || (echo "Установка Aerospike не удалась" && exit 1) -
Используйте аргументы сборки для контроля версий:
dockerfileARG AEROSPIKE_VERSION=3.12.1 RUN apt-get install -y aerospike-server-community=${AEROSPIKE_VERSION} -
Очищайте apt кэш в том же слое:
dockerfileRUN apt-get update && apt-get install -y \ openjdk-7-jdk \ aerospike-server-community && \ rm -rf /var/lib/apt/lists/*
Мониторинг здоровья сборки
Добавьте команды проверки для обеспечения правильной работы ваших сборок:
# Добавьте это для проверки установки aerospike
RUN aerospike-server --help >/dev/null 2>&1 || \
(echo "Сервер Aerospike не установлен должным образом" && exit 1)
Это вызовет сбой сборки, если aerospike не установлен должным образом, предотвращая создание сломанных образов.
Заключение
Чтобы заставить Docker выполнить чистую сборку без использования кэша, просто добавьте флаг --no-cache в команду сборки: docker build --no-cache -t u12_core -f u12_core .. Это пересоберет каждый слой с нуля и решит вашу проблему с установкой aerospike.
Ключевые выводы:
- Используйте
--no-cacheдля отладки и когда подозреваете повреждение кэша - Понимайте, как работает кэширование слоев Docker для лучшего устранения проблем сборки
- Рассмотрите альтернативные методы, такие как изменение вашего Dockerfile или ручная очистка кэша
- Добавьте этапы проверки в ваш Dockerfile для раннего обнаружения сбоев установки
- Для сложных сборок используйте многоэтапные сборки и конкретные версии пакетов для поддержания надёжности
Наиболее немедленным решением для вашей конкретной проблемы является запуск сборки с --no-cache и тщательный анализ вывода для обеспечения успешного завершения установки aerospike на этот раз.