Was ist der richtige Weg, um mit Docker eine Entwicklungsumgebung unter OS X einzurichten?

94

Intro

Ich kann keinen guten Weg finden, um eine Entwicklungsumgebung unter OS X mit Docker und Boot2Docker einzurichten. Das Problem, auf das ich stoße, ist, wie der Quellcode so verwaltet wird, dass:

  1. Ich kann den Code unter OS X mit den bereits installierten Tools (Texteditor, IDE, Git usw.) ändern.
  2. Diese Änderungen werden im Docker-Container angezeigt. Wenn ich also Tests erneut ausführe oder eine Webseite aktualisiere, kann ich meine Änderungen sofort sehen.

Theoretisch sollte dies einfach sein, indem Sie meinen Quellcode als Volume bereitstellen:

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

Leider hat dies zwei Hauptprobleme, die es unter OS X völlig unbrauchbar machen:

Problem Nr. 1: Bereitgestellte Volumes auf VirtualBox (die vboxsf verwenden) sind extrem langsam

Hier ist zum Beispiel, wie lange Jekyll braucht, um meine Homepage zu kompilieren, wenn der Quellcode Teil des Docker-Images ist:

> 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

Hier ist genau das gleiche Docker-Image, außer dass ich diesmal den Quellcode von OS X einbinde:

> 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

Problem Nr. 2: Die Dateiüberwachung ist fehlerhaft

Die Standardüberwachungsmechanismen in SBT, Jekyll und Grunt verwenden Technologien wie inotify, die nicht funktionieren, wenn sie in einem Docker-Container ausgeführt werden und die Änderungen in OS X an einem bereitgestellten Ordner vorgenommen werden.

Problemumgehungen Ich habe es versucht

Ich habe nach Lösungen gesucht (einschließlich aller auf SO) und einige davon ausprobiert, aber keine erfolgreiche gefunden:

  1. Ich habe Boot2Docker auf NFS umgestellt , aber es war genauso langsam.
  2. Ich habe Vagrant + NFS ausprobiert , und das war auch genauso langsam.
  3. Ich habe versucht, ein Samba-Mount zu verwenden , aber der Ordner wurde im Docker-Container immer leer angezeigt.
  4. Ich habe versucht, das Unison-Dateisystem zu verwenden , das kurz zum Synchronisieren von Dateien diente, dann aber weiterhin Verbindungsfehler zeigte .
  5. Ich habe die Abfrage in Jekyll aktiviert , aber das hat die Verzögerung erheblich erhöht, bis meine Änderungen übernommen wurden.
  6. Ich habe Dinghy ausprobiert , einen "schnelleren, freundlicheren Docker unter OS X mit Vagrant" und einige Verbesserungen erzielt. Anstatt dass die Jekyll-Kompilierung 10-15x langsamer war, war sie 2-3x langsamer. Das ist besser, aber immer noch nicht ganz brauchbar.

Hat jemand eine Lösung gefunden, die tatsächlich funktioniert und es Ihnen ermöglicht, Code mit Docker und OS X produktiv zu entwickeln?

Update: endlich eine Lösung!

Ich habe endlich eine Lösung gefunden, die mit Boot2Docker + rsync produktiv erscheint. Ich habe die Details zum Einrichten in meiner eigenen Antwort sowie in einem Open-Source-Projekt namens docker-osx-dev festgehalten .

