Jak zamontować woluminy lokalne na komputerze Docker

85

Próbuję użyć docker-machine z docker-compose. Plik docker-compose.yml ma następujące definicje:

web:
  build: .
  command: ./run_web.sh
  volumes:
    - .:/app
  ports:
    - "8000:8000"
  links:
    - db:db
    - rabbitmq:rabbit
    - redis:redis

Podczas uruchamiania docker-compose up -dwszystko idzie dobrze, dopóki nie spróbujesz wykonać polecenia i nie zostanie wyświetlony błąd:

Nie można uruchomić kontenera b58e2dfa503b696417c1c3f49e2714086d4e9999bd71915a53502cb6ef43936d: [8] Błąd systemu: exec: "./run_web.sh": stat ./run_web.sh: brak takiego pliku lub katalogu

Woluminy lokalne nie są montowane na komputerze zdalnym. Jaka jest zalecana strategia montowania lokalnych woluminów z kodem aplikacji internetowych?

jdcaballerov
źródło
Struktura projektu i docker-compose.yml jest podobna do tego samouczka syncano.com/…
jdcaballerov
1
Powinno to znajdować się w dokumentach Docker-Compose jako pomocna wskazówka dla tych, które mogą zacząć używać lokalnego tworzenia wiadomości. Oszczędziłoby mi to wiele godzin spędzonych na WTF, próbując dowiedzieć się, dlaczego moja ścieżka do pliku była nieprawidłowa lub nie została znaleziona. Nie, po prostu czuję się głupio.
brązowo

Odpowiedzi:

93

Docker-machine automatycznie montuje katalog użytkowników ... Ale czasami to po prostu nie wystarcza.

Nie wiem o Dockerze 1.6, ale w 1.8 MOŻESZ dodać dodatkowy montaż do docker-machine

Dodaj punkt instalacji maszyny wirtualnej (część 1)

CLI : (działa tylko wtedy, gdy maszyna jest zatrzymana)

VBoxManage sharedfolder add <machine name/id> --name <mount_name> --hostpath <host_dir> --automount

Tak więc przykład w oknach byłby

/c/Program\ Files/Oracle/VirtualBox/VBoxManage.exe sharedfolder add default --name e --hostpath 'e:\' --automount

GUI : (NIE wymaga zatrzymania maszyny)

  1. Uruchom „Oracle VM VirtualBox Manager”
  2. Kliknij prawym przyciskiem myszy <machine name>(domyślnie)
  3. Ustawienia ...
  4. Udostępnione foldery
  5. Folder + ikona po prawej stronie (Dodaj udział)
  6. Ścieżka do folderu: <host dir>(e :)
  7. Nazwa folderu: <mount name>(e)
  8. Zaznacz „Auto-mount” i „Make Permanent” (czytaj tylko, jeśli chcesz ...) (Automatyczne montowanie jest obecnie trochę bezcelowe ...)

Montowanie w boot2docker (część 2)

Ręcznie zamontuj w boot2docker :

  1. Istnieją różne sposoby logowania, użyj opcji „Pokaż” w „Oracle VM VirtualBox Manager” lub ssh / putty w dockerze według adresu IP docker-machine ip defaultitp.
  2. sudo mkdir -p <local_dir>
  3. sudo mount -t vboxsf -o defaults,uid=`id -u docker`,gid=`id -g docker` <mount_name> <local_dir>

Ale to jest dobre tylko do momentu ponownego uruchomienia komputera, a wtedy montaż zostanie utracony ...

Dodanie automount do boot2docker :

Po zalogowaniu się do maszyny

  1. Edytuj / utwórz (jako root) /mnt/sda1/var/lib/boot2docker/bootlocal.sh, sda1 może być inny dla Ciebie ...
  2. Dodaj

    mkdir -p <local_dir>
    mount -t vboxsf -o defaults,uid=`id -u docker`,gid=`id -g docker` <mount_name> <local_dir>
    

