Qual é a maneira certa de configurar um ambiente de desenvolvimento no OS X com Docker?

94

Introdução

Não consigo descobrir uma boa maneira de configurar um ambiente de desenvolvimento no OS X usando Docker e Boot2Docker. O problema que estou enfrentando é como gerenciar o código-fonte para que:

  1. Posso modificar o código no OS X usando as ferramentas (editor de texto, IDE, git, etc) que já instalei.
  2. Essas modificações são refletidas no contêiner do Docker, portanto, se eu executar novamente os testes ou atualizar uma página da Web, posso ver minhas alterações imediatamente.

Em teoria, isso deve ser fácil de fazer montando meu código-fonte como um volume:

docker run -it -v /path/to/my/source/code:/src some-docker-image

Infelizmente, isso tem dois problemas principais que o tornam completamente inutilizável no OS X:

Problema nº 1: os volumes montados no VirtualBox (que usam vboxsf) são extremamente lentos

Por exemplo, veja quanto tempo Jekyll leva para compilar minha página inicial se o código-fonte fizer parte da imagem Docker:

> docker run -it brikis98/yevgeniy-brikman-homepage:v1 bash

root@7aaea30d98a1:/src# time bundle exec jekyll build

[...]

real    0m7.879s
user    0m7.360s
sys     0m0.600s

Aqui está exatamente a mesma imagem do Docker, só que desta vez, eu monto o código-fonte do OS X:

> docker run -it -v $(pwd):/src brikis98/yevgeniy-brikman-homepage:v1 bash

root@1521b0b4ce6a:/src# time bundle exec jekyll build

[...]

real    1m14.701s
user    0m9.450s
sys     0m3.410s

Problema nº 2: a observação de arquivos está corrompida

Os mecanismos de observação padrão no SBT, Jekyll e grunt usam tecnologias como inotify, que não funcionam se estiverem sendo executados em um contêiner do Docker e as alterações forem feitas no OS X para uma pasta montada.

Soluções alternativas que tentei

Procurei soluções (incluindo todas no SO) e tentei algumas delas, mas não encontrei nenhuma bem-sucedida:

  1. I comutada Boot2Docker usar NFS , mas era tão lento.
  2. Tentei o Vagrant + NFS , e também era lento.
  3. Tentei uma montagem Samba , mas a pasta sempre apareceu vazia no contêiner do Docker.
  4. Tentei usar o sistema de arquivos Unison , que funcionou brevemente para sincronizar arquivos, mas continuou mostrando erros de conexão .
  5. Habilitei a votação no Jekyll , mas isso aumentou significativamente o atraso até que minhas alterações fossem selecionadas.
  6. Experimentei o Dinghy , um "Docker mais rápido e amigável no OS X com Vagrant" e consegui algumas melhorias. Em vez da compilação do Jekyll ser 10-15x mais lenta, foi 2-3x mais lenta. Está melhor, mas ainda não é totalmente utilizável.

Alguém encontrou uma solução que realmente funcione e permita desenvolver código produtivamente com Docker e OS X?

Atualização: enfim uma solução!

Finalmente encontrei uma solução que parece produtiva usando Boot2Docker + rsync. Capturei os detalhes sobre como configurar isso em minha própria resposta , bem como em um projeto de código aberto chamado docker-osx-dev .

Yevgeniy Brikman
fonte
Você tentou o instalador oficial do Docker para OS X junto com o NFS? AFAIK, este não é um problema limitado ao Docker no OS X, mas também ao desenvolvimento baseado em Vagrant no OS X com base (s) de código maior ( temos um problema semelhante, mas com o Vagrant ). Descobri que o NFS é a única solução viável e aceitável.
James Mills
@JamesMills: Segui as instruções oficiais para instalar o Docker e o Boot2Docker. Existem instruções oficiais para configurar o NFS? Eu só os encontrei na essência do GitHub e, depois de usá-los, não pareceu mais rápido. Como você configurou o NFS?
Yevgeniy Brikman
Você já viu github.com/boot2docker/boot2docker/issues/64 ?
James Mills
6
A maneira certa de trabalhar com o Docker é rodar o Linux nativamente em vez do OS X ou fazer todo o seu trabalho de desenvolvimento dentro de uma VM Linux. A integração do "boot2docker" é um grande e feio hack que não faz nada além de semear confusão e decepção.
larsks
7
@larsks: Isso não ajuda.
Yevgeniy Brikman

