Come montare i volumi locali nella macchina docker


85

Sto cercando di utilizzare docker-machine con docker-compose. Il file docker-compose.yml ha le seguenti definizioni:

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

Quando si esegue docker-compose up -dtutto va bene fino a quando si tenta di eseguire il comando e viene prodotto un errore:

Impossibile avviare il contenitore b58e2dfa503b696417c1c3f49e2714086d4e9999bd71915a53502cb6ef43936d: [8] Errore di sistema: exec: "./run_web.sh": stat ./run_web.sh: nessun file o directory di questo tipo

I volumi locali non sono montati sulla macchina remota. Qual è la strategia consigliata per montare i volumi locali con il codice delle webapp?


La struttura del progetto e docker-compose.yml è simile a questo tutorial syncano.com/…
jdcaballerov

1
Questo dovrebbe essere nei documenti docker-compose come utile suggerimento per coloro che potrebbero iniziare a utilizzare Compose localmente. Mi avrebbe risparmiato ore di momenti WTF cercando di capire perché diamine il percorso del mio file era sbagliato o non trovato. No, mi sento solo stupido.
timbrown

Risposte:


93

Docker-machine monta automaticamente la directory degli utenti ... Ma a volte questo non è sufficiente.

Non so su finestra mobile 1.6, ma in 1.8 si POSSO aggiungere un ulteriore supporto alla finestra mobile-machine

Aggiungi punto di montaggio della macchina virtuale (parte 1)

CLI : (funziona solo quando la macchina è ferma)

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

Quindi un esempio in Windows sarebbe

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