Po tych zmianach powinieneś mieć nowy punkt montowania. Jest to jeden z niewielu plików, które udało mi się znaleźć, wywoływany podczas rozruchu i który jest trwały. Dopóki nie znajdzie się lepszego rozwiązania, powinno to działać.


Stara metoda: mniej zalecana , ale pozostawiona jako alternatywa

  • Edytuj (jako root) /mnt/sda1/var/lib/boot2docker/profile, sda1 może być inny dla Ciebie ...
  • Dodaj

    add_mount() {
      if ! grep -q "try_mount_share $1 $2" /etc/rc.d/automount-shares ; then
        echo "try_mount_share $1 $2" >> /etc/rc.d/automount-shares
      fi
    }
    
    add_mount <local dir> <mount name>
    

W ostateczności możesz wybrać nieco bardziej żmudną alternatywę i możesz po prostu zmodyfikować obraz rozruchowy.

  • git -c core.autocrlf=false clone https://github.com/boot2docker/boot2docker.git
  • cd boot2docker
  • git -c core.autocrlf=false checkout v1.8.1 # lub odpowiednią wersję
  • Edytować rootfs/etc/rc.d/automount-shares
  • Dodaj try_mount_share <local_dir> <mount_name>linię tuż przed fi na końcu. Na przykład

    try_mount_share /e e
    

    Tylko pamiętaj, aby nie ustawiać niczego, czego potrzebuje system operacyjny, takich jak / bin itp.

  • docker build -t boot2docker . # Za pierwszym razem zajmie to około godziny :(
  • docker run --rm boot2docker > boot2docker.iso
  • Utwórz kopię zapasową starego boot2docker.iso i skopiuj nowy w jego miejsce, w ~ / .docker / machine / machines /

To działa, jest po prostu długie i skomplikowane

docker w wersji 1.8.1, docker-machine w wersji 0.4.0

Andy
źródło
Dla każdego, kto ma z tym problemy, jestem prawie pewien, że musiałem dopasować lokalne ścieżki do tych w docker-machine. Wydawało się, że także docker-compose udało się zamontować woluminy, podczas gdy zwykły docker nie - nie wiem dlaczego.
spieden
3
Stworzyłem skrypt dla wspomnianego tutaj rozwiązania. Działa na najnowszych dockerach 1.10 i docker-machine 0.6.0 gist.github.com/cristobal/fcb0987871d7e1f7449e
cristobal
Różne źródła mówią o używaniu /mnt/sda1/var/lib/boot2docker/profile, czy możesz wyjaśnić, dlaczego przeszedłeś na używanie /mnt/sda1/var/lib/boot2docker/bootlocal.sh? Również przekreślenie tak dużej ilości tekstu nie przyczynia się do czytelności twojej odpowiedzi ;-)
Forage
1
@Forage Point zajęło się moim formatowaniem :). Nie pamiętam już od ręki, dlaczego proponuję tę bootlocal.shmetodę. Wszystko, co mogę powiedzieć, to czystszy wygląd, gdy wystarczy użyć polecenia montowania, tak jak to zrobiłem, bootlocal.shniż w profilu. Ponadto zazwyczaj uważam, że profilemożna go uruchomić wiele razy, a montaż wystarczy uruchomić tylko raz, więc ma to większy sens. Ale oba mogą działać.
Andy
KOCHAM TO! Dziękuję Ci!
Qorbani,
28

Wystąpił również ten problem i wygląda na to, że woluminy lokalne nie są montowane podczas korzystania z platformy docker-machine. Rozwiązaniem hakerskim jest

  1. pobierz bieżący katalog roboczy instancji docker-machine docker-machine ssh <name> pwd

  2. użyj narzędzia wiersza poleceń, takiego jak rsyncskopiowanie folderu do systemu zdalnego

    rsync -avzhe ssh --progress <name_of_folder> username@remote_ip:<result _of_pwd_from_1>.
    

Domyślnym pwd jest / root, więc powyższe polecenie byłoby rsync -avzhe ssh --progress <name_of_folder> username@remote_ip:/root

