Как сделать так, чтобы символическая папка отображалась как обычная папка


38

У меня есть два приложения Dart, которые мне нужно докеризировать. Эти два приложения используют общий исходный каталог.
Поскольку Docker предотвращает добавление файлов из папок вне контекстного каталога ( project/app1), я не могу добавлять файлы ../sharedни из shared(из символической ссылки внутри projects/app1).

Я в любом случае ищу способ обмануть Докера.

Моя упрощенная структура проекта

- projects
  - app1
   - Dockerfile
   - shared (symlink ../shared)
   - otherSource
  - app2
   - Dockerfile
   - shared (symlink ../shared)
   - otherSource
  - shared
    - source

Я мог бы подняться на Dockerfileодин уровень и запустить docker buildоттуда, но тогда мне нужны два файла Docker (для app1 и app2) в одном каталоге.

Моя текущая идея была, если бы я мог как-то скрыть тот факт, что projects/app1/sharedэто символическая ссылка, эта проблема была бы решена. Я проверил, могу ли я поделиться projectsс помощью Samba, перемонтировать его в другое место и настроить Samba для обработки символических ссылок, как в обычных папках, но не нашел, поддерживается ли это (у меня нет большого опыта работы с Samba, и я еще не пробовал, просто немного поискал) ,

Есть ли другой инструмент или трюк, который позволил бы это?

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

Ответы:


35

У меня нет большого опыта работы с этим, dockerпоэтому я не могу обещать, что это сработает, но один из вариантов - подключить каталог вместо ссылки на него:

$ cd projects/app1
$ mkdir shared
$ sudo mount -o bind ../shared shared/

Это будет приложить ../sharedк ./sharedи должен быть полностью прозрачным для системы. Как объяснено в man mount:

Привязка крепится.

Начиная с Linux 2.4.0, можно перемонтировать часть файловой иерархии куда-то еще. Вызов:

mount --bind olddir newdir

или используя эту запись fstab:

/olddir /newdir none bind

После этого вызова одно и то же содержимое доступно в двух местах.


1
@zoechi это идеально по теме на обоих сайтах. Как правило, я бы разместил здесь больше технических вопросов на U & L и больше вопросов о пространстве пользователя. Выбор полностью зависит от вас. С одной стороны, здесь больше пользователей, поэтому больше глазных яблок, с другой - гораздо большая концентрация профессиональных * nix людей в U & L. Просто убедитесь, что вы не публикуете один и тот же вопрос на обоих сайтах. Если вы хотите переместить его, либо удалите его, либо пометьте для модного внимания и попросите их перенести.
Тердон

2
Для меня было обязательно перезапустить Docker Daemon! В противном случае установленный каталог не был виден в контейнере.
дим

@ да, да! Я пытался заставить его работать с Capistrano, но он не работал - оказывается, я смонтировал общие каталоги после того, как запустил контейнер
csch

К сожалению, это не будет работать для пользователей Windows или OS X. Дискуссия по этому вопросу была ... оживленной.
Джейсон

монтируется ли «контроль» к управлению исходным кодом, например, github? или мне придется делать это каждый раз?
pie6k

23

Эта проблема неоднократно поднималась в сообществе Docker. Это в основном нарушает требование Dockerfileповторения, если вы запускаете его или я запускаю его. Поэтому я не ожидал, что эта возможность, как описано в этом билете: команда Dockerfile ADD не следует по символическим ссылкам на хосте # 1676 .

Таким образом, вы должны представить себе другой подход. Если вы посмотрите на эту проблему: ADD для поддержки символических ссылок в аргументе # 6094 , наш друг из U & L ( @Patrick aka. Phemmer) предлагает умный обходной путь.

$ tar -czh . | docker build -

Это говорит tarразыменовать символические ссылки из текущего каталога, а затем направить их все в docker build -команду.

выдержка из страницы руководства tar
-c, --create
       create a new archive

-h, --dereference
       follow symlinks; archive and dump the files they point to

-z, --gzip, --gunzip --ungzip

3
Это ОТЛИЧНОЕ решение! Я понимаю, почему Docker утверждает, что они хотят опустить эту функцию. Однако существует значительная разница в рабочем процессе, который я использую при разработке своего контейнерного проекта, и в том, как я ожидаю, что он будет создан для производства. На моей локальной машине я хочу очень плотную петлю обратной связи. Мое приложение имеет 1 репозиторий Git, а среда сборки для контейнеров имеет 2 репо. Мне нужно иметь возможность вносить изменения и создавать тесты локально, прежде чем я смогу решить, хочу ли я зафиксировать и нажать. У меня не будет символических ссылок или ДОБАВИТЬ инструкции в моем конечном проекте.
Бруно Броноски

6
Dockerfiles не повторяются. Dockerfiles невозможно сделать повторяемыми, потому что почти все они имеют apt-get или что-то эквивалентное на 2-м или 3-м уровне, а apt-get не повторяется Связывание стратегии разработки Docker с ошибочной попыткой сделать невозможное правдой просто оседлает Docker серией плохих абстракций, которые никому не помогут. nathanleclaire.com/blog/2014/09/29/…
Джейсон

1
Хорошо, так что я не понимаю, почему это лучше, чем cpкоманда, вы можете объяснить, почему это лучше? Я также думаю, что труба запутанная / чрезмерно запутанная. Почему бы просто не поставить команду tar над командой build. Я полагаю, потому что тогда вы перезапишете символическую директорию настоящей директорией.
Александр Миллс

1
@AlexanderMills - лучший способ увидеть, что происходит, это попробовать и увидеть разницу. Также выше приведено здание контейнера, а не работает, поэтому нет монтажа. stackoverflow.com/questions/37328370/… . Я настоятельно рекомендую вам попробовать все это, это будет иметь больше смысла.
SLM

1
Я только добавил /bin/cp ../requirements.txt . && docker build ...в Makefile для сборки Docker, это было проще
user5359531
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.