Как заставить docker-compose всегда заново создавать контейнеры из свежих изображений?

200

Мои образы докеров создаются на CI-сервере Jenkins и помещаются в наш личный реестр Docker. Моя цель состоит в том, чтобы обеспечить среду с docker-compose, которая всегда запускает исходное состояние образов.

В настоящее время я использую docker-compose 1.3.2, а также 1.4.0 на разных машинах, но ранее мы также использовали более старые версии.

Я всегда использовал docker-compose pull && docker-compose up -dкоманды, чтобы получить свежие изображения из реестра и запустить их. Я полагаю, что мое предпочтительное поведение работало как ожидалось до определенного момента времени, но с тех пор docker-compose upначал перезапускать ранее остановленные контейнеры вместо того, чтобы каждый раз запускать изначально созданные образы.

Есть ли способ избавиться от этого поведения? Может ли это быть способом, который подключен в файле конфигурации docker-compose.yml, чтобы он не зависел от того, чтобы «не забывать» что-то в командной строке при каждом вызове?

пс. Помимо поиска пути к достижению моей цели, я также хотел бы узнать немного больше о предыстории этого поведения. Я думаю, что основная идея Docker заключается в создании неизменной инфраструктуры. Текущее поведение docker-compose, похоже, просто противоречит этому подходу ... или я здесь упускаю некоторые моменты?

Кристоф Йожса
источник

Ответы:

235

docker-compose up --force-recreateэто один из вариантов, но если вы используете его для CI, я бы начал сборку с docker-compose rm -fостановки и удаления контейнеров и томов (затем следовал за ним с помощью pull и up).

Это то, что я использую:

docker-compose rm -f
docker-compose pull
docker-compose up --build -d
# Run some tests
./tests
docker-compose stop -t 1

Причина, по которой контейнеры воссоздаются, заключается в том, чтобы сохранить любые тома данных, которые могут быть использованы (и это также делает upих намного быстрее).

Если вы занимаетесь КИ, вы этого не хотите, поэтому просто удалив все, вы получите то, что хотите.

Обновление: использование, up --buildкоторое было добавлено в docker-compose1.7

dnephin
источник
1
Да, на самом деле это то, что я делаю в CI. Не уверен, почему я не упомянул об этом ...
Адриан Муат
@dnephin docker-compose run -dне существует? Вы хотите сказать docker-compose up -dнет?
Гийом Винсент
2
если вы бежите docker-compose pullраньше, docker-compose rm -fвы можете сэкономить еще больше времени
stephanlindauer
2
Что делает флаг -d в конце?
Дэвид Дж. Дэвис
3
«-d Отдельный режим: запускать контейнеры в фоновом режиме»,
dnephin
137

Единственное решение, которое работало для меня, было этой командой:

docker-compose build --no-cache

Это автоматически извлечет свежее изображение из репозитория и не будет использовать версию кеша, которая была предварительно собрана с какими-либо параметрами, которые вы использовали ранее.

davidbonachera
источник
1
Кроме того, в Windows 10 это может помочь установить DNS-сервер в настройках с Автоматически на Фиксированный или с Фиксированного на Автоматический.
qräbnö
2
У меня работала над сборкой OS X с Docker-Comopse версии 2.
RoboBear
1
Работал на OS X докер.
HelloWorld
56

Согласно текущей официальной документации, существует сокращение, которое останавливает и удаляет контейнеры, сети, тома и образы, созданные up, если они уже остановлены или частично удалены и т. Д., То это тоже поможет:

docker-compose down

Тогда, если у вас есть новые изменения в ваших изображениях или Dockerfiles, используйте:

docker-compose build --no-cache

В заключение:docker-compose up

В одной команде: docker-compose down && docker-compose build --no-cache && docker-compose up

Виктор Тимофей
источник
2
docker-compose build --no-cacheнужен только если есть изменения в Dockerfiles.
Виктор Тимофей
Действительно, Виктор. Спасибо! Я подумал, что это также необходимо после обновления модуля / приложения, которое выполняется при запуске контейнера. В этих случаях перед запуском docker-compose upнеобходимо перестроить сервисы с помощью docker-compose build.
ivanleoncz
18

Вы можете перейти --force-recreateк docker compose up, который должен использовать свежие контейнеры.

Я думаю, что причина повторного использования контейнеров заключается в том, чтобы сохранить любые изменения в процессе разработки. Обратите внимание, что Compose делает то же самое с томами, которые также сохраняются между воссозданием контейнера (воссозданный контейнер будет присоединяться к томам своего предшественника). Это может быть полезно, например, если в качестве кеша используется контейнер Redis и вы не хотите терять кеш каждый раз, когда вносите небольшие изменения. В других случаях это просто сбивает с толку.

Я не верю, что есть какой-то способ заставить это сделать из файла Compose.

Возможно, это противоречит неизменным принципам инфраструктуры. Контр-аргумент, вероятно, заключается в том, что вы не используете Compose в производстве (пока). Кроме того, я не уверен, что согласен с тем, что неизменная инфраструктура является основной идеей Docker, хотя это, безусловно, хороший вариант использования / точка продажи.

Адриан Муат
источник
Спасибо за ответ. Я думаю, что было бы действительно полезно форсировать это на уровне конфигурации, например. применить его к контейнеру базы данных и отключить воссоздание по умолчанию для контейнеров приложений.
Кристоф Йозса
8
--force-recreateу меня не работает ... Изображение не вытащено, хотя там есть более новая версия ...
Лисак
1
@ lisak Я никогда не говорил, что это вытянуло новые изображения. Это не так. Он просто запускает новые контейнеры, используя любое доступное изображение. Вам нужно будет запустить Docker Pull вручную.
Адриан Муат
3
docker-compose up --build

ИЛИ

docker-compose build --no-cache
flgn
источник
1
По возможности, пожалуйста, постарайтесь предоставить дополнительное объяснение, а не просто код. Такие ответы имеют тенденцию быть более полезными, поскольку они помогают членам сообщества и особенно новым разработчикам лучше понять обоснованность решения и могут помочь избежать необходимости отвечать на последующие вопросы.
Раджан
-10
$docker-compose build

Если есть что-то новое, оно будет восстановлено.

Матиас Асберг
источник