Respostas:

46

Decidi adicionar minha própria resposta com a melhor solução que encontrei até agora. Vou atualizar isso se encontrar opções melhores.

Melhor solução até agora

A melhor solução que encontrei para configurar um ambiente de desenvolvimento produtivo com Docker no OS X é: Boot2Docker + Rsync . Com o rsync, os tempos de construção em um contêiner do Docker estão no mesmo nível que a execução da construção diretamente no OSX! Além disso, o código do inspetor de arquivos não precisa de pesquisa ( inotifyfunciona, pois o rsync usa pastas normais), então o recarregamento a quente é quase tão rápido.

Existem duas maneiras de configurá-lo: uma instalação automatizada e uma instalação manual.

Instalação automatizada

Eu empacotei todas as etapas para configurar o Boot2Docker com Rsync em um projeto de código aberto chamado docker-osx-dev . O código é um pouco grosseiro, mas tenho usado com sucesso por várias semanas para alternar facilmente entre 3 projetos com 3 pilhas de tecnologia diferentes. Experimente, relate bugs e envie alguns PRs! Além disso, consulte minha postagem do blog, Um ambiente de desenvolvimento produtivo com Docker no OS X para obter mais informações.

Configuração manual

  1. Instale Boot2Docker : brew install boot2docker.
  2. Run Boot2Docker, mas com VirtualBox pastas compartilhadas desativado: boot2docker init && boot2docker start --vbox-share=disable.
  3. Execute boot2docker shellinite copie as variáveis ​​de ambiente que ele imprime em seu ~/.bash_profilearquivo.
  4. Instale rsync na Boot2Docker VM: boot2docker ssh "tce-load -wi rsync".
  5. Crie as pastas básicas de que você precisa na VM Boot2Docker e defina as permissões corretamente para elas. Por exemplo, se você vai ser a sincronização da /foo/barpasta do OS X, você precisa criar /foo/barna Boot2Docker VM: boot2docker ssh "mkdir -p /foo/bar && chown -R docker /foo/bar".
  6. Execute rsync para sincronizar os arquivos para o Boot2Docker VM: rsync --archive --rsh="ssh -i $HOME/.ssh/id_boot2docker -o StrictHostKeyChecking=no" /foo/bar docker@dockerhost:/foo. Verifique os documentos rsync para várias configurações que você pode querer habilitar, como usar --exclude .gitpara excluir a .gitpasta durante a sincronização.
  7. Use um observador de arquivos para manter os arquivos sincronizados. Por exemplo, você pode usar fswatch ( brew install fswatch) canalizado para rsync.
  8. Neste ponto, você deve ser capaz de usar docker runpara disparar o seu recipiente Docker e usar a -vbandeira para montar a pasta que você está sincronizando: docker run -v /foo/bar:/src some-docker-image.
  9. Atualize o código no OS X como de costume. As alterações devem se propagar muito rapidamente usando rsync, o código do inspetor de arquivos normal deve pegar as alterações como de costume (ou seja, usando inotify), e a construção deve ser executada rapidamente porque todos os arquivos são "locais" para o contêiner.
  10. Se você precisar testar um site em execução, execute o boot2docker ipcomando para descobrir em qual IP ele está.
Yevgeniy Brikman
fonte
Obrigado por compartilhar! Quando eles dizem que rsync é "unilateral", isso significa que não posso usar o sistema de arquivos OS X para compartilhar arquivos entre dois contêineres? Exemplo: o contêiner 1 observa os arquivos de origem e compila um binário, o contêiner 2 é usado para executar o binário compilado (usando Haskell neste exemplo).
Nicolas Hery
1
@NicolasHery: Meu entendimento é que o rsync irá copiar as alterações do OS X para o contêiner do Docker, mas não o contrário. Portanto, quaisquer arquivos gerados pelo contêiner do Docker (por exemplo, um binário compilado) não serão visíveis no OS X. No entanto, se esses arquivos forem gerados em uma pasta marcada como um VOLUME, então você pode dar a outro contêiner acesso a esse volume usando o --volumes-frombandeira. Ainda não tentei, mas suspeito que funcionaria.
Yevgeniy Brikman
1
Ótima resposta. Você poderia criar um driver para docker-machine ( github.com/docker/machine ) que faz a maior parte do clichê para você.
dom
1
@dom: Gosto dessa ideia, mas você sabe como criar um driver para docker-machine? Uma solicitação pull no repo é a única maneira ou é possível criar um driver externamente?
Yevgeniy Brikman
1
Este tutorial ainda é válido para uma nova versão 1.9.1 no Windows? Posso usá-lo ou talvez o Docker já tenha uma nova solução para este "problema"?
18