Jewgenij Brikman
quelle
Sie haben das offizielle Docker-Installationsprogramm für OS X direkt zusammen mit NFS ausprobiert? AFAIK Dies ist kein Problem, das auf Docker unter OS X beschränkt ist, sondern auch auf Vagrant-basierte Entwicklung unter OS X mit größeren Codebasen ( wir haben ein ähnliches Problem, aber mit Vagrant ). Ich habe festgestellt, dass NFS die einzig praktikable und akzeptable Lösung ist.
James Mills
@ JamesMills: Ich habe die offiziellen Anweisungen zur Installation von Docker und Boot2Docker befolgt. Gibt es offizielle Anweisungen zum Einrichten von NFS? Ich habe sie nur in einem GitHub-Gist gefunden, und nachdem ich sie verwendet habe, schien es nicht schneller zu sein. Wie haben Sie NFS eingerichtet?
Jewgenij Brikman
Haben Sie github.com/boot2docker/boot2docker/issues/64 gesehen ?
James Mills
6
Die richtige Art, mit Docker zu arbeiten, besteht darin, Linux nativ anstelle von OS X auszuführen oder Ihre gesamte Entwicklungsarbeit in einer Linux-VM auszuführen. Die "boot2docker" -Integration ist ein großer hässlicher Hack, der nur Verwirrung und Enttäuschung stiftet.
Larsks
7
@larsks: Das ist nicht hilfreich.
Jewgenij Brikman

Antworten:

46

Ich habe beschlossen, meine eigene Antwort mit der besten Lösung hinzuzufügen, die ich bisher gefunden habe. Ich werde dies aktualisieren, wenn ich bessere Optionen finde.

Beste Lösung bisher

Die beste Lösung, die ich zum Einrichten einer produktiven Entwicklungsumgebung mit Docker unter OS X gefunden habe, ist: Boot2Docker + Rsync . Mit rsync entsprechen die Build-Zeiten in einem Docker-Container der Ausführung des Builds direkt unter OSX! Darüber hinaus muss der Dateiüberwachungscode nicht abgefragt werden ( inotifyfunktioniert, da rsync normale Ordner verwendet), sodass das Hot-Reload fast genauso schnell ist.

Es gibt zwei Möglichkeiten, es einzurichten: eine automatisierte Installation und eine manuelle Installation.

Automatisierte Installation

Ich habe alle Schritte zum Einrichten von Boot2Docker mit Rsync in ein Open Source-Projekt namens docker-osx-dev gepackt . Der Code ist etwas rau, aber ich benutze ihn seit mehreren Wochen erfolgreich, um einfach zwischen 3 Projekten mit 3 verschiedenen Tech-Stacks zu wechseln. Probieren Sie es aus, melden Sie Fehler und reichen Sie einige PRs ein! Siehe auch meinen Blog-Beitrag,Weitere Informationen finden Eine produktive Entwicklungsumgebung mit Docker unter OS X.

Manuelle Einrichtung

  1. Installieren Sie Boot2Docker : brew install boot2docker.
  2. Führen Sie Boot2Docker aus, jedoch mit deaktivierten freigegebenen VirtualBox-Ordnern : boot2docker init && boot2docker start --vbox-share=disable.
  3. Führen Sie boot2docker shellinitdie Umgebungsvariablen aus und kopieren Sie sie in Ihre ~/.bash_profileDatei.
  4. Installieren Sie rsync auf der Boot2Docker-VM : boot2docker ssh "tce-load -wi rsync".
  5. Erstellen Sie die Basisordner, die Sie auf der Boot2Docker-VM benötigen, und legen Sie die Berechtigungen für sie korrekt fest. Wenn Sie beispielsweise den /foo/barOrdner unter OS X synchronisieren , müssen Sie ihn erstellen/foo/bar Folgendes auf der Boot2Docker-VM : boot2docker ssh "mkdir -p /foo/bar && chown -R docker /foo/bar".
  6. Führen Sie rsync aus, um die Dateien mit der Boot2Docker-VM zu synchronisieren : rsync --archive --rsh="ssh -i $HOME/.ssh/id_boot2docker -o StrictHostKeyChecking=no" /foo/bar docker@dockerhost:/foo. Überprüfen Sie die rsync-Dokumente auf verschiedene Einstellungen, die Sie möglicherweise aktivieren möchten, z. B. --exclude .gitzum Ausschließen von.git Ordners bei der Synchronisierung.
  7. Verwenden Sie einen Datei-Watcher, um Dateien synchron zu halten. Zum Beispiel könnten Sie fswatch verwenden (brew install fswatch ) verwenden, das in rsync geleitet wird.
  8. Zu diesem Zeitpunkt sollten Sie in der Lage sein, docker runIhren Docker-Container zu starten und das -vFlag zum Mounten des zu synchronisierenden Ordners zu verwenden:docker run -v /foo/bar:/src some-docker-image .
  9. Aktualisieren Sie den Code unter OS X wie gewohnt. Änderungen sollten mit rsync sehr schnell weitergegeben werden, der normale Dateiüberwachungscode sollte die Änderungen wie gewohnt übernehmen (dh verwenden inotify) und der Build sollte schnell ausgeführt werden, da alle Dateien im Container "lokal" sind.
  10. Wenn Sie eine laufende Website testen müssen, führen Sie den boot2docker ipBefehl aus, um herauszufinden, auf welcher IP sie sich befindet.
