Como montar volumes locais na máquina docker


86

Estou tentando usar docker-machine com docker-compose. O arquivo docker-compose.yml tem as seguintes definições:

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

Ao correr docker-compose up -dtudo vai bem até tentar executar o comando e ocorrer um erro:

Não é possível iniciar o contêiner b58e2dfa503b696417c1c3f49e2714086d4e9999bd71915a53502cb6ef43936d: [8] Erro do sistema: exec: "./run_web.sh": stat ./run_web.sh: nenhum arquivo ou diretório

Os volumes locais não são montados na máquina remota. Qual é a estratégia recomendada para montar os volumes locais com o código dos webapps?


A estrutura do projeto e docker-compose.yml é semelhante a este tutorial syncano.com/…
— jdcaballerov

1
Isso deve estar nos documentos docker-compose como uma dica útil para aqueles que podem começar a usar o compose localmente. Teria me poupado horas de momentos WTF tentando descobrir por que diabos o caminho do meu arquivo estava errado ou não foi encontrado. Não, eu apenas me sinto boba.
— Timbrown de

Respostas:


93

A máquina Docker monta automaticamente o diretório de usuários ... Mas às vezes isso não é suficiente.

Não sei sobre o docker 1.6, mas no 1.8 você PODE adicionar uma montagem adicional à docker-machine

Adicionar Ponto de Montagem de Máquina Virtual (parte 1)

CLI : (só funciona quando a máquina está parada)

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

Portanto, um exemplo no Windows seria

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

GUI : (NÃO requer que a máquina seja parada)

  1. Inicie o "Oracle VM VirtualBox Manager"
  2. Clique com o botão direito <machine name>(padrão)
  3. Configurações...
  4. Pastas partilhadas
  5. A pasta + ícone à direita (adicionar compartilhamento)
  6. Caminho da pasta: <host dir>(e :)
  7. Nome da pasta: <mount name>(e)
  8. Marque "Montagem automática" e "Tornar permanente" (leia apenas se quiser ...) (A montagem automática é meio inútil atualmente ...)

Montagem em boot2docker (parte 2)

Monte manualmente no boot2docker :

  1. Existem várias maneiras de fazer login, use "Mostrar" no "Oracle VM VirtualBox Manager" ou ssh / putty no docker por endereço IP docker-machine ip default, etc ...
  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>

Mas isso só é bom até você reiniciar a máquina, e então a montagem é perdida ...

Adicionando uma montagem automática ao boot2docker :

Enquanto estiver conectado à máquina

  1. Editar / criar (como root) /mnt/sda1/var/lib/boot2docker/bootlocal.sh, sda1 pode ser diferente para você ...
  2. Adicionar

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

Com essas mudanças, você deve ter um novo ponto de montagem. Este é um dos poucos arquivos que encontrei que é chamado na inicialização e é persistente. Até que haja uma solução melhor, isso deve funcionar.


Método antigo: menos recomendado , mas deixado como uma alternativa

  • Editar (como root) /mnt/sda1/var/lib/boot2docker/profile, sda1 pode ser diferente para você ...
  • Adicionar

    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>
    

Como último recurso , você pode escolher a alternativa um pouco mais tediosa e pode apenas modificar a imagem de inicialização.

  • git -c core.autocrlf=false clone https://github.com/boot2docker/boot2docker.git
  • cd boot2docker
  • git -c core.autocrlf=false checkout v1.8.1 #ou sua versão apropriada
  • Editar rootfs/etc/rc.d/automount-shares
  • Adicione a try_mount_share <local_dir> <mount_name>linha logo antes de fi no final. Por exemplo

    try_mount_share /e e
    

    Apenas certifique-se de não configurar o para qualquer coisa que o sistema operacional precise, como / bin, etc ...

  • docker build -t boot2docker . #Isso levará cerca de uma hora na primeira vez :(
  • docker run --rm boot2docker > boot2docker.iso
  • Faça backup do boot2docker.iso antigo e copie o novo em seu lugar, em ~ / .docker / machine / machines /

Isso funciona, é apenas longo e complicado

docker versão 1.8.1, docker-machine versão 0.4.0


Para qualquer um que tenha problemas com isso, tenho quase certeza de que devo fazer com que os caminhos locais correspondam aos da docker-machine. Além disso, docker-compose parecia ter sucesso na montagem dos volumes, enquanto o docker regular não - não sei por quê.
— espiado em

