Quelle est la bonne façon de configurer un environnement de développement sur OS X avec Docker?

94

Intro

Je ne peux pas trouver un bon moyen de configurer un environnement de développement sur OS X à l'aide de Docker et Boot2Docker. Le problème que je rencontre est de savoir comment gérer le code source pour que:

  1. Je peux modifier le code sous OS X en utilisant les outils (éditeur de texte, IDE, git, etc.) que j'ai déjà installés.
  2. Ces modifications sont reflétées dans le conteneur Docker, donc si je réexécute des tests ou actualise une page Web, je peux voir mes modifications immédiatement.

En théorie, cela devrait être facile à faire en montant mon code source sous forme de volume:

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

Malheureusement, cela présente deux problèmes majeurs qui le rendent complètement inutilisable sous OS X:

Problème n ° 1: les volumes montés sur VirtualBox (qui utilisent vboxsf) sont extrêmement lents

Par exemple, voici combien de temps il faut à Jekyll pour compiler ma page d'accueil si le code source fait partie de l'image 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

Voici exactement la même image Docker, sauf que cette fois, je monte le code source depuis 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

Problème n ° 2: la surveillance des fichiers est interrompue

Les mécanismes de surveillance par défaut dans SBT, Jekyll et grunt utilisent des technologies telles que inotify, qui ne fonctionnent pas s'ils s'exécutent dans un conteneur Docker et que les modifications sont apportées dans OS X à un dossier monté.

Solutions de contournement que j'ai essayées

J'ai cherché des solutions (y compris toutes celles sur SO) et en ai essayé quelques-unes, mais je n'ai pas trouvé de solution réussie:

  1. J'ai changé Boot2Docker pour utiliser NFS , mais c'était tout aussi lent.
  2. J'ai essayé Vagrant + NFS , et c'était tout aussi lent.
  3. J'ai essayé un montage Samba , mais le dossier était toujours vide dans le conteneur Docker.
  4. J'ai essayé d'utiliser le système de fichiers Unison , qui a fonctionné brièvement pour synchroniser les fichiers, mais a continué à montrer des erreurs de connexion .
  5. J'ai activé l' interrogation dans Jekyll , mais cela a considérablement augmenté le délai jusqu'à ce que mes modifications soient prises en compte.
  6. J'ai essayé Dinghy , un "Docker plus rapide et plus convivial sur OS X avec Vagrant" et j'ai obtenu quelques améliorations. Au lieu que la compilation Jekyll soit 10 à 15 fois plus lente, elle était 2 à 3 fois plus lente. C'est mieux, mais pas encore tout à fait utilisable.

Quelqu'un a-t-il trouvé une solution qui fonctionne réellement et vous permet de développer du code de manière productive avec Docker et OS X?

Mise à jour: enfin une solution!

J'ai enfin trouvé une solution qui semble productive en utilisant Boot2Docker + rsync. J'ai capturé les détails sur la façon de configurer cela dans ma propre réponse ainsi que dans un projet open source appelé docker-osx-dev .

Yevgeniy Brikman
la source
Vous avez essayé le programme d'installation officiel de Docker pour OS X avec NFS? AFAIK ce n'est pas un problème limité à Docker sur OS X mais aussi au développement basé sur Vagrant sur OS X avec une ou plusieurs bases de code plus grandes ( nous avons un problème similaire mais avec Vagrant ). J'ai trouvé que NFS était la seule solution viable et acceptable.
James Mills
@JamesMills: J'ai suivi les instructions officielles pour installer Docker et Boot2Docker. Existe-t-il des instructions officielles pour configurer NFS? Je ne les ai trouvés que dans un GitHub, et après les avoir utilisés, cela ne semblait pas plus rapide. Comment avez-vous configuré NFS?
Yevgeniy Brikman
6
La bonne façon de travailler avec Docker est d'exécuter Linux de manière native au lieu d'OS X, ou de faire tout votre travail de développement dans une machine virtuelle Linux. L'intégration "boot2docker" est un gros hack laid qui ne fait que semer la confusion et la déception.
larsks
7
@larsks: Ce n'est pas utile.
Yevgeniy Brikman

