Абсолютные пути
Во-первых, вы не можете использовать абсолютные пути для COPY
.Все пути должны быть в контексте сборки , что означает относительно Dockerfile
.Если структура папок на вашем хосте похожа на
my-docker-directory
-- Dockerfile
-- docker-compose.yml
-- addons
, тогда вы можете использовать COPY addons /path/to/directory/inside/container
.Для всех последующих объяснений я предполагаю, что у вас есть папка addons
относительно Dockerfile
.
Монтирование каталога
COPY
не простосмонтировать папку в контейнер во время выполнения.Это на самом деле не монтировать каталог вообще.Вместо этого addons
копируется в /path/to/directory/inside/container
внутри изображения .Важно понимать, что этот процесс происходит однонаправленно (host> image) и происходит только тогда, когда образ собирается.
COPY
предназначен для добавления в образ зависимостей, которые требовались во время сборки, например, исходного кода, скомпилированного в двоичные файлы.Вот почему вы не можете использовать абсолютные пути.Dockerfile
обычно размещается вместе с исходным кодом / файлами конфигурации в области верхнего уровня.
Процесс сборки образа происходит только при первом запуске, за исключением того, что вы принудительно используете его с помощью docker-compose up --build
.Но не похоже, что это то, что вы хотите.Чтобы смонтировать каталог с хоста во время выполнения, используйте volume
в файле docker-compose
:
version: '3'
services:
test:
build: .
volumes:
- ./addons/:/path/to/directory/inside/container
Когда использовать COPY
и когда тома?
Важнопоймите, что COPY
и ADD
будут копировать содержимое в образ во время сборки, где volumes
монтирует их с хоста в runtume (без включения их в образ).Поэтому вы обычно копируете в образ общие вещи, которые нужны пользователям, например файлы конфигурации по умолчанию.
Тома должны включать файлы с хоста, такие как настраиваемые файлы конфигурации.Или постоянные вещи как каталог данных базы данных.Без томов эти контейнеры работают, но не являются постоянными.Таким образом, весь контент будет потерян при перезапуске контейнера.
Обратите внимание, что одно не исключает другое.Можно COPY
использовать конфигурацию по умолчанию для некоторого приложения в образе, где пользователь может переопределить это томами для их изменения.Особенно во время разработки это может упростить задачу, поскольку вам не нужно перестраивать весь образ для одного измененного файла конфигурации *
* Хотя это хорошая практика, оптимизируйте файлы Docker для интегрированного механизма кэширования.Если Dockerfile
написано хорошо, перестройка небольших изменений конфигурации часто не занимает много времени.Но это еще одна тема вне этой области.
Более подробное объяснение с примером
Базовая настройка с COPY
в Dockerfile
В качестве простого примера мы создаем Dockerfile
из образа веб-сервера nginx и скопируйте в него html
FROM nginx:alpine
COPY my-html /usr/share/nginx/html
Позволяет создать папку с демонстрационным содержимым
mkdir my-html
echo "Dockerfile content" > my-html/index.html
и добавить минималистичный docker-compose.yml
version: '3'
services:
test:
build: .
Если мы запустим его в первый раз, используя docker-compose up -d
, образ получен, и наша тестовая страница будет обслуживаться:
root@server2:~/docker-so-example# docker-compose up -d
Creating network "docker-so-example_default" with the default driver
Creating docker-so-example_test_1 ... done
root@server2:~/docker-so-example# curl $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-so-example_test_1)
Dockerfile content
Давайте манипулируем нашим тестовым файлом:
echo "NEW Modified content" > my-html/index.html
Если мы снова запросим наш сервер с curl
, мы получим старый ответ:
root@server2:~/docker-so-example# curl $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-so-example_test_1)
Dockerfile content
Чтобы применить наш контент, требуется перестройка:
docker-compose down && docker-compose up -d --build
Теперь мы можем увидеть нашизменения:
root@server2:~/docker-so-example# curl $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-so-example_test_1)
NEW Modified content
Использование томов в docker-compose
Чтобы показать разницу, мы используем тома, изменив наш файл docker-compose.yml
следующим образом:
version: '3'
services:
test:
build: .
volumes:
- ./my-html:/usr/share/nginx/html
Теперь перезапустите контейнеры, используя docker-compose down && docker-compose up -d
и попробуйте еще раз:
root@server2:~/docker-so-example# echo "Again changed content" > my-html/index.html
root@server2:~/docker-so-example# curl $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-so-example_test_1)
NEW Modified content
root@server2:~/docker-so-example# echo "Some content" > my-html/index.html
root@server2:~/docker-so-example# curl $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-so-example_test_1)
Some content
Обратите внимание, что мы не пересобрали образ и нашу модификациюкатионы применяются немедленно.При использовании томов файлы не включаются в образ.