Как перезапустить отдельный контейнер с помощью docker-compose

333

У меня есть docker-compose.ymlфайл, который содержит 4 контейнера: Redis, Postgres, API, рабочий

Во время разработки работника мне часто приходится перезапускать его, чтобы применить изменения. Есть ли хороший способ перезапустить контейнер (например worker) без перезапуска других контейнеров?

Брайан Чен
источник
2
docker-compose -f docker-compose.yml перезапустить работника
Джинна Балу

Ответы:

398

Это очень просто: используйте команду:

docker-compose restart worker

Вы можете установить время ожидания остановки перед уничтожением контейнера (в секундах)

docker-compose restart -t 30 worker

Обратите внимание, что это перезапустит контейнер, но не перестраивает его. Если вы хотите применить свои изменения и затем перезапустить, взгляните на другие ответы.

bmkrio
источник
3
для меня это сработало, но общий вопрос, если он разрешен здесь: перезапускает заботу о связанных контейнерах и обновляет / etc / hosts или не перезапускает изменение каких-либо IP-адресов вообще?
michabbb
Контейнеры связаны по имени, и обычно единственный IP-адрес, о котором вам нужно беспокоиться, - это IP-адрес внешнего докера (обычно 192.168.99.100). Проблемы могут возникнуть, если вы, скажем, перезапустите контейнер базы данных, к которому подключены другие контейнеры. Зависимые контейнеры должны быть достаточно эластичными, чтобы их можно было повторно подключить.
Райан Кимбер
20
ОП утверждает, что ему нужно «перезапустить его, чтобы применить изменения». В соответствии с документами docker-compose restartкоманды НЕ будут применять какие-либо изменения. «Если вы вносите изменения в свою docker-compose.ymlконфигурацию, эти изменения не отражаются после выполнения этой команды». Поэтому пользуйтесь docker-compose up -d --build. docs.docker.com/compose/reference/restart
featherbelly
5
nb, worker - это имя, данное службе в файле yaml, а не то, что вы видите при запускеdocker ps -a
worc 31.10-18
2
Этот другой ответ намного лучше stackoverflow.com/a/39501539/292408 , так как restartне применяет изменения, даже если вы уже выполнили, docker-compose build <container name>и это нерабочий / неправильный ответ.
Элайджа Линн
170

Другие ответы на перезапуск одного узла находятся на цели, docker-compose restart worker. Это отразит этот контейнер, но не будет включать никаких изменений, даже если вы перестроили его отдельно. Вы можете вручную stop, rm, createи start, но есть гораздо проще метода.

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

docker-compose up --detach --build

Это сначала восстановит ваши изображения из любого измененного кода, что быстро, если нет изменений, так как кэш используется повторно. И тогда он только заменяет измененные контейнеры. Если ваши загруженные изображения устарели, вы можете добавить команду выше:

docker-compose pull

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

И чтобы сделать это только для одного сервиса, выполните команду up или pull с сервисами, которые вы хотите указать, например:

docker-compose up --detach --build worker

Вот краткий пример первого варианта, Dockerfile структурирован так, чтобы часто изменяющиеся части кода оставались ближе к концу. Фактически требования выдвигаются отдельно, pip installпоскольку этот файл редко изменяется. И поскольку контейнеры nginx и redis были обновлены, они не были перезапущены. Общее время на весь процесс составило менее 6 секунд:

$ time docker-compose -f docker-compose.nginx-proxy.yml up --detach --build
Building counter
Step 1 : FROM python:2.7-alpine
 ---> fc479af56697
Step 2 : WORKDIR /app
 ---> Using cache
 ---> d04d0d6d98f1
Step 3 : ADD requirements.txt /app/requirements.txt
 ---> Using cache
 ---> 9c4e311f3f0c
Step 4 : RUN pip install -r requirements.txt
 ---> Using cache
 ---> 85b878795479
Step 5 : ADD . /app
 ---> 63e3d4e6b539
Removing intermediate container 9af53c35d8fe
Step 6 : EXPOSE 80
 ---> Running in a5b3d3f80cd4
 ---> 4ce3750610a9
Removing intermediate container a5b3d3f80cd4
Step 7 : CMD gunicorn app:app -b 0.0.0.0:80 --log-file - --access-logfile - --workers 4 --keep-alive 0
 ---> Running in 0d69957bda4c
 ---> d41ff1635cb7
Removing intermediate container 0d69957bda4c
Successfully built d41ff1635cb7
counter_nginx_1 is up-to-date
counter_redis_1 is up-to-date
Recreating counter_counter_1