Réponses:

46

J'ai décidé d'ajouter ma propre réponse avec la meilleure solution que j'ai trouvée jusqu'à présent. Je mettrai à jour ceci si je trouve de meilleures options.

La meilleure solution à ce jour

La meilleure solution que j'ai trouvée pour mettre en place un environnement de développement productif avec Docker sous OS X est: Boot2Docker + Rsync . Avec rsync, les temps de construction dans un conteneur Docker sont comparables à l'exécution de la compilation directement sur OSX! De plus, le code de l'observateur de fichiers n'a pas besoin d'interrogation ( inotifyfonctionne puisque rsync utilise des dossiers normaux), donc le rechargement à chaud est presque aussi rapide.

Il existe deux façons de le configurer: une installation automatisée et une installation manuelle.

Installation automatisée

J'ai regroupé toutes les étapes de configuration de Boot2Docker avec Rsync dans un projet open source appelé docker-osx-dev . Le code est un peu approximatif, mais je l'utilise avec succès depuis plusieurs semaines pour basculer facilement entre 3 projets avec 3 piles technologiques différentes. Essayez-le, signalez les bugs et soumettez des PR! Voir également mon article de blog, Un environnement de développement productif avec Docker sur OS X pour plus d'informations.

Configuration manuelle

  1. Installer Boot2Docker : brew install boot2docker.
  2. Exécutez Boot2Docker, mais avec VirtualBox dossiers partagés handicapés: boot2docker init && boot2docker start --vbox-share=disable.
  3. Exécutez boot2docker shellinitet copiez les variables d'environnement qu'il imprime dans votre ~/.bash_profilefichier.
  4. Installez rsync sur la machine virtuelle Boot2Docker: boot2docker ssh "tce-load -wi rsync".
  5. Créez les dossiers de base dont vous avez besoin sur la VM Boot2Docker et définissez correctement les autorisations pour eux. Par exemple, si vous allez synchronisez le /foo/bardossier à partir de OS X, vous devez créer /foo/barsur la Boot2Docker VM: boot2docker ssh "mkdir -p /foo/bar && chown -R docker /foo/bar".
  6. Exécutez rsync pour synchroniser les fichiers sur la machine virtuelle Boot2Docker: rsync --archive --rsh="ssh -i $HOME/.ssh/id_boot2docker -o StrictHostKeyChecking=no" /foo/bar docker@dockerhost:/foo. Consultez la documentation rsync pour connaître les différents paramètres que vous souhaiterez peut-être activer, comme l'utilisation --exclude .gitpour exclure le .gitdossier lors de la synchronisation.
  7. Utilisez un observateur de fichiers pour synchroniser les fichiers. Par exemple, vous pouvez utiliser fswatch ( brew install fswatch) redirigé vers rsync.
  8. À ce stade, vous devriez être en mesure d'utiliser docker runpour tirer votre conteneur Docker et utiliser le -vdrapeau pour monter le dossier que vous synchronisez: docker run -v /foo/bar:/src some-docker-image.
  9. Mettez à jour le code sur OS X comme d'habitude. Les changements devraient se propager très rapidement en utilisant rsync, le code normal de l'observateur de fichiers devrait prendre les changements comme d'habitude (c'est-à-dire en utilisant inotify), et la construction devrait s'exécuter rapidement car tous les fichiers sont "locaux" pour le conteneur.
  10. Si vous devez tester un site Web en cours d'exécution, exécutez la boot2docker ipcommande pour savoir sur quelle adresse IP il se trouve.
