Dockerfile VOLUME инструкция очищает данные - PullRequest
0 голосов
/ 08 января 2020

Как часть большой установки, у меня есть многоэтапная сборка Docker с Docker Compose, которая имеет контейнер builder с некоторыми данными в /var/www. Когда я создаю контейнер второй стадии с именем application, мой Dockerfile имеет следующие инструкции

ARG APPLICATION_BUILDER

FROM $APPLICATION_BUILDER as builder

FROM busybox

COPY --from=builder --chown=www-data:www-data /var/www /var/www

VOLUME /var/www

ENTRYPOINT ["tail"]
CMD ["-f", "/dev/null"]

Файл builder Docker:

FROM ubuntu:16.04

ARG APPLICATION_SOURCE_FOLDER

COPY --chown=www-data:www-data ${APPLICATION_SOURCE_FOLDER} /var/www

Когда я запускаю контейнер builder, он имеет все данные в /var/www, как и ожидалось. Однако, когда я запускаю контейнер application, используя: docker run -it <IMAGE>, он ничего не содержит в /var/www

Если я удаляю строку VOLUME /var/www в Dockerfile, тогда данные выглядят как и ожидалось. Но я не понимаю, почему инструкция VOLUME может привести к исчезновению данных, я думал, что она предназначена для экспорта содержимого /var/www/ в виде тома?

Нужно ли указывать -v когда я делаю docker run в дополнение к инструкции VOLUME?

Ответы [ 2 ]

1 голос
/ 08 января 2020

Директива VOLUME не «экспортирует содержимое» каталога. Там написано "создать том и смонтировать его по этому пути". Поэтому, когда вы пишете:

COPY --from=builder --chown=www-data:www-data /var/www /var/www
VOLUME /var/www

Вы говорите:

  • Сначала скопируйте группу файлов в /var/www
  • Затем смонтируйте пустой том on /var/www

Монтирование тома происходит как во время сборки (влияет на любые последующие операторы RUN), так и во время выполнения (влияет на среду, которую вы видите с помощью docker run).

Если вы удалите директиву VOLUME из Dockerfile, а затем запустите свое изображение следующим образом:

docker run -v /var/www yourimage ...

Тогда Docker создаст новый том и скопирует в него содержимое /var/www перед монтированием.

Аналогично, если у вас есть именованный том, вы можете сделать то же самое:

docker run -v myvolume:/var/www yourimage ...

Docker будет выполнять эту автоматическую c операцию копирования только в том случае, если Том, который вы монтируете, пуст. Если том имеет существующее содержимое, он будет просто подключен по указанному пути, скрывая все, что находится под этой точкой монтирования.


Например ...

У меня есть изображение с именем kos имеет несколько файлов в /var/www. Мы можем увидеть их, запустив ls /var/www:

bash-5.0$ docker run kos ls /var/www
index.html
testing.jpg

Если я смонтирую анонимный том на /var/www с docker run -v, мы увидим, что он заполняется содержимым из базового /var/www directory:

bash-5.0$ docker run -v /var/www kos ls /var/www
index.html
testing.jpg

Мы видим то же поведение, если создаем именованный том и монтируем его на /var/www:

bash-5.0$ docker volume create kos_testing
kos_testing
bash-5.0$ docker run -v kos_testing:/var/www kos ls /var/www
index.html
testing.jpg
bash-5.0$
0 голосов
/ 08 января 2020

Я подозреваю, что происходит то, что, когда вы указываете VOLUME, он по существу перезаписывает то, что вы ранее скопировали, с пустым монтированием тома.

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

Сначала объявите свой том, а затем скопируйте данные в свой том.

...