Jewgenij Brikman
quelle
Danke für das Teilen! Wenn sie sagen, dass rsync "nur in eine Richtung" ist, bedeutet dies, dass ich das OS X-Dateisystem nicht zum Freigeben von Dateien zwischen zwei Containern verwenden kann? Beispiel: Container 1 überwacht Quelldateien und kompiliert eine Binärdatei. Container 2 wird zum Ausführen der kompilierten Binärdatei verwendet (in diesem Beispiel mit Haskell).
Nicolas Hery
1
@NicolasHery: Ich verstehe, dass rsync Änderungen von OS X in den Docker-Container kopiert, aber nicht umgekehrt. Daher werden alle vom Docker-Container generierten Dateien (z. B. eine kompilierte Binärdatei) in OS X nicht angezeigt. Wenn diese Dateien jedoch in einem als a gekennzeichneten Ordner generiert werden VOLUME, können Sie einem anderen Container mithilfe von den Zugriff auf dieses Volume gewähren --volumes-fromFlagge. Ich habe das noch nicht versucht, aber ich vermute, es würde funktionieren.
Jewgenij Brikman
1
Gute Antwort. Sie können einen Treiber für die Docker-Maschine ( github.com/docker/machine ) erstellen , der den größten Teil der Boilerplate für Sie erledigt.
Dom
1
@dom: Ich mag diese Idee, aber wissen Sie, wie man einen Treiber für Docker-Maschine erstellt? Ist eine Pull-Anfrage in das Repo der einzige Weg oder ist es möglich, einen Treiber extern zu erstellen?
Jewgenij Brikman
1
Ist dieses Tutorial für eine neue Version 1.9.1 unter Windows noch gültig? Kann ich es verwenden oder hatte Docker bereits eine neue Lösung für dieses "Problem"?
18

Update : Jetzt, da Docker für Mac in der Beta-Phase mit Nicht-Hack-Funktionalität ist, ist dieser Weg für die lokale Entwicklung möglicherweise viel vernünftiger, ohne dass ein Aufsatz Hacks und Problemumgehungen enthält.

Tu es nicht . Ich weiß, dass dies nicht die Antwort ist, auf die Sie wahrscheinlich hoffen, aber nehmen Sie eine ehrliche Bewertung der Kosten / Nutzen des Versuchs, lokalen Quellcode + Docker-Ausführung zu erhalten, anstatt nur lokale Entwicklung unter OSX durchzuführen.

Irgendwann können alle Probleme, Einrichtungsaufwand und betrieblichen Schwachstellen gut genug gelöst werden, aber ab sofort ist dies ein Nettoverlust.

Problem Nr. 1: Bereitgestellte Volumes auf Virtual Box (die vboxfs verwenden) sind extrem langsam

Warten Sie eine Weile und dies wird sich mit ziemlicher Sicherheit verbessern.

Problem Nr. 2: Die Dateiüberwachung ist fehlerhaft