real    0m5.959s
user    0m0.508s
sys     0m0.076s
BMitch
источник
Это интересно, но можно ли его использовать вместе с -no-cacheопцией? Скажем, я добавил что-то в свой package.jsonи нужно повторно, RUN npm installно Dockerfileсам по себе не изменился
Августин Ридингер
2
@augustinriedinger Если ваш входной файл изменился, и вы включили его в COPYкоманду, это автоматически сломает кеш.
BMitch
1
@augustinriedinger спасибо. Я мобильн, поэтому не вижу связанных вопросов. Из шагов вашего вопроса у вас уже должна быть COPYкоманда в вашем Dockerfile. git pullОбновит файл package.json и кэш сборки будет ломаться , когда докер видит скопировать в другой файл.
BMitch
1
Спасибо, не знал об этом поведении! Я использовал ADDвместо, COPYно, видимо, последний является лучшей практикой, поэтому я пойду на это!
Августин Ридингер
1
@augustinriedinger ADDбудет иметь тот же результат, что и COPYв случае с кешем, но (как указано в ссылке на лучшие практики) большинству не нужны дополнительные возможности, поэтому я даже не буду упоминать об этом.
BMitch
28

Чтобы перезапустить службу с изменениями, вот шаги, которые я выполнил:

docker-compose stop -t 1 worker
docker-compose build worker
docker-compose create worker
docker-compose start worker
Джефф
источник
10
Если вам нужны изменения для применения со сборкой, вы можете легко это сделать, docker-compose up -d --buildи она восстановит все и перезапустит все измененные контейнеры. Нет необходимости сначала останавливаться с временем простоя и отдельными командами создания и запуска.
BMitch
4
Да, если вы хотите перезапустить все сервисы, но OP хочет перезапустить только один сервис, а не перезапускать другие
Jeff
3
Посмотрите ответ, который я разместил, в этом примере upзавещание воссоздает только тот контейнер, который был изменен и поэтому нуждается в перезапуске.
BMitch
18

Следующая команда

docker-compose restart worker

просто ОСТАНОВИТЕ и НАЧНИТЕ контейнер. т.е. без загрузки каких-либо изменений из docker-compose.xml

STOP похож на спящий режим в ПК. Следовательно, stop / start не будет искать какие-либо изменения, внесенные в файл конфигурации. Для перезагрузки из рецепта контейнера (docker-compose.xml) нам нужно удалить и создать контейнер (аналогично перезагрузке ПК)

Так что команды будут следующими

docker-compose stop worker       // go to hibernate
docker-compose rm worker        // shutdown the PC 
docker-compose create worker     // create the container from image and put it in hibernate

docker-compose start worker //bring container to life from hibernation
Мистер кодер
источник
+1, большое спасибо! Для rmстроки опция -fудобна (без подсказки) и с текущим докером createи startобъединена как up(таким образом, у нас есть 3 команды, а не 4), а upопция -dполезна (выполнение выполняется в фоновом режиме).
Astrowalker
10

Перезапустите Сервис с помощью docker-compose file

docker-compose -f [COMPOSE_FILE_NAME].yml restart [SERVICE_NAME]

Вариант использования # 1: если COMPOSE_FILE_NAME - это docker-compose.ymlи сервис работает

docker-compose restart worker

Вариант использования № 2: если имя файла sample.ymlи служба работает

docker-compose -f sample.yml restart worker

По умолчанию docker-compose ищет команду, docker-compose.ymlесли мы запускаем docker-composeкоманду, в противном случае у нас есть флаг для указания конкретного имени файла с-f [FILE_NAME].yml

Джинна Балу
источник
7

Простая команда «docker» ничего не знает о «рабочем» контейнере. Используйте команду как это

docker-compose -f docker-compose.yml restart worker

Shtlzut
источник
4
не работает - новые изменения в coker-compose.yml не были применены при перезапуске
jlee
3

Перезапустить контейнер

Если вы хотите просто перезапустить свой контейнер:

docker-compose restart servicename

Думайте об этой команде как о «просто перезапустите контейнер по его имени», что эквивалентно docker restartкоманде.

Примечание предостережения:

  1. Если вы изменили переменные ENV, они не будут обновляться в контейнере. Вы должны остановить это и начать снова. Или, используя одну команду docker-compose up, обнаружит изменения и заново создаст контейнер.

  2. Как упоминали многие другие, если вы изменили docker-compose.ymlсам файл, простой перезапуск не применит эти изменения.

  3. Если вы копируете свой код в контейнер на этапе сборки (при Dockerfileиспользовании команд ADDили COPY), каждый раз, когда код изменяется, вам необходимо перестраивать контейнер ( docker-compose build).

Соотношение с вашим кодом

docker-compose restartдолжно прекрасно работать, если ваш код получает путь, сопоставленный с контейнером, директивой volume docker-compose.ymlследующим образом:

services:

  servicename:
    volumes:
      - .:/code

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

Лев Рубель
источник
1

Ответ здесь говорит об отражении изменений в файле docker-compose.yml.

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

1. остановка докера

docker stop container-id

2. удаление контейнера докера

docker rm container-id

3. удаление образа докера

docker rmi image-id

4. снова составьте контейнер

docker-compose up container-name
Аншул Шарма
источник