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.

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.


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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.