Ich bin mir nicht sicher, ob dies in naher Zukunft behoben werden kann. Wenn diese Art von Funktionalität der Schlüssel zu Ihrem Entwicklungsworkflow ist, würde ich dies als Dealbreaker betrachten. Es ist keine große Forschungs- und Entwicklungsarbeit wert, wenn man nur rbenv / bundler verwendet, um Ihre Jekyll / Ruby-Installationen zu verwalten und lokal unter OSX auszuführen, wie es die Leute in den letzten zehn Jahren erfolgreich gemacht haben.

Genau wie "die Cloud" an meinem lokalen Entwicklungssetup nicht beteiligt ist, ist Docker im Moment ein Gewinn für das Testen / Staging / Bereitstellen und für das Ausführen von Datenbanken und anderen Komponenten von Drittanbietern, aber die Anwendungen, die ich tatsächlich codiere, werden direkt ausgeführt unter OSX.

Peter Lyons
quelle
1
Ich stimme dem zu. Wir entwickeln unter OSX und führen die Apps direkt im System aus (mit Live-Reload usw.). Sobald die App fertig ist, dockerisieren wir sie zum Testen, Staging und Produzieren.
ItalyPaleAle
4
Hm, das ist ein bisschen enttäuschend. Ich hatte immer Parität in meinen Staging- / Produktionsumgebungen. Es ist ein Entwickler, der immer der Ausreißer war, da ich unter OS X codiere. Die Docker-Dokumentation ließ es sicher so klingen, als wäre dies ein gelöstes Problem. Ich werde mich noch einmal anstrengen und sehen, ob ich etwas zum Arbeiten bringen kann.
Jewgenij Brikman
Halten Sie diese Antwort heute noch für gültig, Peter? Nur ein paar Monate später, aber angesichts des Projekts von @ Yevgeniy und nur 2 Problemen, die jetzt behoben sind, lohnt sich das Kosten-Nutzen-Verhältnis möglicherweise bereits! Ist es nicht?
Cregox
1
Es ist eine persönliche Präferenzsache. Ich würde mich immer noch nicht damit anlegen, weil ich so viele Projekte als Berater habe. Wenn ich ein Vollzeitbeschäftigter wäre, der wochen- / monatelang hauptsächlich am selben Projekt arbeitet, könnte es sich lohnen, das rsync / fswatch-Zeug einzurichten.
Peter Lyons
Docker Toolbox ist heutzutage der richtige Weg, denn wenn Sie Homebrew oder einen anderen Paketmanager verwenden, werden die Docker-Tool-Versionen nicht mehr synchronisiert, es sei denn, sie folgen der Versionierung als Docker-Toolbox.
Taco
12

Docker für Mac und Windows soll die endgültige Entwicklungsmethode mit Docker unter OS X (und Windows) sein. Als Docker-Produkt ist die Software eine „integrierte, einfach zu implementierende Umgebung zum Erstellen, Zusammenstellen und Versenden von Anwendungen von Mac oder Windows“. Es soll in der Lage sein, die vom OP gestellten Probleme lösen zu können. Aus der Ankündigung vom 24. März 2016 :

  • Schneller und zuverlässiger: keine VirtualBox mehr! Die Docker-Engine wird in einer Alpine Linux-Distribution auf einer xhyve Virtual Machine unter Mac OS X oder auf einer Hyper-V-VM unter Windows ausgeführt und diese VM wird von der Docker-Anwendung verwaltet. Sie benötigen keine Docker-Maschine, um Docker für Mac und Windows auszuführen.
  • Tools-Integration: Docker für Mac ist eine Mac-Anwendung und Docker für Windows ist eine Windows-Anwendung, einschließlich einer nativen Benutzeroberfläche und einer Funktion zur automatischen Aktualisierung. Das Docker-Toolset wird mitgeliefert: Docker-Befehlszeile, Docker Compose und Docker Notary-Befehlszeile.
  • Volume-Mount für Ihren Code und Ihre Daten: Der Volume-Datenzugriff funktioniert ordnungsgemäß, einschließlich Benachrichtigungen über Dateiänderungen (auf Mac funktioniert inotify jetzt nahtlos in Containern für Volume-gemountete Verzeichnisse). Dies ermöglicht Bearbeitungs- / Testzyklen für die Entwicklung im Container.
  • Einfacher Zugriff auf ausgeführte Container im lokalen Host-Netzwerk: Docker für Mac und Windows enthält einen DNS-Server für Container und ist in das Mac OS X- und Windows-Netzwerksystem integriert. Auf einem Mac kann Docker auch verwendet werden, wenn eine Verbindung zu einem sehr restriktiven Unternehmens-VPN besteht.
  • Docker für Mac wurde von Grund auf neu entwickelt, um dem Sicherheitsmodell der OS X-Sandbox gerecht zu werden, und wir arbeiten eng mit Apple zusammen, um dies zu erreichen.
