Docker: добавление файла из родительского каталога


187

По моему Dockerfileу меня есть:

ADD ../../myapp.war /opt/tomcat7/webapps/

Этот файл существует, поскольку ls ../../myapp.warвозвращает мне правильный файл, но при выполнении sudo docker build -t myapp .я получаю:

Step 1 : ADD ../../myapp.war /opt/tomcat7/webapps/
2014/07/02 19:18:09 ../../myapp.war: no such file or directory

Кто-нибудь знает почему и как это правильно сделать?


2
Некоторые обходные пути superuser.com/questions/842642
Гюнтер Цохбауэр

Ответы:


226

Вы можете собрать Dockerfile из родительского каталога:

docker build -t <some tag> -f <dir/dir/Dockerfile> .

3
Спасибо! Это хорошо работает на локальном компьютере, но Docker Hub не может создать образ, так как он пытается сделать это из того же каталога (tbh, как и следовало ожидать). Есть ли способ сделать такой же трюк в Docker Hub?
Марсель Эрнандес

Не то, что я знаю о. Вы можете отправить изображение в реестр вместо автоматической сборки.
Боэди,

2
@ eduncan911 Я не думаю, что это устарело в то время, когда я пишу свой комментарий. Возможно, они изменили свое мнение с тех пор? Если я не прав, можете ли вы ссылаться на документацию, где говорится, что это устарело. Спасибо!
omninonsense

6
-f не представляется устаревшим в соответствии с документами -> Укажите файл Docker (-f) : docs.docker.com/engine/reference/commandline/build/…
Рэй

6
@ eduncan911 Можете ли вы удалить свой комментарий, поскольку он явно не считается устаревшим? Я пропустил этот ответ изначально из-за вашего комментария.
Крис Андерсон

104

С помощью docker-compose вы можете установить контекстную папку:

#docker-compose.yml
version: '3.3'    
services:
      yourservice:
        build:
          context: ./
          dockerfile: ./docker/yourservice/Dockerfile

103

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

Из документации :

Путь <src> должен быть внутри контекста сборки; вы не можете ДОБАВИТЬ ../something / что-то, потому что первый шаг сборки docker - это отправить каталог контекста (и подкаталоги) демону docker.

РЕДАКТИРОВАТЬ: теперь есть опция ( -f), чтобы указать путь к вашему Dockerfile; его можно использовать для достижения того, чего вы хотите, см. ниже ответ @Boedy.


22
Есть ли «чистый» обходной путь для этого? Я бы предпочел не реструктурировать весь каталог моего проекта только для того, чтобы приспособиться к этому.
ben_frankly

Как сказал @ Günter, здесь есть обходной путь superuser.com/a/842690/136024 ... это действительно "чисто"? Ну, по крайней мере, это «обходной путь» :)
Энтони О.

2
См. Лучший ответ от @Boedy stackoverflow.com/a/34300129/2950621
nmgeek

9

Добавление фрагментов кода для поддержки принятого ответа.

Структура каталогов:

setup/
 |__docker/DockerFile
 |__target/scripts/<myscripts.sh>
src/
 |__<my source files>

Запись файла Docker:

RUN mkdir -p /home/vagrant/dockerws/chatServerInstaller/scripts/
RUN mkdir -p /home/vagrant/dockerws/chatServerInstaller/src/
WORKDIR /home/vagrant/dockerws/chatServerInstaller

#Copy all the required files from host's file system to the container file system.
COPY setup/target/scripts/install_x.sh scripts/
COPY setup/target/scripts/install_y.sh scripts/
COPY src/ src/

Команда, используемая для создания образа докера

docker build -t test:latest -f setup/docker/Dockerfile .

отличный подход. Можно ли разделить код install_x.sh, а?
Ariful Haque

4

Решением для тех, кто использует composer, является использование тома, указывающего на родительскую папку:

#docker-composer.yml

foo:
  build: foo
  volumes:
    - ./:/src/:ro

Но я почти уверен, что можно поиграть с объемами в Dockerfile .


3
Не может Примечание. Каталог хоста по своей природе зависит от хоста. По этой причине вы не можете смонтировать каталог хоста из Dockerfile, потому что созданные образы должны быть переносимыми. Каталог хостов не будет доступен на всех потенциальных хостах. docs.docker.com/engine/tutorials/dockervolumes/…
Кокк

4

Так как -fвозникла другая проблема, я разработал другое решение.

  • Создать базовое изображение в родительской папке
  • Добавлены необходимые файлы.
  • Использовал это изображение как базовое изображение для проекта, который находится в папке-потомке.

-fФлаг не решить мою проблему , потому что мои onbuildизображения ищет файл в папке и должен был назвать так:

-f foo/bar/Dockerfile foo/bar

вместо того

-f foo/bar/Dockerfile .

Также обратите внимание, что это только решение для некоторых случаев, как -fфлаг

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.