3
Criou um script para a solução mencionada aqui. Funciona no último docker 1.10 e docker-machine 0.6.0 gist.github.com/cristobal/fcb0987871d7e1f7449e
— cristobal

Recursos diferentes falam sobre o uso /mnt/sda1/var/lib/boot2docker/profile, você pode explicar por que mudou para o uso /mnt/sda1/var/lib/boot2docker/bootlocal.sh? Além disso, riscar tanto texto não contribui para a legibilidade da sua resposta ;-)
— Forragem

1
@Forage Point levado sobre minha formatação :). Não me lembro mais por que sugiro o bootlocal.shmétodo. Tudo o que posso dizer é que parece mais limpo apenas usar um comando de montagem como fiz no bootlocal.shdo que no perfil. Além disso, normalmente, acredito que o profilepode ser executado várias vezes, e uma montagem só precisa ser executada uma vez, por isso faz mais sentido. Mas ambos podem funcionar.
— Andy

ADORO! Obrigado!
— Qorbani

28

Também tive esse problema e parece que os volumes locais não são montados ao usar docker-machine. Uma solução de hack é

  1. obter o diretório de trabalho atual da instância docker-machine docker-machine ssh <name> pwd

  2. use uma ferramenta de linha de comando como rsynccopiar a pasta para o sistema remoto

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

O pwd padrão é / root, então o comando acima seria rsync -avzhe ssh --progress <name_of_folder> username@remote_ip:/root

NB: você precisará fornecer a senha para o sistema remoto. Você pode criar um rapidamente por ssh no sistema remoto e criando uma senha.

  1. mude o ponto de montagem do volume em seu docker-compose.ymlarquivo de .:/apppara/root/<name_of_folder>:/app

  2. corre docker-compose up -d

NB: quando as alterações são feitas localmente, não se esqueça de executar novamente rsyncpara enviar as alterações para o sistema remoto.

Não é perfeito, mas funciona. Um problema está em andamento https://github.com/docker/machine/issues/179

Outro projeto que tenta resolver isso inclui docker-rsync


rsync precisa ser instalado no sistema remoto, parece `sh: rsync: não encontrado rsync: conexão fechada inesperadamente (0 bytes recebidos até agora) [remetente] erro rsync: comando remoto não encontrado (código 127) em / SourceCache / rsync / rsync -45 / rsync / io.c (453) [sender = 2.6.9] `Como você fez com que funcionasse?
— Krinker

1
O rsync precisa ser instalado em seu sistema local
— gbozee

Usar essas etapas bloqueia completamente meu host digitalocean. Os arquivos são transferidos sem problemas, mas quando tento reconectar ao host com docker-machine, consigo exit status 255e tenho que recriar completamente a máquina.
— dsifford

1
Criou um script para a solução mencionada aqui. Funciona na mais recente docker 1.10e docker-machine 0.6.0 gist.github.com/cristobal/fcb0987871d7e1f7449e
— cristobal

@cristobal parece que você fez o script da solução de montagem, não da solução rsync?
— Andy

14

No momento, não consigo ver nenhuma maneira de montar volumes em máquinas, então a abordagem agora seria copiar ou sincronizar de alguma forma os arquivos de que você precisa para a máquina.

Há conversas sobre como resolver esse problema no repositório github da docker-machine. Alguém fez uma solicitação de pull implementando scp na docker-machine e já está mesclado no master, então é muito provável que a próxima versão o inclua.

Como ainda não foi lançado, agora eu recomendaria que, se você tem seu código hospedado no github, apenas clone seu repo antes de executar o aplicativo

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

Atualização: Olhando mais além, descobri que o recurso já está disponível nos binários mais recentes , quando você os obtiver, poderá copiar seu projeto local executando um comando como este:

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

Sendo esta a forma geral:

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

Assim, você pode copiar arquivos de, para e entre máquinas.

Saúde! 1


a documentação para docker-machine scp: docs.docker.com/machine/reference/scp
— Anthony Dahanne