GUI : (NON richiede l'arresto della macchina)

  1. Avvia "Oracle VM VirtualBox Manager"
  2. Fare clic con il <machine name>pulsante destro del mouse (impostazione predefinita)
  3. Impostazioni...
  4. Cartelle condivise
  5. La cartella + icona a destra (Aggiungi condivisione)
  6. Percorso cartella: <host dir>(e :)
  7. Nome cartella: <mount name>(e)
  8. Seleziona "Auto-mount" e "Make Permanent" (Leggi solo se vuoi ...) (L'auto-mount è una specie di inutile attualmente ...)

Montaggio in boot2docker (parte 2)

Montare manualmente in boot2docker :

  1. Esistono vari modi per accedere, utilizzare "Mostra" in "Oracle VM VirtualBox Manager" o ssh / putty nella finestra mobile tramite indirizzo IP docker-machine ip default, ecc ...
  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>

Ma questo è buono solo fino a quando non riavvii la macchina, quindi il supporto è perso ...

Aggiungere un automount a boot2docker :

Durante l'accesso alla macchina

  1. Modifica / crea (come root) /mnt/sda1/var/lib/boot2docker/bootlocal.sh, sda1 potrebbe essere diverso per te ...
  2. Inserisci

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

Con queste modifiche, dovresti avere un nuovo punto di montaggio. Questo è uno dei pochi file che ho trovato che viene chiamato all'avvio ed è persistente. Fino a quando non ci sarà una soluzione migliore, dovrebbe funzionare.


Vecchio metodo: meno consigliato , ma lasciato come alternativa

  • Modifica (come root) /mnt/sda1/var/lib/boot2docker/profile, sda1 potrebbe essere diverso per te ...
  • Inserisci

    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>
    

Come ultima risorsa , puoi prendere l'alternativa leggermente più noiosa e puoi semplicemente modificare l'immagine di avvio.

  • git -c core.autocrlf=false clone https://github.com/boot2docker/boot2docker.git
  • cd boot2docker
  • git -c core.autocrlf=false checkout v1.8.1 # o la versione appropriata
  • modificare rootfs/etc/rc.d/automount-shares
  • Aggiungi una try_mount_share <local_dir> <mount_name>linea subito prima di fi alla fine. Per esempio

    try_mount_share /e e
    

    Assicurati solo di non impostare nulla di cui il sistema operativo ha bisogno, come / bin, ecc ...

  • docker build -t boot2docker . # Questa operazione richiederà circa un'ora la prima volta :(
  • docker run --rm boot2docker > boot2docker.iso
  • Esegui il backup del vecchio boot2docker.iso e copia quello nuovo al suo posto, in ~ / .docker / machine / machines /

Funziona, è solo lungo e complicato

docker versione 1.8.1, docker-machine versione 0.4.0


Per chiunque abbia problemi con questo, sono abbastanza sicuro che ho dovuto fare in modo che i percorsi locali corrispondessero a quelli nella docker-machine. Anche docker-compose sembrava riuscire a montare i volumi mentre il normale docker no, non so perché.
spieden

3
Creato uno script per la soluzione menzionata qui. Funziona sull'ultima finestra mobile 1.10 e docker-machine 0.6.0 gist.github.com/cristobal/fcb0987871d7e1f7449e
cristobal

Diverse risorse parlano di utilizzo /mnt/sda1/var/lib/boot2docker/profile, puoi spiegare perché sei passato all'utilizzo /mnt/sda1/var/lib/boot2docker/bootlocal.sh? Inoltre, colpire tutto questo testo non contribuisce alla leggibilità della tua risposta ;-)
Forage

1
@Forage Point preso sulla mia formattazione :). Non ricordo più da vicino perché suggerisco più il bootlocal.shmetodo. Tutto quello che posso dire è che sembra più pulito usare solo un comando di montaggio come ho fatto io in bootlocal.shrispetto a quanto fa nel profilo. Inoltre, in genere, credo che profilepotrebbe essere eseguito più volte e un montaggio deve essere eseguito solo una volta, quindi ha più senso. Ma entrambi possono funzionare.
Andy

LO ADORO! Grazie!
Qorbani

28

Inoltre ha riscontrato questo problema e sembra che i volumi locali non siano montati quando si utilizza docker-machine. Una soluzione hack è quella di

  1. ottenere la directory di lavoro corrente dell'istanza docker-machine docker-machine ssh <name> pwd

  2. utilizzare uno strumento da riga di comando come rsynccopiare la cartella sul sistema remoto

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

Il pwd predefinito è / root quindi il comando sopra sarebbe rsync -avzhe ssh --progress <name_of_folder> username@remote_ip:/root

NB: è necessario fornire la password per il sistema remoto. È possibile crearne uno rapidamente tramite ssh nel sistema remoto e creare una password.

  1. cambia il punto di montaggio del volume nel tuo docker-compose.ymlfile da .:/appa/root/<name_of_folder>:/app

  2. correre docker-compose up -d

NB quando le modifiche vengono effettuate localmente, non dimenticare di rieseguire rsyncper inviare le modifiche al sistema remoto.

Non è perfetto ma funziona. È in corso un problema https://github.com/docker/machine/issues/179

Altri progetti che tentano di risolvere questo problema includono docker-rsync


rsync deve essere installato sul sistema remoto sembra `sh: rsync: non trovato rsync: connessione chiusa inaspettatamente (0 byte ricevuti finora) [mittente] errore rsync: comando remoto non trovato (codice 127) in / SourceCache / rsync / rsync -45 / rsync / io.c (453) [sender = 2.6.9] `Come hai fatto a farlo funzionare?
krinker

1
rsync deve essere installato sul tuo sistema locale
gbozee

L'utilizzo di questi passaggi blocca completamente il mio host digitalocean. Il trasferimento dei file è andato a buon fine, ma quando provo a ricollegarmi all'host con docker-machine, ottengo exit status 255e devo ricreare completamente la macchina.
dsifford,

1
Creato uno script per la soluzione menzionata qui. Funziona su ultimo docker 1.10e docker-machine 0.6.0 gist.github.com/cristobal/fcb0987871d7e1f7449e
cristobal

@cristobal sembra che tu abbia scritto la soluzione di montaggio, non la soluzione rsync?
Andy

14

Al momento non riesco davvero a vedere alcun modo per montare i volumi sulle macchine, quindi l'approccio ormai sarebbe copiare o sincronizzare in qualche modo i file necessari nella macchina.

Ci sono conversazioni su come risolvere questo problema nel repository GitHub della docker-machine. Qualcuno ha fatto una richiesta pull implementando scp su docker-machine ed è già unito su master, quindi è molto probabile che la prossima versione lo includa.

Dato che non è ancora stato rilasciato, a questo punto ti consiglierei se il tuo codice è ospitato su GitHub, basta clonare il tuo repository prima di eseguire l'app

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

Aggiornamento: Guardando oltre ho scoperto che la funzionalità è già disponibile negli ultimi binari , quando li ottieni sarai in grado di copiare il tuo progetto locale eseguendo un comando come questo:

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

Essendo questa la forma generale:

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

Quindi puoi copiare file da, verso e tra macchine.

Salute! 1


la documentazione per docker-machine scp: docs.docker.com/machine/reference/scp
Anthony Dahanne

2
questo metodo è molto lento :(
Sergej Jevsejev

5

Da ottobre 2017 c'è un nuovo comando per docker-machine che fa il trucco, ma assicurati che non ci sia nulla nella directory prima di eseguirlo, altrimenti potrebbe perdersi:

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

Controlla i documenti per maggiori informazioni: https://docs.docker.com/machine/reference/mount/

PR con la modifica: https://github.com/docker/machine/pull/4018


1
Incredibilmente, dalla documentazione di Docker Machine (che hai collegato), è - letteralmente - impossibile sapere che l'ordine nel comando è ...:<guest-path> <host-path>(piuttosto che il contrario). Qualcosa di così semplice e critico come quello da notare nella documentazione ... semplicemente non lo è!
Dan Nissenbaum

Immagino che non sia molto esplicito, hai ragione. Deve essere indovinato dalla lista dei comandi
Jorge

Fa il trucco, ma in un altro modo. Permette di montare la directory docker-machine sulla macchina locale. Sfortunatamente non consente altro modo :(
ravenwing

4

Se scegli l'opzione rsync con docker-machine, puoi combinarla con il docker-machine ssh <machinename>comando in questo modo:

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

Usa questo formato di comando di rsync, lasciando HOSTvuoto:

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

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


1

Finalmente ho capito come aggiornare Windows Docker Toolbox alla v1.12.5 e mantenere i miei volumi funzionanti aggiungendo una cartella condivisa nel Oracle VM VirtualBoxgestore e disabilitando la conversione del percorso. Se hai Windows 10 o versioni successive, è meglio utilizzare il nuovo Docker per Windows.

1 ° l'aggiornamento Pain:

  1. Disinstallare prima VirtualBox.
    • Sì, questo potrebbe rompere le cose in altri strumenti come Android Studio. Grazie Docker :(
  2. Installa la nuova versione di Docker Toolbox.

Esempio di database Redis: redis: image: redis:alpine container_name: redis ports: - "6379" volumes: - "/var/db/redis:/data:rw"

In Docker Quickstart Terminal ...

  1. run docker-machine stop default: assicurati che la VM sia invasa

In Oracle VM VirtualBox Manager ...

  1. Aggiunta una cartella condivisa nella defaultVM tramite o riga di comando
    • D:\Projects\MyProject\db => /var/db

In docker-compose.yml...

  1. Volume redis mappato come: "/var/db/redis:/data:rw"

In Docker Quickstart Terminal ...

  1. Set COMPOSE_CONVERT_WINDOWS_PATHS=0(per versione Toolbox> = 1.9.0)
  2. eseguire docker-machine start defaultper riavviare la VM.
  3. cd D:\Projects\MyProject\
  4. docker-compose up dovrebbe funzionare ora.

Ora crea il database redis in D:\Projects\MyProject\db\redis\dump.rdb

Perché evitare percorsi host relativi?

Ho evitato percorsi host relativi per Windows Toolbox in quanto potrebbero introdurre caratteri "\" non validi. Non è bello come usare i percorsi relativi a, docker-compose.ymlma almeno i miei colleghi sviluppatori possono farlo facilmente anche se la loro cartella del progetto è altrove senza dover hackerare il docker-compose.ymlfile (male per SCM).

Emissione originale

Cordiali saluti ... Ecco l'errore originale che ho ricevuto quando ho usato dei percorsi relativi puliti che funzionavano bene per le versioni precedenti. La mia mappatura del volume era giusta"./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

Questo si interrompe per due motivi ..

  1. Non può accedere D:all'unità
  2. I percorsi dei volumi non possono includere \caratteri
    • docker-compose li aggiunge e poi te ne accusa !!
    • Usa COMPOSE_CONVERT_WINDOWS_PATHS=0per fermare queste sciocchezze.

Consiglio di documentare la mappatura della cartella condivisa della VM aggiuntiva nel docker-compose.ymlfile poiché potrebbe essere necessario disinstallare nuovamente VirtualBox e reimpostare la cartella condivisa e comunque i tuoi colleghi sviluppatori ti adoreranno per questo.


signore, siete una brava persona
AaronHS

1

Tutte le altre risposte erano buone per il momento, ma ora (Docker Toolbox v18.09.3) funziona tutto fuori dagli schemi. Hai solo bisogno di aggiungere una cartella condivisa nella VM VirtualBox.

Docker Toolbox aggiunge automaticamente C:\Userscome cartella condivisa /c/Userssotto la macchina Linux virtuale (utilizzando la funzione cartelle condivise di Virtual Box), quindi se il tuo docker-compose.ymlfile si trova da qualche parte sotto questo percorso e monti le directory della macchina host solo sotto questo percorso, tutto dovrebbe funzionare immediatamente.

Per esempio:

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

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

Il .percorso verrà convertito automaticamente in percorso assoluto C:\Users\username\my-projecte quindi in /c/Users/username/my-project. Ed è esattamente così che viene visto questo percorso dal punto di vista della macchina virtuale linux (puoi verificarlo: docker-machine sshe poi ls /c/Users/username/my-project). Quindi, la cavalcatura finale sarà/c/Users/username/my-project:/app .

Tutto funziona in modo trasparente per te.

Ma questo non funziona se il percorso di montaggio dell'host non è in C:\Userspath. Ad esempio, se metti lo stesso docker-compose.ymlsotto D:\dev\my-project.

Questo può essere risolto facilmente però.

  1. Arresta la macchina virtuale ( docker-machine stop).
  2. Apri la GUI della Virtual Box, apri le Impostazioni della Macchina Virtuale denominata default, apri la Shared Folderssezione e aggiungi la nuova cartella condivisa:

    • Percorso cartella: D:\dev
    • Nome della cartella: d/dev

    Premere OKdue volte e chiudere la GUI di Virtual Box.

  3. Avvia la macchina virtuale ( docker-machine start).

È tutto. Tutti i percorsi della macchina host sotto D:\devdovrebbero ora funzionare in docker-compose.ymlmount.


1

Può essere combinazione strega fatta di tre strumenti: docker-machine mount, rsync,inotifywait

TL; DR

Lo script basato su tutto ciò che segue è qui

Diciamo che hai il tuo docker-compose.ymle run_web.shdentro/home/jdcaballerov/web

  1. Directory di montaggio sulla macchina che ha lo stesso percorso che hai sul tuo hostdocker-machine machine:/home/jdcaballerov/web /tmp/some_random_dir
  2. Sincronizza la directory montata con dir sul tuo host rsync -r /home/jdcaballerov/web /tmp/some_random_dir
  3. Sincronizza ad ogni cambio di file nella tua directory:

    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
    

ATTENZIONE : ci sono due directory che hanno lo stesso percorso: una è sulla macchina locale (host), la seconda è sulla macchina docker.


0

Presumo che il run_web.shfile si trovi nella stessa directory del tuo docker-compose.ymlfile. Quindi il comando dovrebbe essere command: /app/run_web.sh.

A meno che il Dockerfile(che non stai rivelando) si occupi di inserire il run_web.shfile nell'immagine Docker.


grazie per la tua risposta. È nella stessa directory. Tuttavia ho notato che il volume non viene montato. I file non sono disponibili e questo è il problema. Come aggiungerli. La struttura è simile a syncano.com/…
jdcaballerov

Assicurati di disporre delle ultime versioni di docker e dicker-compose.
Thomasleveil

docker: Docker versione 1.6.0, build 4749651, docker-machine versione 0.2.0 (8b9eaf2), docker-compose 1.2.0
jdcaballerov

Hai modificato in qualche modo il Dockerfile di syncano.com/… ?
Thomasleveil

1
Sì, aggiungo il codice, creo la directory. Il problema è che quando docker-compose viene eseguito sovrascrive il volume: volumi: -.: / App e lascia una directory vuota. Ho commentato i volumi in composizione e funziona.
jdcaballerov

0

Dopo aver riassunto i post qui, allegato lo script aggiornato, per creare un punto di montaggio host aggiuntivo e montare automaticamente al riavvio di Virtualbox. Il riassunto dell'ambiente di lavoro come di seguito: - Windows 7 - docker-machine.exe versione 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'

0

Sto usando docker-machine 0.12.2 con l'unità virtualbox sulla mia macchina locale. Ho scoperto che esiste una directory /hosthome/$(user name)da cui hai accesso ai file locali.


0

Ho pensato di menzionare che ho utilizzato 18.03.1-ce-win65 (17513) su Windows 10 e ho notato che se in precedenza hai condiviso un'unità e memorizzato nella cache le credenziali, una volta modificata la password, la finestra mobile inizierà ad avere i volumi montati all'interno dei contenitori come vuoti.

Non fornisce alcuna indicazione che ciò che sta effettivamente accadendo è che ora non riesce ad accedere alla condivisione con le vecchie credenziali memorizzate nella cache. La soluzione in questo scenario è reimpostare le credenziali tramite l'interfaccia utente (Impostazioni-> Unità condivise) o disabilitare, quindi riattivare la condivisione dell'unità e inserire la nuova password.

Sarebbe utile se docker-compose fornisse un errore in queste situazioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.