Quinn Comendant
quelle
Ich habe das neulich gesehen und es sieht bei weitem nach der vielversprechendsten Lösung aus. Ich freue mich sehr, es zu versuchen, sobald es aus der Beta herauskommt, und wenn es gut funktioniert, werde ich es ändern, um die offiziell akzeptierte Antwort zu sein.
Jewgenij Brikman
4
Leider scheint die aktuelle Beta-Version (1.11.0-beta7) genauso langsam zu sein wie andere Methoden, so dass es eine Weile dauern kann, bis dies möglich ist, um forums.docker.com/t/…
walterra
3

Haftungsausschluss: Ich bin möglicherweise voreingenommen, da ich der Autor von Docker-Sync bin.

Ich habe wahrscheinlich alle hier genannten Lösungen ausprobiert, einschließlich einiger weiterer (siehe die Version https://github.com/EugenMayer/docker-sync/wiki/Alternatives-to-docker-sync ), aber sie sind im Grunde entweder auf der Seite von fehlgeschlagen Leistung (die meisten von ihnen) oder auf der Docker-Maschine (oder keine) verwendet / erzwungen.

http://docker-sync.io wurde entwickelt, um alle Lösungen zusammenzuführen und die besten Strategien bereitzustellen (Implementierung mehrerer, können Sie wählen).

Es kann mit rsync (1-Wege-Synchronisierung) einschließlich Berechtigungskorrekturen für Benutzer und mit unisono (2-Wege-Synchronisierung) verwendet werden. Es zwingt Sie weder zu einer Docker-Maschine oder einem bestimmten Hypervisor, noch erfordert es, dass Sie Docker für Mac haben. Es funktioniert mit allen.

Die Leistung von EugenMayer / docker-sync / wiki / 4.-Performance wird nicht beeinflusst, es ist, als hätten Sie überhaupt keine Freigaben.

Docker-Sync und seine Change-Watcher sind optimiert und arbeiten problemlos mit Projekten mit 12k-Dateien.

Probieren Sie es aus, wenn Sie möchten, würde ich gerne Feedback hören!

Eugen Mayer
quelle
2

Ich kann das gut nachfühlen! Ich glaube, ich habe so ziemlich alles versucht, was du versucht hast, und leider war es immer noch langsam. Dann bin ich auf diesen Kommentar https://github.com/boot2docker/boot2docker/issues/64#issuecomment-70689254 gestoßen , der die Verwendung von Vagrant und Parallels anstelle von Virtualbox vorschlägt. Dies erlaubte mir, nfs zu verwenden, und ich sah tatsächlich einen großen Leistungsschub für mein Projekt (Drupal).

Hier ist die Vagrant-Datei. Alles, was Sie tun müssen, ist, vagrant zu installieren, dies in eine Datei namens Vagrantfile zu kopieren und in einem Ordner abzulegen. Gehen Sie zu diesem Ordner und führen Sie vagrant upstatt Ihres normalen boot2docker einfach einen aus.

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
quelle
Ich gehe davon aus, dass dies eine Parallelinstallation erfordert.
Jewgenij Brikman
2

Ich verwende Vagrant auch mit Parallelen und boot2docker ( https://github.com/Parallels/boot2docker-vagrant-box ). Die Entwicklung war für mich nie einfacher. Funktioniert sehr gut mit docker-composeund großen Setups. Ich spüre keine Verzögerung oder keinen massiven Ressourcenverbrauch.

So Vagrantfilesieht mein aus:

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
quelle
1

Ich entwickle seit einigen Wochen in einer OS X (Mitte 2011 Macbook Air) + Boot2Docker + Docker-Compose-Umgebung. Ich habe keine größeren Leistungsprobleme festgestellt, aber ich vermeide es, bei der Entwicklung Builds auszuführen (warum nicht so etwas verwenden jekyll serve --skip-initial-build?). Hier ist eine Beispieldatei docker-compose.yml, die ich verwende:

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

Ich verwende manchmal NFS ( http://syskall.com/using-boot2docker-using-nfs-instead-of-vboxsf/ ), habe dabei aber keinen großen Leistungsunterschied festgestellt.

Für mich ist die Bequemlichkeit eines einfachen docker-compose up test zu betriebsbereiten Umgebung die Kosten für die Leistung wert (ich arbeite routinemäßig an mehreren Projekten mit unterschiedlichen Stapeln).

PS: nodemonist einer der wenigen Datei-Watcher, die mit vboxsf arbeiten (siehe https://github.com/remy/nodemon/issues/419 ).

Olivier Lalonde
quelle
Selbst wenn ich den ersten Build mit Jekyll überspringe, muss er jedes Mal, wenn ich eine Datei ändere, neu erstellt werden. Dies dauert in der Größenordnung von 1-3 Minuten, wenn der Quellcode bereitgestellt wird. Dies macht es unmöglich, irgendeine Art von Stiländerung zu entwickeln und neu zu laden.
Jewgenij Brikman
@YevgeniyBrikman Oh, das war mir nicht bewusst :( Ich denke, die letzte Option wäre, Ihren Code in der boot2docker-VM zu haben und ihn mit sshfs auf Ihrem Host-Computer zu mounten. Andernfalls müssen Sie wohl warten Bessere Leistung für gemountete Ordner, um Docker als Entwicklungsumgebung zu verwenden.
Olivier Lalonde
-1

Es ist möglich, Docker als Entwicklungswerkzeug zum Laufen zu bringen. Aber es wird weh tun. Ich habe den Prozess hier dokumentiert:

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

Harmingcola
quelle
Vielen Dank für die Veröffentlichung, aber wie löst dies die Leistungsprobleme mit bereitgestellten Volumes?
Jewgenij Brikman
Entschuldigung, Sie müssen vBox nicht mehr verwenden, um etwas zu mounten. Sie können Ordner über die reguläre Docker-Oberfläche
einbinden
-4

Diese Methode ist die neueste (September 2015) und einfachste Möglichkeit, Docker auf dem Mac einzurichten: Link hier:

Sie installieren Docker über den Docker Toolbox- Link zu den folgenden Anweisungen:

Es handelt sich um ein vollständiges Docker-Setup-Paket, das die folgenden Docker-Tools enthält:

Docker-Maschine zum Ausführen der Docker-Maschine-Binärdatei

Docker Engine zum Ausführen der Docker-Binärdatei

Docker Compose zum Ausführen der Docker-Compose-Binärdatei

Kitematisch ist die Docker-GUI eine Shell, die für eine Docker-Befehlszeilenumgebung vorkonfiguriert ist

Oracle VM VirtualBox

Geben Sie hier die Bildbeschreibung ein

Was ist in der Toolbox:

  • Docker Client
  • Docker-Maschine
  • Docker Compose (nur Mac)
  • Docker Kitematic
  • VirtualBox
Rootscript
quelle
3
Ja, aber es hat das ursprünglich vorgestellte Problem leider nicht gelöst.
Nick