2
este método é muito lento :(
— Sergej Jevsejev

5

Desde outubro de 2017, há um novo comando para docker-machine que resolve o problema, mas certifique-se de que não haja nada no diretório antes de executá-lo, caso contrário, ele pode se perder:

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

Verifique os documentos para obter mais informações: https://docs.docker.com/machine/reference/mount/

PR com a mudança: https://github.com/docker/machine/pull/4018


1
Inacreditavelmente, a partir da documentação da Docker Machine (que você vinculou), é - literalmente - impossível saber se a ordem do comando é ...:<guest-path> <host-path>(e não o contrário). Algo tão simples e crítico quanto isso para anotar na documentação ... simplesmente não é!
— Dan Nissenbaum

Acho que não é muito explícito, você tem razão. Tem que ser adivinhado na lista de comandos
— Jorge

Funciona, mas de outra maneira. Ele permite montar o diretório docker-machine em sua máquina local. Infelizmente, não permite outra maneira :(
— ravenwing

4

Se você escolher a opção rsync com docker-machine, poderá combiná-la com o docker-machine ssh <machinename>comando como este:

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

Ele usa este formato de comando de rsync, deixando em HOSTbranco:

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

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


1

Finalmente descobri como atualizar o Windows Docker Toolbox para v1.12.5 e manter meus volumes funcionando adicionando uma pasta compartilhada no Oracle VM VirtualBoxgerenciador e desabilitando a conversão de caminho. Se você tem o Windows 10+, é melhor usar o Docker para Windows mais recente.

Primeiro a dor de atualização:

  1. Desinstale o VirtualBox primeiro.
    • Sim, isso pode quebrar coisas em outras ferramentas como o Android Studio. Obrigado Docker :(
  2. Instale a nova versão do Docker Toolbox.

Exemplo de banco de dados Redis: redis: image: redis:alpine container_name: redis ports: - "6379" volumes: - "/var/db/redis:/data:rw"

No Terminal Docker Quickstart ....

  1. executar docker-machine stop default- Certifique-se de que a VM esteja interrompida

No Oracle VM VirtualBox Manager ...

  1. Adicionada uma pasta compartilhada na defaultVM via ou linha de comando
    • D:\Projects\MyProject\db => /var/db

Em docker-compose.yml...

  1. Volume redis mapeado como: "/var/db/redis:/data:rw"

No Terminal Docker Quickstart ....

  1. Definido COMPOSE_CONVERT_WINDOWS_PATHS=0(para a versão do Toolbox> = 1.9.0)
  2. execute docker-machine start defaultpara reiniciar a VM.
  3. cd D:\Projects\MyProject\
  4. docker-compose up deve funcionar agora.

Agora cria banco de dados redis em D:\Projects\MyProject\db\redis\dump.rdb

Por que evitar caminhos de host relativos?

Eu evitado caminhos de acolhimento relativas para Windows caixa de ferramentas como eles podem introduzir '\' caracteres inválidos. Não é tão bom quanto usar caminhos relativos a, docker-compose.ymlmas pelo menos meus colegas desenvolvedores podem fazer isso facilmente, mesmo se sua pasta de projeto estiver em outro lugar, sem ter que hackear o docker-compose.ymlarquivo (ruim para SCM).

Problema Original

Para sua informação ... Aqui está o erro original que recebi quando usei bons caminhos relativos limpos que costumavam funcionar bem para versões mais antigas. Meu mapeamento de volume costumava ser apenas"./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

Isso quebra por dois motivos ..

  1. Não pode acessar o D:drive
  2. Caminhos de volume não podem incluir \caracteres
    • docker-compose adiciona e depois culpa você por isso !!
    • Use COMPOSE_CONVERT_WINDOWS_PATHS=0para parar com esse absurdo.

Eu recomendo documentar seu mapeamento de pasta compartilhada VM adicional em seu docker-compose.ymlarquivo, pois pode ser necessário desinstalar o VirtualBox novamente e redefinir a pasta compartilhada e, de qualquer forma, seus colegas desenvolvedores vão adorar você por isso.


você senhor, é uma boa pessoa
— AaronHS

1

Todas as outras respostas foram boas para o momento, mas agora (Docker Toolbox v18.09.3) tudo funciona fora da caixa. Você só precisa adicionar uma pasta compartilhada no VirtualBox VM.

O Docker Toolbox adiciona automaticamente C:\Usersuma pasta compartilhada /c/Usersna máquina virtual linux (usando o recurso de pastas compartilhadas do Virtual Box), portanto, se o seu docker-compose.ymlarquivo estiver localizado em algum lugar sob este caminho e você montar os diretórios da máquina host apenas neste caminho - tudo deve funcionar imediatamente.

Por exemplo:

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

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

O .caminho será convertido automaticamente em caminho absoluto C:\Users\username\my-projecte depois em /c/Users/username/my-project. E é exatamente assim que esse caminho é visto do ponto de vista da máquina virtual linux (você pode conferir: docker-machine sshe depois ls /c/Users/username/my-project). Então, a montagem final será /c/Users/username/my-project:/app.

Tudo funciona de forma transparente para você.

Mas isso não funciona se o caminho de montagem do host não estiver sob o C:\Userscaminho. Por exemplo, se você colocar o mesmo docker-compose.ymlem D:\dev\my-project.

Isso pode ser corrigido facilmente.

  1. Pare a máquina virtual ( docker-machine stop).
  2. Abra a GUI do Virtual Box, abra as configurações da máquina virtual nomeada default, abra a Shared Foldersseção e adicione a nova pasta compartilhada:

    • Caminho da pasta: D:\dev
    • Nome da pasta: d/dev

    Pressione OKduas vezes e feche a GUI do Virtual Box.

  3. Inicie a máquina virtual ( docker-machine start).

Isso é tudo. Todos os caminhos da máquina host sob D:\devdevem funcionar agora nas docker-compose.ymlmontagens.


1

Pode ser combinação bruxa feito de três ferramentas: docker-machine mount, rsync,inotifywait

TL; DR

O script baseado em tudo abaixo está aqui

Digamos que você tenha seu docker-compose.ymle run_web.shem/home/jdcaballerov/web

  1. Monte o diretório na máquina que tem o mesmo caminho que você tem em seu hostdocker-machine machine:/home/jdcaballerov/web /tmp/some_random_dir
  2. Sincronize o diretório montado com o dir em seu host rsync -r /home/jdcaballerov/web /tmp/some_random_dir
  3. Sincronize a cada mudança de arquivos em seu diretório:

    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
    

ATENÇÃO - há dois diretórios com o mesmo caminho - um está na máquina local (host), o segundo está na máquina docker.


0

Presumo que o run_web.sharquivo esteja no mesmo diretório do seu docker-compose.ymlarquivo. Então o comando deve ser command: /app/run_web.sh.

A menos Dockerfileque (que você não está divulgando) se encarregue de colocar o run_web.sharquivo na imagem do Docker.


obrigado pela sua resposta. Ele está no mesmo diretório. No entanto, noto que o volume não está sendo aumentado. Os arquivos não estão disponíveis, e essa é a questão. Como adicioná-los. A estrutura é semelhante a syncano.com/…
— jdcaballerov

Certifique-se de ter as versões mais recentes de docker e dicker-compose.
— Thomasleveil

docker: Docker versão 1.6.0, compilação 4749651, docker-machine versão 0.2.0 (8b9eaf2), docker-compose 1.2.0
— jdcaballerov

Você modificou o Dockerfile de syncano.com/… de alguma forma?
— Thomasleveil

1
Sim, eu adiciono o código, crio o diretório. O problema é que quando docker-compose é executado, ele sobrescreve o volume: volumes: -.: / App e deixa um diretório vazio. Comentei volumes na composição e funciona.
— jdcaballerov

0

Depois de resumir as postagens aqui, o script atualizado anexado cria um ponto de montagem de host adicional e montagem automática quando o Virtualbox reiniciar. O resumo do ambiente de trabalho é o seguinte: - Windows 7 - docker-machine.exe versão 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

Estou usando docker-machine 0.12.2 com a unidade virtualbox em minha máquina local. Descobri que existe um diretório /hosthome/$(user name)de onde você tem acesso aos arquivos locais.


0

Pensei em mencionar que estou usando 18.03.1-ce-win65 (17513) no Windows 10 e percebi que, se você compartilhou uma unidade e armazenou as credenciais em cache, depois de alterar sua senha, o docker começará a ter os volumes montados em contêineres em branco.

Não dá nenhuma indicação de que o que realmente está acontecendo é que agora ele não está conseguindo acessar o compartilhado com as credenciais antigas armazenadas em cache. A solução neste cenário é redefinir as credenciais por meio da IU (Configurações-> Unidades compartilhadas) ou desabilitar e, em seguida, reativar o compartilhamento da unidade e inserir a nova senha.

Seria útil se docker-compose fornecesse um erro nessas situações.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.