Atualização : agora que o docker para mac está em beta com funcionalidade não hack, seguir esse caminho pode ser muito mais razoável para o desenvolvimento local sem um ensaio de hacks e soluções alternativas.

Não . Eu sei que essa não é a resposta que você provavelmente está esperando, mas faça uma avaliação honesta do custo / benefício de tentar obter o código-fonte local + execução dockerizada versus apenas fazer o desenvolvimento local no OSX.

Em algum ponto, todos os problemas, esforço de configuração e pontos problemáticos operacionais PODEM ser resolvidos bem o suficiente, mas a partir de agora minha opinião sobre isso é uma perda líquida.

Problema nº 1: os volumes montados no Virtual Box (que usam vboxfs) são extremamente lentos

Espere um pouco e isso certamente melhorará.

Problema nº 2: a observação de arquivos está corrompida

Não tenho certeza se uma solução para isso está em um futuro próximo. Se esse tipo de funcionalidade é a chave para o seu fluxo de trabalho de desenvolvimento, eu consideraria isso um problema. Não vale a pena um grande esforço de P&D quando comparado a apenas usar rbenv / bundler para gerenciar suas instalações de jekyll / ruby ​​e executá-las localmente no OSX como as pessoas têm feito com sucesso na última década +.

Assim como "a nuvem" tem envolvimento zero em minha configuração de desenvolvimento local, no momento, docker é uma vitória para teste / preparação / implantação e para execução de bancos de dados e outros componentes de terceiros, mas os aplicativos que estou codificando são executados diretamente no OSX.

Peter Lyons
fonte
1
Eu concordo. Desenvolvemos em OSX e rodamos os aplicativos diretamente dentro do sistema (com live reload etc). Em seguida, quando o aplicativo é concluído, nós o encaixamos para teste, teste e produção.
ItalyPaleAle
4
Hm, isso é um pouco decepcionante. Sempre tive paridade em meus ambientes de preparação / produção. É o desenvolvimento que sempre foi o atípico, já que eu codifico no OS X. A documentação do Docker certamente fez parecer que esse era um problema resolvido. Vou dar mais um dia de esforço e ver se consigo fazer algo funcionar.
Yevgeniy Brikman
Você ainda acha que essa resposta é válida hoje, Peter? Apenas alguns meses depois, mas dado o projeto de @Yevgeniy e apenas 2 problemas que foram corrigidos, talvez o custo / benefício já valha a pena! Não é?
cregox
1
É uma questão de preferência pessoal. Eu ainda não iria mexer com isso por causa da grande quantidade de projetos entre os quais alterno como consultor. Se eu fosse um temporizador trabalhando principalmente no mesmo projeto por semanas / meses, talvez valesse a pena configurar o rsync / fswatch.
Peter Lyons
Docker Toolbox é a maneira certa de fazer isso hoje em dia porque se você usar homebrew ou outro gerenciador de pacotes, as versões da ferramenta docker ficarão fora de sincronia, a menos que sigam o controle de versão como caixa de ferramentas docker.
taco
12