Yevgeniy Brikman
la source
Merci d'avoir partagé! Quand ils disent que rsync est "à sens unique", cela signifie-t-il que je ne peux pas utiliser le système de fichiers OS X pour partager des fichiers entre deux conteneurs? Exemple: le conteneur 1 regarde les fichiers source et compile un binaire, le conteneur 2 est utilisé pour exécuter le binaire compilé (en utilisant Haskell dans cet exemple).
Nicolas Hery
1
@NicolasHery: Je crois comprendre que rsync copiera les modifications d'OS X vers le conteneur Docker, mais pas l'inverse. Par conséquent, tous les fichiers générés par le conteneur Docker (par exemple, un binaire compilé) ne seront pas visibles sous OS X. Cependant, si ces fichiers sont générés dans un dossier marqué comme un VOLUME, vous pouvez donner à un autre conteneur l'accès à ce volume en utilisant le --volumes-fromdrapeau. Je n'ai pas encore essayé cela, mais je pense que cela fonctionnerait.
Yevgeniy Brikman
1
Très bonne réponse. Vous pouvez créer un pilote pour docker-machine ( github.com/docker/machine ) qui effectue la plupart des opérations standard pour vous.
dom
1
@dom: J'aime cette idée, mais savez-vous comment créer un pilote pour docker-machine? Une demande d'extraction dans le dépôt est-elle le seul moyen ou est-il possible de créer un pilote en externe?
Yevgeniy Brikman
1
Ce tutoriel est-il toujours valable pour une nouvelle version 1.9.1 sous Windows? Puis-je l'utiliser ou peut-être que Docker avait déjà une nouvelle solution pour ce "problème"?
18

Mise à jour : maintenant que docker pour mac est en version bêta avec des fonctionnalités non-hack, cette voie peut être beaucoup plus raisonnable pour le développement local sans la valeur d'un essai de hacks et de solutions de contournement.

Ne fais pas ça . Je sais que ce n'est pas la réponse que vous espérez probablement, mais prenez une évaluation honnête du coût / avantage d'essayer d'obtenir du code source local + une exécution dockerisée par rapport au développement local sur OSX.

À un moment donné, tous les problèmes, les efforts de configuration et les problèmes opérationnels PEUVENT être assez bien résolus, mais pour le moment, je pense que c'est une perte nette.

Problème n ° 1: les volumes montés sur Virtual Box (qui utilisent vboxfs) sont extrêmement lents

Attendez un peu et cela s'améliorera presque certainement.

Problème n ° 2: la surveillance des fichiers est interrompue

Je ne suis pas sûr qu'une solution à ce problème se trouve dans un proche avenir. Si ce type de fonctionnalité est la clé de votre flux de travail de développement, je considérerais cela comme un facteur décisif. Cela ne vaut pas un effort de R&D majeur par rapport à l'utilisation de rbenv / bundler pour gérer vos installations jekyll / ruby ​​et à les exécuter localement sur OSX comme les gens le font avec succès depuis plus d'une décennie.

Tout comme "le cloud" n'a aucune implication dans ma configuration de développement local, pour le moment, docker est une victoire pour les tests / la mise en scène / le déploiement et pour l'exécution de bases de données et d'autres composants tiers, mais les applications que je suis en train de coder fonctionnent correctement sur OSX.

Peter Lyons
la source
1
Je suis d'accord. Nous développons sur OSX et exécutons les applications directement dans le système (avec rechargement en direct, etc.). Ensuite, une fois l'application terminée, nous la dockérisons pour les tests, la mise en scène et la production.
ItaliePaleAle
4
Hm, c'est un peu décevant. J'ai toujours eu la parité dans mes environnements de préparation / production. C'est le développement qui a toujours été la valeur aberrante, car je code sur OS X. La documentation Docker donnait certainement l'impression que c'était un problème résolu. Je vais lui donner une autre journée d'efforts et voir si je peux faire fonctionner quelque chose.
Yevgeniy Brikman
Pensez-vous toujours que cette réponse est valable aujourd'hui, Peter? Quelques mois plus tard, mais étant donné le projet de @ Yevgeniy et seulement 2 problèmes qui sont maintenant résolus, peut-être que le rapport coût / avantage en vaut déjà la peine! N'est-ce pas?
cregox
1
C'est une question de préférence personnelle. Je ne voudrais toujours pas jouer avec cela à cause de la quantité de projets que je passe entre eux en tant que consultant. Si j'étais un chronométreur travaillant principalement sur le même projet pendant des semaines / mois, cela pourrait valoir la peine de configurer le truc rsync / fswatch.
Peter Lyons
Docker Toolbox est la bonne façon de procéder de nos jours car si vous utilisez un homebrew ou un autre gestionnaire de packages, les versions de l'outil Docker ne seront pas synchronisées, à moins qu'elles ne suivent le contrôle de version en tant que boîte à outils docker.
taco le
12

