Як зробити так, щоб зв'язана папка виглядала як звичайна папка


38

У мене є два додатки Dart, які мені потрібно докерізувати. Ці два додатки використовують спільний каталог джерел.
Оскільки Докер забороняє додавати файли з папок поза каталогом контексту ( project/app1), я не можу додавати файли ../sharedні з, ні з shared(посилання символу всередині projects/app1).

Я шукаю спосіб, як обдурити Докера, щоб це все одно було.

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

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

Я міг би перейти на Dockerfileодин рівень вгору і бігти docker buildзвідти, але тоді мені потрібні два Dockerfiles (для 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! Інакше змонтованого режиму не було видно в контейнері.
тьма

@dim так! Я спробував змусити його працювати з Capistrano, і це не вийшло - виявляється, я змонтував спільні каталоги після запуску контейнера
csch

На жаль, це не буде працювати для користувачів Windows або OS X. Дебати з цього питання пройшли ... жваво.
Джейсон

монтується "дозволено" для управління джерелом, наприклад, github? чи я мав би робити це кожен раз?
pie6k

23

Це питання неодноразово виникало в спільноті Докер. Це в основному порушує вимогу Dockerfileбути повторюваним, якщо ви запускаєте його чи я виконую. Тому я б не очікував цієї здатності, як описано в цьому квитку: команда Dockerfile ADD не слідує за посиланнями на хост # 1676 .

Тож вам доведеться мислити інший підхід. Якщо ви подивитесь на це питання: ДОБАВИТИ для підтримки символьних посилань у аргументі № 6094 , наш друг з U&L ( @Patrick aka. Phemmer) надає розумний спосіб вирішення.

$ tar -czh . | docker build -

Це повідомляє tarпро вилучення символічних посилань з поточного каталогу, а потім передає їх усім docker build -команді.

уривок зі сторінки чоловіка з дьогтем
-c, --create
       create a new archive

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

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

3
Це ВИКЛЮЧНЕ рішення! Я розумію, чому Докер стверджує, що хочуть опустити цю функцію. Однак є значна різниця в робочому процесі, який я використовую під час розробки свого проекту для контейнерів, і в тому, як я очікую, що він буде побудований для виробництва. На своїй локальній машині я хочу дуже щільний цикл зворотного зв'язку. У моєму додатку є 1 git repo, а середовище збирання контейнерів має 2-е репо. Мені потрібно мати можливість редагувати та створювати тести на місцевому рівні, перш ніж я можу вирішити, чи хочу я здійснити та натиснути. У моєму остаточному проекті у мене не буде посилань чи інструкцій щодо додавання.
Бруно Броноський

6
Докерфайли не повторюються. Докерфіли неможливо зробити повторюваними, оскільки вони майже всі мають apt-get або щось еквівалентне на 2-му або 3-му шарі, і apt-get не повторюється. Прив’язання стратегії розвитку Докера до хибної спроби зробити неможливе справжньою буде просто осіловити Доккера низкою поганих абстракцій, які нікому не допомагають. nathanleclaire.com/blog/2014/09/29/…
Джейсон

1
Гаразд, тому я не розумію, чому це краще, ніж cpкоманда, чи можете ви пояснити, чому це краще? Я також думаю, що труба плутається / надмірно перекручена. Чому б просто не поставити команду tar над командою build. Я здогадуюсь, тому що тоді ви перезаписали б зв'язаний dir справжнім dir.
Олександр Міллс

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.