Стек Docker развертывает скользящие обновления, проблема с объемом

Я запускаю докер для производственного приложения PHP-FPM/Nginx, я хочу использовать docker-stack.yml и развернуть его в роевом кластере. Вот мой файл:

version: "3"
services:

app:
  image: <MYREGISTRY>/app
volumes:
   - app-data:/var/www/app
deploy:
  mode: global

php:
  image: <MYREGISTRY>/php
volumes:
   - app-data:/var/www/app
deploy:
  replicas: 2

nginx:
  image: <MYREGISTRY>/nginx
    depends_on:
      - php
  volumes:
    - app-data:/var/www/app
  deploy:
    replicas: 2
  ports:
    - "80:80"

volumes:
 app-data:

Мой код находится в контейнере app с изображением из моего реестра.

Я хочу обновить свой код с помощью docker service update --image <MYREGISTRY>/app:latest, но он не работает, код не изменился. Я предполагаю, что вместо этого он использует локальный том app-data.

Нормально ли, что новые данные контейнера не переопределяют данные тома?


person ninja_dev    schedule 15.03.2017    source источник


Ответы (2)


У меня была та же проблема, что у меня есть контейнеры приложений и nginx, использующие один и тот же том. Мое текущее решение имеет сценарий развертывания, который запускается

docker service update --mount-add mount service

для приложения и nginx после развертывания стека докеров. Это заставит обновить том для контейнеров приложений и nginx.

person Lecky Lao    schedule 08.03.2018

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

Если вам нужно, чтобы файлы обновлялись с каждым новым изображением, то, возможно, они не должны быть в томе? Если они вам нужны внутри тома, вам может потребоваться создать процедуру для обновления томов из образа, например. если бы это был docker run, вы могли бы сделать:

docker run -v app-data:/target --rm <your_registry>/app cp -a /var/www/app/. /target/.

В противном случае вы можете удалить том или просто удалить все файлы из тома и перезапустить стек, чтобы заполнить его снова.

person BMitch    schedule 15.03.2017
comment
Спасибо за ваш ответ, я действительно думаю, что это не должно быть в томе, но как я могу поделиться кодом с app по php и nginx без тома? Я также подумал о процедуре обновления тома, я думаю, это мой лучший вариант на данный момент - person ninja_dev; 15.03.2017
comment
Я немного смущен, почему у вас есть и контейнер nginx, и контейнер php, и какую цель предоставляет контейнер приложения, кроме вашего тома. Похоже, его следует упростить до одного контейнера, которому даже не нужен том. - person BMitch; 15.03.2017
comment
Вы правы, единственная цель контейнера приложения — иметь код и обеспечить объем. Единый контейнер для всех сложнее обновить (например, если я просто хочу обновить код), и я думаю, что лучше использовать версию кода только для изображения. - person ninja_dev; 15.03.2017
comment
Для меня было бы проще создать один образ на основе образа php+apache, который доступен как часть официального репозитория. Добавьте свой единственный слой кода поверх этого. Это устраняет оба других контейнера (nginx был бы излишним) и позволяет вам выполнять последовательные обновления и другие версии с этим контейнером. - person BMitch; 15.03.2017
comment
Я боролся именно с этой проблемой, это самое простое и умное решение: сделать один контейнер. Гарантия рабочего решения. - person AymDev; 15.07.2019