Docker pour Mac et Windows sera le moyen définitif de développement avec Docker sur OS X (et Windows). Produit Docker, le logiciel est un «environnement intégré et facile à déployer pour créer, assembler et expédier des applications à partir de Mac ou Windows». Il prétend être en mesure de résoudre les problèmes présentés par le PO. De son annonce du 24 mars 2016 :

  • Plus rapide et plus fiable: plus de VirtualBox! Le moteur Docker s'exécute dans une distribution Alpine Linux sur une machine virtuelle xhyve sous Mac OS X ou sur une machine virtuelle Hyper-V sous Windows, et cette machine virtuelle est gérée par l'application Docker. Vous n'avez pas besoin de docker-machine pour exécuter Docker pour Mac et Windows.
  • Intégration des outils: Docker pour Mac est une application Mac et Docker pour Windows est une application Windows, comprenant une interface utilisateur native et une capacité de mise à jour automatique. L'ensemble d'outils Docker est fourni avec: ligne de commande Docker, Docker Compose et ligne de commande Docker Notary.
  • Montage de volume pour votre code et vos données: l'accès aux données de volume fonctionne correctement, y compris les notifications de changement de fichier (sur Mac, inotify fonctionne désormais de manière transparente à l'intérieur des conteneurs pour les répertoires montés en volume). Cela permet des cycles d'édition / test pour le développement «en conteneur».
  • Accès facile aux conteneurs en cours d'exécution sur le réseau hôte local: Docker pour Mac et Windows comprend un serveur DNS pour les conteneurs et est intégré au système de réseau Mac OS X et Windows. Sur un Mac, Docker peut être utilisé même lorsqu'il est connecté à un VPN d'entreprise très restrictif.
  • Docker pour Mac a été conçu à partir de zéro pour pouvoir s'adapter au modèle de sécurité du bac à sable OS X et nous travaillons en étroite collaboration avec Apple pour y parvenir.
Comendant Quinn
la source
Je viens de voir cela l'autre jour, et cela ressemble de loin à la solution la plus prometteuse. Je suis très heureux de lui donner une chance une fois qu'il sortira de la version bêta, et si cela fonctionne bien, je le changerai pour être la réponse officiellement acceptée.
Yevgeniy Brikman
4
Malheureusement, la version bêta actuelle (1.11.0-beta7) semble être tout aussi lente que les autres méthodes, donc cela peut prendre un certain temps avant que cela ne soit possible d'utiliser forums.docker.com/t
...
3

Avis de non-responsabilité: je suis peut-être partial, car je suis l'auteur de docker-sync.