Docker para Mac e Windows deve ser a forma definitiva de desenvolver com Docker no OS X (e Windows). Um produto Docker, o software é um “ambiente integrado e fácil de implantar para criar, montar e enviar aplicativos do Mac ou Windows”. Pretende resolver os problemas apresentados pelo OP. De seu anúncio de 24 de março de 2016 :

  • Mais rápido e confiável: chega de VirtualBox! O mecanismo Docker está sendo executado em uma distribuição Alpine Linux em cima de uma máquina virtual xhyve no Mac OS X ou em uma VM Hyper-V no Windows e essa VM é gerenciada pelo aplicativo Docker. Você não precisa do docker-machine para executar o Docker para Mac e Windows.
  • Integração de ferramentas: Docker para Mac é um aplicativo Mac e Docker para Windows é um aplicativo Windows, incluindo uma interface de usuário nativa e capacidade de atualização automática. O conjunto de ferramentas Docker vem com ele: linha de comando Docker, Docker Compose e linha de comando Docker Notary.
  • Montagem de volume para seu código e dados: o acesso a dados de volume funciona corretamente, incluindo notificações de alteração de arquivo (no Mac, o inotify agora funciona perfeitamente dentro de contêineres para diretórios montados em volume). Isso ativa os ciclos de edição / teste para desenvolvimento “no contêiner”.
  • Fácil acesso a contêineres em execução na rede host local: Docker para Mac e Windows inclui um servidor DNS para contêineres e está integrado ao sistema de rede Mac OS X e Windows. Em um Mac, o Docker pode ser usado mesmo quando conectado a uma VPN corporativa muito restritiva.
  • O Docker para Mac foi arquitetado do zero para ser capaz de se ajustar ao modelo de segurança sandbox do OS X e estamos trabalhando em estreita colaboração com a Apple para conseguir isso.
Quinn Comendant
fonte
Acabei de ver isso outro dia e parece de longe a solução mais promissora. Estou muito animado para tentar assim que sair da versão beta e, se funcionar bem, vou alterá-la para ser a resposta oficialmente aceita.
Yevgeniy Brikman
4
Infelizmente, a versão beta atual (1.11.0-beta7) parece ser tão lenta quanto os outros métodos, então pode demorar um pouco até que seja viável para usar o forum.docker.com/t/…
walterra
3

Isenção de responsabilidade: posso ser tendencioso, já que sou o autor de docker-sync.

