Docker für die lokale Entwicklung

Ich benutze Docker. Täglich. Es ist zu einem sehr wertvollen Teil meiner Toolchain geworden, weil ich damit jedes Backend, das meine Applikationen zum Laufen brauchen, schnell aufsetzen und in dem Moment wieder abräumen kann, in dem ich es nicht mehr brauche. Vorbei sind die Zeiten, in denen man alle möglichen Datenbanken und anderen Services installiert haben musste, nur um seine Apps lokal laufen zu lassen. Mit Docker kannst du all das tun und es von deiner Maschine isolieren.
Die meisten Backend-Systeme sind über HTTP und einen bestimmten Port erreichbar. Das kannst du dir zunutze machen und viele Services betreiben, von denen jeder in seinem eigenen Docker-Container läuft und den jeweiligen Port auf deinem lokalen Host bereitstellt.
Docker installieren
Falls du Docker noch nicht installiert hast, empfehle ich dir, das jetzt zu tun und danach zurückzukommen. Ich für meinen Teil habe Docker for Mac richtig schätzen gelernt. Du kannst es auch über Homebrew mit folgendem Befehl installieren:
$ brew cask install docker
Unter Windows installierst du Docker mit Docker for Windows, und unter Linux geht es denkbar einfach: Nimm einfach deinen lokalen Paketmanager.
Services betreiben
Kommen wir dazu, die Services tatsächlich laufen zu lassen. Die Zauberformel ist hier der folgende Befehl:
$ docker run -d -p <port>:<port> <service>
Ersetze <port> durch den Standardport deines Service und <service> durch
dessen Namen – und schon hast du eine laufende Instanz. Das Flag -d gibt an,
dass du den Docker-Container im
Detached Mode
laufen lassen willst. Das heisst, er läuft im Hintergrund weiter, auch wenn du
dein Terminal schliesst. Hier ein paar Beispiele, um Services mit dem obigen
Befehl zu starten:
# MongoDB
$ docker run -d -p 27017:27017 mongo
Einfach!
# Redis
$ docker run -d -p 6379:6379 redis:3
Hier haben wir zusätzlich die Redis-Version angegeben, die wir verwenden wollen. Die verfügbaren Versionen findest du, indem du im Docker Store nach dem jeweiligen Image suchst.
# MySQL
$ docker run -d -p 3306:3306 -e 'MYSQL_ALLOW_EMPTY_PASSWORD=yes' mysql
In diesem Fall verwenden wir das Flag -e, um eine zusätzliche
Umgebungsvariable zu setzen, die das MySQL-Image benötigt.
Nach diesen Beispielen hast du die Idee sicher verstanden. Denk aber daran, dass
du diese Befehle auf fast jeden Service anwenden kannst, der in einem Container
läuft. Du kannst dich aus deiner Applikation jetzt mit den containerisierten
Services verbinden, als würden sie auf deiner lokalen Maschine laufen. Das liegt
daran, dass das Flag -p den Containern sagt, dass sie ihre internen Ports auf
deine lokalen weiterleiten sollen.
Wenn zum Beispiel ein MongoDB-Container läuft, der seinen Port 27017 auf
deinen lokalen Port 27017 weiterleitet, kannst du dich mit der mongo-Shell
problemlos mit der Datenbank im Container verbinden – genau so, als würde die DB
lokal laufen.
Docker-Shortcuts
Beim Arbeiten mit Docker habe ich ein paar praktische Kurzbefehle entdeckt, mit denen sich ungenutzte Services aufräumen lassen, damit sie deinen Rechner nicht mehr zumüllen. Ein weiterer Vorteil: Du kannst deine Datenbanken und andere persistente Services sauber und einfach leeren, um sicherzugehen, dass du gegen einen frischen Zustand testest.
Ein erster wichtiger Kniff: Du kannst jede Container-ID immer auf ihre ersten
paar Zeichen abkürzen (solange es das einzige Objekt ist, dessen ID mit diesen
Zeichen beginnt). Statt die vollständige ID zu tippen und
docker stop 4f263b9aad2d zu schreiben, kann ich also einfach docker stop 4f
eingeben (solange dieser Container der einzige laufende mit einer ID ist, die
mit «4f» beginnt).
Weitere nützliche Befehle sind:
# Alle laufenden Container stoppen
$ docker stop $(docker ps -a -q)
# Alle gestoppten Container entfernen
$ docker rm $(docker ps -a -q)
# Alle ungenutzten Images entfernen
$ docker rmi $(docker images -q)
# Alle ungenutzten Volumes entfernen
$ docker volume rm $(docker volume ls -q)
# Alle ungenutzten Netzwerke entfernen
$ docker network rm $(docker network ls -q)
# Alles entfernen
$ docker system prune --all