J'ai probablement essayé toutes les solutions citées ici, y compris d'autres (voir la version https://github.com/EugenMayer/docker-sync/wiki/Alternatives-to-docker-sync ), mais elles ont échoué du côté de performances (la plupart d'entre elles) ou sur la machine docker (ou aucune) utilisée / appliquée.

http://docker-sync.io a été conçu pour fusionner toutes les solutions et fournir les meilleures stratégies (en implémentant plusieurs, vous pouvez choisir).

Il peut être utilisé avec rsync (synchronisation 1 voie), y compris les correctifs d'autorisation pour les utilisateurs, et avec l'unisson (synchronisation 2 voies). Cela ne vous oblige pas à entrer dans docker-machine ou dans un hyperviseur spécifique, et ne vous oblige pas à avoir docker pour Mac. Cela fonctionne avec tous.

Les performances EugenMayer / docker-sync / wiki / 4.-Les performances ne sont pas influencées, c'est comme si vous n'aviez aucun partage.

docker-sync et ses observateurs de changement sont optimisés et fonctionnent avec des projets avec des fichiers 12k sans problème.

Essayez-le, si vous le souhaitez, j'aimerais entendre vos commentaires!

Eugen Mayer
la source
2

Je vous comprends! Je pense que j'ai essayé à peu près tout ce que vous avez essayé et malheureusement c'était encore lent. Puis je suis tombé sur ce commentaire https://github.com/boot2docker/boot2docker/issues/64#issuecomment-70689254 qui suggère d'utiliser Vagrant et Parallels et au lieu de Virtualbox. Cela m'a permis d'utiliser nfs et j'ai en effet vu une grosse amélioration des performances de mon projet (Drupal).

Voici le fichier Vagrant. Tout ce que vous avez à faire est d'installer vagrant, copiez-le dans un fichier appelé Vagrantfile et mettez-le dans un dossier. Allez dans ce dossier et faites simplement un vagrant upau lieu de votre 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
la source
Je suppose que cela nécessite une installation parallèle?
Yevgeniy Brikman
2

J'utilise également Vagrant avec des parallèles et boot2docker ( https://github.com/Parallels/boot2docker-vagrant-box ). Le développement n'a jamais été aussi simple pour moi. Fonctionne très bien avec les docker-composegrandes configurations. Je ne ressens pas vraiment de retard ou de consommation massive de ressources.

Voici à quoi mon Vagrantfileressemble:

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
la source
1

Je développe depuis quelques semaines un environnement OS X (Macbook Air mi-2011) + Boot2Docker + Docker-compose. Je n'ai pas rencontré de problèmes de performances majeurs, mais j'évite d'exécuter toute sorte de build lors du développement (pourquoi ne pas utiliser quelque chose comme jekyll serve --skip-initial-build?). Voici un exemple de docker-compose.ymlfichier que j'utilise:

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

J'utilise parfois NFS ( http://syskall.com/using-boot2docker-using-nfs-instead-of-vboxsf/ ) mais je n'ai pas remarqué une grande différence de performances en le faisant.

Pour moi, la commodité d'un simple docker-compose up test pour faire fonctionner mon environnement a valu le coût en performances (je travaille régulièrement sur plusieurs projets avec des piles différentes).

PS: nodemonest l'un des rares observateurs de fichiers qui fonctionnent avec vboxsf (voir https://github.com/remy/nodemon/issues/419 ).

Olivier Lalonde
la source
Même si je saute la construction initiale avec Jekyll, chaque fois que je change un fichier, il devra reconstruire, ce qui prend toujours de l'ordre de 1 à 3 minutes si le code source est monté. Cela rend impossible toute sorte de développement de style de changement et de rechargement.
Yevgeniy Brikman
@YevgeniyBrikman Oh, je n'étais pas au courant de cela: (Je suppose que la dernière option serait d'avoir votre code dans la VM boot2docker et de le monter sur votre machine hôte en utilisant sshfs. Sinon, je suppose que vous devrez attendre meilleures performances des dossiers montés pour utiliser docker comme environnement de développement
Olivier Lalonde
-1

Faire fonctionner docker comme outil de développement est possible. Mais ça va faire mal. J'ai documenté le processus ici:

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

harmingcola
la source
Merci d'avoir posté, mais comment cela résout-il les problèmes de performances avec les volumes montés?
Yevgeniy Brikman
Ah, désolé, vous n'avez plus besoin d'utiliser vBox pour monter quoi que ce soit. Vous pouvez monter des dossiers via l'interface standard du docker
harmingcola
-4

Cette méthode est la dernière (septembre 2015) et le moyen le plus simple de configurer Docker sur Mac: lien ici:

Vous installez Docker à l'aide du lien Docker Toolbox vers les instructions ici:

Il s'agit d'un package d'installation Docker complet, qui comprend les outils Docker suivants:

Docker Machine pour exécuter le binaire docker-machine

Docker Engine pour exécuter le binaire docker

Docker Compose pour exécuter le binaire docker-compose

Kitematic, l'interface graphique Docker un shell préconfiguré pour un environnement de ligne de commande Docker

Oracle VM VirtualBox

entrez la description de l'image ici

Que contient la boîte à outils:

  • Client Docker
  • Machine Docker
  • Docker Compose (Mac uniquement)
  • Kitematic Docker
  • VirtualBox
Rootscript
la source
3
Oui mais cela n'a malheureusement pas résolu le problème initialement présenté.
Nick