Jak sprawić, by folder z dowiązaniem symbolicznym pojawiał się jako normalny folder

38

Mam dwie aplikacje Dart, które muszę dokować. Te dwie aplikacje używają udostępnionego katalogu źródłowego.
Ponieważ Docker zapobiega dodawaniu plików z folderów spoza katalogu kontekstowego ( project/app1), nie mogę dodawać plików z ../sharedani z shared(dowiązanie symboliczne w środku projects/app1).

W każdym razie szukam sposobu, aby oszukać Dockera.

Moja uproszczona struktura projektu

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

Mógłbym przejść o Dockerfilejeden poziom wyżej i uruchomić docker buildstamtąd, ale potrzebuję dwóch plików Docker (dla app1 i app2) w tym samym katalogu.

Mój obecny pomysł polegał na tym, że gdybym mógł jakoś ukryć fakt, że projects/app1/sharedjest dowiązaniem symbolicznym, problem ten zostałby rozwiązany. Sprawdziłem, czy mogę udostępniać projectsza pomocą Samby i zamontowałem ją gdzie indziej i skonfigurowałem Sambę, aby traktowała dowiązania symboliczne jak normalne foldery, ale nie znalazłem, czy jest to obsługiwane (nie mam dużego doświadczenia z Sambą i jeszcze jej nie wypróbowałem, tylko trochę szukałem) .

Czy jest jakieś inne narzędzie lub sztuczka, które na to pozwalają?

Wolałbym nie zmieniać struktury katalogów, ponieważ spowodowałoby to inne problemy, a także raczej nie kopiowałbym plików.

zoechi
źródło

Odpowiedzi:

35

Nie mam dużego doświadczenia, dockerwięc nie mogę obiecać, że to zadziała, ale jednym wyborem byłoby zamontowanie katalogu zamiast łączenia się z nim:

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

Który dołączy ../shareddo ./sharedi powinno być całkowicie przezroczyste dla systemu. Jak wyjaśniono w man mount:

Wiążą się wierzchowce.

Od Linuksa 2.4.0 można ponownie zamontować część hierarchii plików w innym miejscu. Połączenie jest następujące:

mount --bind olddir newdir

lub używając tego wpisu fstab:

/olddir /newdir none bind

Po tej rozmowie te same treści są dostępne w dwóch miejscach.

terdon
źródło
1
@zoechi jest to doskonale na temat na obu stronach. Zasadniczo zamieszczałbym więcej technicznych pytań takich jak ten na U&L i więcej pytań dotyczących przestrzeni użytkownika tutaj. Wybór należy jednak do Ciebie. Z jednej strony jest tu więcej użytkowników, więc więcej gałek ocznych, z drugiej strony jest znacznie większa koncentracja profesjonalnych * nix osób na U&L. Tylko upewnij się, że nie opublikujesz tego samego pytania na obu stronach. Jeśli chcesz go przenieść, usuń to lub zaznacz flagę mod i poproś o migrację.
terdon
2
Ponowne uruchomienie demona dokera było obowiązkowe! W przeciwnym razie zamontowany katalog nie był widoczny w pojemniku.
dim
@dim tak! Próbowałem zmusić go do współpracy z Capistrano i to nie zadziałało - okazało się, że zamontowałem wspólne katalogi po uruchomieniu kontenera
csch
Niestety nie będzie to działać dla użytkowników systemu Windows lub OS X. Debata na ten temat była ... ożywiona.
Jason
czy montowanie jest „zobowiązane” do kontroli źródła, np. github? czy musiałbym to robić za każdym razem?
pie6k
23

Ten problem pojawiał się wielokrotnie w społeczności Docker. Zasadniczo narusza to wymóg Dockerfilepowtarzalności, jeśli go uruchomisz lub uruchomię. Nie spodziewałbym się więc tej zdolności, jak opisano w tym zgłoszeniu: polecenie Dockerfile ADD nie śledzi dowiązań symbolicznych na hoście # 1676 .

Musisz więc wymyślić inne podejście. Jeśli spojrzysz na ten problem: DODAJ, aby obsługiwać dowiązania symboliczne w argumencie # 6094 , nasz przyjaciel z U&L ( @Patrick aka. Phemmer) zapewnia sprytne obejście.

$ tar -czh . | docker build -

Mówi tarto o dereferencji dowiązań symbolicznych z bieżącego katalogu, a następnie potokowanie ich wszystkich do docker build -polecenia.

fragment strony man tar
-c, --create
       create a new archive

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

-z, --gzip, --gunzip --ungzip
slm
źródło
3
To jest DOSKONAŁE rozwiązanie! Rozumiem, dlaczego Docker twierdzi, że chce pominąć tę funkcję. Istnieje jednak znaczna różnica w przepływie pracy, z którego korzystam podczas opracowywania mojego projektu kontenerowego i w jaki sposób spodziewam się, że zostanie on zbudowany do produkcji. Na mojej lokalnej maszynie chcę bardzo ciasną pętlę sprzężenia zwrotnego. Moja aplikacja ma 1 repozytorium git, a środowisko kompilacji dla kontenerów ma drugie repo. Muszę być w stanie dokonywać edycji i budować testy lokalnie, zanim będę mógł zdecydować, czy chcę zatwierdzać i wypychać. W moim ostatnim projekcie nie będę mieć dowiązań symbolicznych ani instrukcji DODAJ.
Bruno Bronosky,
6
Pliki dokerów nie są powtarzalne. Pliki dokerów nie mogą być możliwe do powtórzenia, ponieważ prawie wszystkie mają apt-get lub coś równoważnego na 2. lub 3. warstwie, a apt-get nie jest powtarzalny. Powiązanie strategii rozwoju Dockera z nieudaną próbą urzeczywistnienia niemożliwego stanie się tylko osiodłaniem Dockera serią złych abstrakcji, które nikomu nie pomogą. nathanleclaire.com/blog/2014/09/29/…
Jason
1
Ok, więc tak naprawdę nie rozumiem, dlaczego jest to lepsze niż cppolecenie, czy możesz wyjaśnić, dlaczego jest lepsze? Myślę też, że rura jest myląca / nadmiernie skomplikowana. Dlaczego nie po prostu umieścić polecenia tar nad poleceniem kompilacji. Chyba dlatego, że wtedy nadpisujesz dowiązanie symboliczne realnym katalogiem.
Alexander Mills,
1
@AlexanderMills - najlepszym sposobem, aby zobaczyć, co się dzieje, jest wypróbowanie i zobaczenie różnicy. Powyżej znajduje się budynek kontenera, a nie działający, więc nie ma montażu. stackoverflow.com/questions/37328370/… . Gorąco polecam wypróbowanie wszystkich tych rzeczy, będzie to miało o wiele więcej sensu.
slm
1
Właśnie dodałem /bin/cp ../requirements.txt . && docker build ...do pliku Makefile, aby zbudować
doker