Uwaga: musisz podać hasło do systemu zdalnego. Możesz szybko utworzyć jedno przez ssh do zdalnego systemu i tworząc hasło.

  1. zmień punkt podłączenia woluminu w docker-compose.ymlpliku z .:/appna/root/<name_of_folder>:/app

  2. biegać docker-compose up -d

Uwaga: jeśli zmiany są dokonywane lokalnie, nie zapomnij uruchomić ponownie, rsyncaby przesłać zmiany do systemu zdalnego.

Nie jest doskonały, ale działa. Trwa problem https://github.com/docker/machine/issues/179

Inne projekty, które próbują rozwiązać ten problem, obejmują docker-rsync

gbozee
źródło
rsync musi być zainstalowany na zdalnym systemie wygląda na to, że `sh: rsync: nie znaleziono rsync: połączenie nieoczekiwanie zamknięte (do tej pory odebrano 0 bajtów) [nadawca] błąd rsync: nie znaleziono polecenia zdalnego (kod 127) w / SourceCache / rsync / rsync -45 / rsync / io.c (453) [sender = 2.6.9] `Jak to działa?
krinker
1
rsync musi być zainstalowany w systemie lokalnym
gbozee
Wykonanie tych kroków całkowicie blokuje mojego hosta digitalocean. Przesyłanie plików przebiega prawidłowo, ale kiedy próbuję ponownie połączyć się z hostem za pomocą docker-machine, otrzymuję exit status 255i muszę całkowicie odtworzyć maszynę.
dsifford
1
Stworzyłem skrypt dla wspomnianego tutaj rozwiązania. Działa na najnowsze docker 1.10i docker-machine 0.6.0 gist.github.com/cristobal/fcb0987871d7e1f7449e
cristobal
@cristobal, wygląda na to, że utworzyłeś skrypt dla rozwiązania montowania, a nie rozwiązania rsync?
Andy,
14

W tej chwili naprawdę nie widzę żadnego sposobu na zamontowanie woluminów na maszynach, więc teraz podejście polegałoby na skopiowaniu lub zsynchronizowaniu potrzebnych plików na komputerze.

Istnieją rozmowy na temat rozwiązania tego problemu w repozytorium github platformy docker-machine. Ktoś wysłał żądanie ściągnięcia implementujące scp na docker-machine i zostało już scalone na master, więc jest bardzo prawdopodobne, że w następnej wersji będzie to zawierać.

Ponieważ nie jest jeszcze wydany, do tej pory zalecałbym, aby jeśli masz swój kod hostowany na github, po prostu sklonuj repozytorium przed uruchomieniem aplikacji

web:
  build: .
  command: git clone https://github.com/my/repo.git; ./repo/run_web.sh
  volumes:
    - .:/app
  ports:
    - "8000:8000"
  links:
    - db:db
    - rabbitmq:rabbit
    - redis:redis

Aktualizacja: Patrząc dalej, odkryłem, że funkcja jest już dostępna w najnowszych plikach binarnych , kiedy je zdobędziesz, będziesz mógł skopiować swój lokalny projekt, wykonując takie polecenie:

docker-machine scp -r . dev:/home/docker/project

Będąc tym ogólną formą:

docker-machine scp [machine:][path] [machine:][path]

Możesz więc kopiować pliki z, do i między komputerami.

Pozdrawiam! 1