Provavelmente tentei todas as soluções nomeadas aqui, incluindo algumas mais (veja a compersion https://github.com/EugenMayer/docker-sync/wiki/Alternatives-to-docker-sync ), mas basicamente falharam no lado de desempenho (a maioria deles) ou na máquina docker (ou nenhum) usado / forçado.

http://docker-sync.io foi construído para unir todas as soluções e fornecer as melhores estratégias (implementação de várias, você pode escolher).

Pode ser usado com rsync (sincronização de 1 via), incluindo correções de permissão para usuários, e com uníssono (sincronização de 2 vias). Ele não força você a entrar na docker-machine ou em um hypervisor específico, nem exige que você tenha o docker para Mac. Funciona com todos eles.

O desempenho EugenMayer / docker-sync / wiki / 4.-Performance não é influenciado, é como se você não tivesse compartilhamentos.

docker-sync e seus observadores de mudanças são otimizados e funcionam com projetos com arquivos de 12k sem problemas.

Experimente, se quiser, eu adoraria ouvir seus comentários!

Eugen Mayer
fonte
2

Eu entendo você! Acho que tentei quase tudo que você tentou e, infelizmente, ainda estava lento. Então me deparei com este comentário https://github.com/boot2docker/boot2docker/issues/64#issuecomment-70689254 que sugere o uso de Vagrant e Parallels em vez de Virtualbox. Isso me permitiu usar nfs e realmente vi um grande aumento de desempenho em meu projeto (Drupal).

Aqui está o arquivo Vagrant. Tudo que você precisa fazer é instalar o vagrant, copiar em um arquivo chamado Vagrantfile e colocá-lo em alguma pasta. Vá para essa pasta e execute um vagrant upboot2docker em vez de seu boot2docker normal.

Vagrant.configure(2) do |config|
  config.vm.box = "parallels/boot2docker"

  config.vm.network "forwarded_port", guest: 80, host: 80

  config.vm.synced_folder(
    "/Users/dicix/work/www", "/vagrant",
    type: 'nfs',
    nfs_udp: true,
    mount_options: %w[actimeo=2],
    bsd__nfs_options: %w[alldirs maproot=root:wheel]
  )
end
Alex Dicianu
fonte
Estou assumindo que isso requer uma instalação paralela?
Yevgeniy Brikman
2

Também estou usando o Vagrant com paralelos e boot2docker ( https://github.com/Parallels/boot2docker-vagrant-box ). O desenvolvimento nunca foi tão fácil para mim. Funciona muito bem com docker-composeconfigurações grandes. Eu realmente não sinto atraso ou consumo massivo de recursos.

É assim que meu se Vagrantfileparece:

Vagrant.configure(2) do |config|

  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.box = "parallels/boot2docker"

  config.vm.synced_folder "/Users", "/Users", type: "nfs", mount_options: ["nolock", "vers=3", "udp"], id: "nfs-sync"

end
David Heidrich
fonte
1

Estou desenvolvendo em um ambiente OS X (meados de 2011 Macbook Air) + Boot2Docker + Docker-compose há algumas semanas. Não encontrei grandes problemas de desempenho, mas evito executar qualquer tipo de construção durante o desenvolvimento (por que não usar algo como jekyll serve --skip-initial-build?). Aqui está um docker-compose.ymlarquivo de exemplo que estou usando:

docker-compose.yml:

test:
  build: .
  volumes:
    - ./client:/src/client
    - ./server:/src/server
    - ./test:/src/test
  command: nodemon --exec jasmine-node -- test/ --verbose --autotest --captureExceptions --color
  environment:
    - DEBUG=*

Dockerfile:

FROM node:0.12

RUN mkdir -p /src
WORKDIR /src

ENV PATH=/src/node_modules/.bin:$PATH

# We add package.json first so that we the
# image build can use the cache as long as the
# contents of package.json hasn't changed.

COPY package.json /src/
RUN npm install --unsafe-perm

COPY . /src

CMD [ "npm", "start" ]
EXPOSE 3000

Às vezes, uso NFS ( http://syskall.com/using-boot2docker-using-nfs-instead-of-vboxsf/ ), mas não notei uma grande diferença de desempenho ao fazer isso.

Para mim, a conveniência de docker-compose up testcolocar meu ambiente em execução simples tem compensado o custo em desempenho (trabalho rotineiramente em vários projetos com pilhas diferentes).

PS: nodemoné um dos poucos observadores de arquivo que funcionam com vboxsf (consulte https://github.com/remy/nodemon/issues/419 ).

Olivier Lalonde
fonte
Mesmo se eu pular a compilação inicial com Jekyll, toda vez que eu alterar um arquivo, ele terá que reconstruir, o que ainda leva cerca de 1-3 minutos se o código-fonte for montado. Isso torna impossível fazer qualquer tipo de desenvolvimento de estilo de alterar e recarregar.
Yevgeniy Brikman
@YevgeniyBrikman Oh, eu não sabia disso :( Acho que a última opção seria ter seu código ativo dentro da VM boot2docker e montá-lo em sua máquina host usando sshfs. Caso contrário, acho que você terá que esperar por melhor desempenho da pasta montada para usar o docker como um ambiente de desenvolvimento.
Olivier Lalonde
-1

É possível fazer o docker funcionar como uma ferramenta de desenvolvimento. Mas vai doer. Documentei o processo aqui:

http://harmingcola.blogspot.com/2015/05/how-to-setup-docker-as-development-tool.html

Harmingcola
fonte
Obrigado por postar, mas como isso resolve os problemas de desempenho com volumes montados?
Yevgeniy Brikman
Ah, desculpe, você não precisa mais usar o vBox para montar nada. Você pode montar pastas por meio da interface normal do docker
harmingcola
-4

Este método é a maneira mais recente (setembro de 2015) e mais fácil de obter a configuração do Docker no Mac: link aqui:

Você instala o Docker usando o link Docker Toolbox para obter instruções aqui:

É um pacote completo de instalação do Docker, que inclui as seguintes ferramentas do Docker:

Máquina Docker para executar o binário docker-machine

Docker Engine para executar o binário do docker

Docker Compose para executar o binário docker-compose

Kitematic, o Docker GUI um shell pré-configurado para um ambiente de linha de comando do Docker

Oracle VM VirtualBox

insira a descrição da imagem aqui

O que há na caixa de ferramentas:

  • Cliente Docker
  • Máquina Docker
  • Docker Compose (somente Mac)
  • Docker Kitematic
  • VirtualBox
rootcript
fonte
3
Sim, mas infelizmente não resolveu o problema originalmente apresentado.
Nick