claudevandort
źródło
dokumentacja dla docker-machine scp: docs.docker.com/machine/reference/scp
Anthony Dahanne
2
ta metoda jest bardzo powolna :(
Sergej Jevsejev
5

Od października 2017 pojawiło się nowe polecenie dla docker-machine, które załatwia sprawę, ale przed wykonaniem upewnij się, że nie ma nic w katalogu, w przeciwnym razie może się zgubić:

docker-machine mount <machine-name>:<guest-path> <host-path>

Sprawdź dokumentację, aby uzyskać więcej informacji: https://docs.docker.com/machine/reference/mount/

PR ze zmianą: https://github.com/docker/machine/pull/4018

Jorge
źródło
1
Po prostu niewiarygodnie, z dokumentacji Docker Machine (którą utworzyłeś link), jest - dosłownie - niemożliwe, aby wiedzieć, że kolejność w poleceniu jest ...:<guest-path> <host-path>(a nie na odwrót). Coś tak prostego i krytycznego, jak to odnotować w dokumentacji ... po prostu nie jest!
Dan Nissenbaum
Myślę, że nie jest to zbyt wyraźne, masz rację. Trzeba to odgadnąć z listy poleceń
Jorge
To załatwia sprawę, ale w inny sposób. Pozwala na zamontowanie katalogu docker-machine na komputerze lokalnym. Niestety nie pozwala na to w inny sposób :(
ravenwing
4

Jeśli wybierzesz opcję rsync z docker-machine, możesz połączyć ją z takim docker-machine ssh <machinename>poleceniem:

rsync -rvz --rsh='docker-machine ssh <machinename>' --progress <local_directory_to_sync_to> :<host_directory_to_sync_to>

Używa tego formatu polecenia rsync, pozostawiając HOSTpuste:

rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST

( http://linuxcommand.org/man_pages/rsync1.html )

dmh
źródło
1

W końcu dowiedziałem się, jak uaktualnić Windows Docker Toolbox do wersji 1.12.5 i utrzymać moje woluminy w pracy, dodając folder współdzielony w Oracle VM VirtualBoxmenedżerze i wyłączając konwersję ścieżki. Jeśli masz system Windows 10+, najlepiej jest używać nowszego Dockera dla systemu Windows.

Pierwsza aktualizacja Ból:

  1. Najpierw odinstaluj VirtualBox.
    • Tak, to może zepsuć rzeczy w innych narzędziach, takich jak Android Studio. Dzięki Docker :(
  2. Zainstaluj nową wersję Docker Toolbox.

Przykład bazy danych Redis: redis: image: redis:alpine container_name: redis ports: - "6379" volumes: - "/var/db/redis:/data:rw"

W terminalu Docker Quickstart ....

  1. run docker-machine stop default- upewnij się, że maszyna wirtualna została włamana

W Oracle VM VirtualBox Manager ...

  1. Dodano udostępniony folder w defaultmaszynie wirtualnej za pośrednictwem lub wiersza poleceń
    • D:\Projects\MyProject\db => /var/db

W docker-compose.yml...

  1. Zmapowana objętość redis jako: "/var/db/redis:/data:rw"

W terminalu Docker Quickstart ....

  1. Zestaw COMPOSE_CONVERT_WINDOWS_PATHS=0(dla wersji Toolbox> = 1.9.0)
  2. uruchom, docker-machine start defaultaby ponownie uruchomić maszynę wirtualną.
  3. cd D:\Projects\MyProject\
  4. docker-compose up powinno teraz działać.

Teraz tworzy bazę danych redis w D:\Projects\MyProject\db\redis\dump.rdb

Po co unikać względnych ścieżek hostów?

I unikać ścieżek względnych hosta dla systemu Windows Toolbox, ponieważ mogą one wprowadzać nieprawidłowe znaki „\”. Nie jest to tak przyjemne, jak używanie ścieżek względnych, docker-compose.ymlale przynajmniej moi koledzy programiści mogą z łatwością to zrobić, nawet jeśli ich folder projektu znajduje się w innym miejscu bez konieczności hakowania docker-compose.ymlpliku (złe dla SCM).

Pierwotna przyczyna

FYI ... Oto oryginalny błąd, który otrzymałem, gdy użyłem ładnych, czystych ścieżek względnych, które działały dobrze dla starszych wersji. Moje mapowanie wolumenu było kiedyś sprawiedliwe"./db/redis:/data:rw"

ERROR: for redis Cannot create container for service redis: Invalid bind mount spec "D:\\Projects\\MyProject\\db\\redis:/data:rw": Invalid volume specification: 'D:\Projects\MyProject\db\redis:/data

Dzieje się tak z dwóch powodów.

  1. Nie ma dostępu do D:dysku
  2. Ścieżki woluminów nie mogą zawierać \znaków
    • docker-compose dodaje je i obwinia za to !!
    • Użyj, COMPOSE_CONVERT_WINDOWS_PATHS=0aby zatrzymać ten nonsens.

Zalecam udokumentowanie dodatkowego mapowania folderów współdzielonych maszyny wirtualnej w docker-compose.ymlpliku, ponieważ może być konieczne ponowne odinstalowanie VirtualBox i zresetowanie folderu współdzielonego, a mimo to inni programiści będą Cię za to kochać.

Tony O'Hagan
źródło
Pan, jest pan dobrą osobą
AaronHS
1

Wszystkie inne odpowiedzi były dobre na ten czas, ale teraz (Docker Toolbox v18.09.3) wszystko działa po wyjęciu z pudełka. Wystarczy dodać udostępniony folder do maszyny wirtualnej VirtualBox.

Docker Toolbox automatycznie dodaje C:\Usersjako folder współdzielony /c/Userspod wirtualną maszyną linux (używając funkcji folderów współdzielonych Virtual Box), więc jeśli twój docker-compose.ymlplik znajduje się gdzieś pod tą ścieżką i montujesz katalogi maszyny hosta tylko pod tą ścieżką - wszystko powinno działać po wyjęciu z pudełka.

Na przykład:

C:\Users\username\my-project\docker-compose.yml:

...
  volumes:
    - .:/app
...

.Ścieżka automatycznie przekształca się w absolutnym ścieżki C:\Users\username\my-project, a następnie /c/Users/username/my-project. I tak właśnie wygląda ta ścieżka z punktu widzenia maszyny wirtualnej linux (możesz to sprawdzić: docker-machine ssha potem ls /c/Users/username/my-project). Tak więc ostateczny wierzchowiec będzie /c/Users/username/my-project:/app.

Wszystko działa dla Ciebie w sposób przejrzysty.

Ale to nie działa, jeśli ścieżka montowania hosta nie znajduje się pod C:\Usersścieżką. Na przykład, jeśli umieścisz to samo docker-compose.ymlpod D:\dev\my-project.

Można to jednak łatwo naprawić.

  1. Zatrzymaj maszynę wirtualną ( docker-machine stop).
  2. Otwórz interfejs GUI Virtual Box, otwórz Ustawienia maszyny wirtualnej o nazwie default, otwórz Shared Folderssekcję i dodaj nowy folder współdzielony:

    • Ścieżkę foldera: D:\dev
    • Nazwa folderu: d/dev

    Naciśnij OKdwukrotnie i zamknij graficzny interfejs użytkownika Virtual Box.

  3. Uruchom maszynę wirtualną ( docker-machine start).

To wszystko. Wszystkie ścieżki hosta D:\devpowinny teraz działać w docker-compose.ymlmontowaniach.

Rusłan Stelmachenko
źródło
1

Można to zrobić połączenie czarownica z trzech narzędzi: docker-machine mount, rsync,inotifywait

TL; DR

Skrypt oparty na wszystkim poniżej jest tutaj

Powiedzmy, że masz swoje docker-compose.ymli run_web.shw/home/jdcaballerov/web

  1. Zamontuj katalog na komputerze, który ma taką samą ścieżkę, jak na hościedocker-machine machine:/home/jdcaballerov/web /tmp/some_random_dir
  2. Zsynchronizuj zamontowany katalog z katalogiem na hoście rsync -r /home/jdcaballerov/web /tmp/some_random_dir
  3. Synchronizuj przy każdej zmianie plików w Twoim katalogu:

    inotifywait -r -m -e close_write --format '%w%f' /home/jdcaballerov/web | while read CHANGED_FILE
    do
        rsync /home/jdcaballerov/web /tmp/some_random_dir
    done
    

UWAŻAJ - istnieją dwa katalogi, które mają tę samą ścieżkę - jeden znajduje się na komputerze lokalnym (host), a drugi na komputerze docker.

Krucze Skrzydło
źródło
0

Zakładam, że run_web.shplik znajduje się w tym samym katalogu co twój docker-compose.ymlplik. Wtedy polecenie powinno być command: /app/run_web.sh.

Chyba że Dockerfile(którego nie ujawniasz) zajmie się umieszczeniem run_web.shpliku w obrazie Dockera.

Thomasleveil
źródło
dzięki za odpowiedź. Znajduje się w tym samym katalogu. Jednak zauważam, że wolumin nie jest montowany. Pliki nie są dostępne i oto jest pytanie. Jak je dodać. Struktura jest podobna do syncano.com/…
jdcaballerov
Upewnij się, że masz najnowsze wersje zarówno dockera, jak i dicker-compose.
Thomasleveil
docker: Docker w wersji 1.6.0, kompilacja 4749651, docker-machine wersja 0.2.0 (8b9eaf2), docker-compose 1.2.0
jdcaballerov
Czy w jakikolwiek sposób zmodyfikowałeś plik Dockerfile ze strony syncano.com/… ?
Thomasleveil
1
Tak, dodaję kod, tworzę katalog. Problem polega na tym, że kiedy docker-compose wykonuje, nadpisuje wolumin: woluminy: -.: / App i pozostawia pusty katalog. Komentowałem tomy w komponowaniu i to działa.
jdcaballerov
0

Po podsumowaniu postów tutaj, dołączono zaktualizowany skrypt, aby utworzyć dodatkowy punkt montowania hosta i automatyczne montowanie po ponownym uruchomieniu Virtualbox. Opis środowiska pracy, jak poniżej: - Windows 7 - docker-machine.exe wersja 0.7.0 - VirtualBox 5.0.22

    #!env bash

    : ${NAME:=default}
    : ${SHARE:=c/Proj}
    : ${MOUNT:=/c/Proj}
    : ${VBOXMGR:=C:\Program Files\Oracle\VirtualBox\VBoxManage.exe}
    SCRIPT=/mnt/sda1/var/lib/boot2docker/bootlocal.sh

    ## set -x
    docker-machine stop $NAME
    "$VBOXMGR" sharedfolder add $NAME --name c/Proj --hostpath 'c:\' --automount 2>/dev/null || :
    docker-machine start $NAME
    docker-machine env $NAME

    docker-machine ssh $NAME 'echo "mkdir -p $MOUNT" | sudo tee $SCRIPT'
    docker-machine ssh $NAME 'echo "sudo mount -t vboxsf -o rw,user $SHARE $MOUNT" |  sudo tee -a $SCRIPT'
    docker-machine ssh $NAME 'sudo chmod +x /mnt/sda1/var/lib/boot2docker/bootlocal.sh'
    docker-machine ssh $NAME 'sudo /mnt/sda1/var/lib/boot2docker/bootlocal.sh'
    #docker-machine ssh $NAME 'ls $MOUNT'
Jesse
źródło
0

Używam docker-machine 0.12.2 z dyskiem virtualbox na moim komputerze lokalnym. Odkryłem, że istnieje katalog, /hosthome/$(user name)z którego masz dostęp do plików lokalnych.

Benjamin Slabbert
źródło
0

Pomyślałem, że wspomnę, że używam 18.03.1-ce-win65 (17513) w systemie Windows 10 i zauważyłem, że jeśli wcześniej udostępniłeś dysk i zapisałeś poświadczenia, po zmianie hasła docker zacznie mieć objętości zamontowane w pojemnikach jako puste.

Nie daje to żadnej wskazówki, że to, co faktycznie się dzieje, polega na tym, że nie ma teraz dostępu do udostępnionych poświadczeń z pamięci podręcznej. Rozwiązaniem w tym scenariuszu jest zresetowanie poświadczeń za pośrednictwem interfejsu użytkownika (Ustawienia-> Dyski współdzielone) lub wyłączenie, a następnie ponowne włączenie udostępniania dysku i wprowadzenie nowego hasła.

Byłoby użyteczne, gdyby docker-compose podał błąd w takich sytuacjach.

nrjohnstone
źródło