Docker bundled Information
Docker bundled Information
Wichtige Bezeichner:
-p HostPort:ContainerPort | Map a Port | e.g. -p 8080:80
-d | "detached" - container rennt im Hintergrund
logs | docker container logs containername(oder id) | verlassen mit Ctrl-c
rm | Container entfernen (muss zuerst gestoppt werden oder mit -f (force) erzwungen )
stop/restart | stoppen und neu starten eines Containers
--name | einen eigenen Namen für den Container definieren
stats | die verwendeten Ressourcen eines Containers anzeigen
top | laufende Tasks eines Containers anzeigen
-v | "volume" einen Host Ordner mir einem Container Ordner binden.
-w | den Arbeitsordner (working directory) innerhalb des Containers definieren.
--rm | Docker entfernt den Container wieder - nachdem das Script ausgeführt wurde.
--help | zeigt hilfreiche Möglichkeiten die mit diesem Command ausgeführt werden können - dies funktioniert auf unterschiedlichen Ebenen!
inspect | um detaillierte Informationen über ein Image zu erhalten - das Image muss nicht heruntergeladen sein! e.g. inspect nginx:latest | damit können die nach außen verwendeten Ports, Umgebungsvariablen, die Working Dir uvw. nützliche Informationen in Erfahrung gebracht werden. Mit -f "{{.Config.ExposedPorts}}" können wir und einzelnen Werte direkt ausgeben lassen.
cp | kopieren von Dateien und Ordner zwischen Container und dem Host System.
Note: Mit dem Command pwd (print working directory) kann der aktuelle Pfad zum verbinden der Ordner angezeigt werden.
Alle Container Stoppen und Entfernen:
docker stop $(docker ps -a -q) docker rm $(docker ps -a -q)
Images anzeigen, alle nicht zu einem Container gehörenden Images entfernen:
docker images docker image prune -a
Beispiel - Host Ordner Mappen:
Der passende Container Ordner muss erst in Erfahrung gebracht werden. Oftmals ist der einfachste weg dafür über die Docker Hup Dokumentation des verwendeten Images. Beispielsweise möchten wir wissen, welcher Ordner von NGINX zum ausliefern der HTML Dateien verwendet wird.
Wir erstellen ein HelloWorld Html File auf unserm Host und mappen diesen Ordner dann mit unserem Container.
docker container run --name docker-example01 -v /Users/UserName/Workspace/Docker/Example01:/usr/share/nginx/html -p 8000:80 -d nginx
Das erzeuge HTML File ist nun über localhost:8000 erreichbar. Änderungen am Host File ist sofort und ohne neu start ersichtlich. Sollte der angegebene Ordner nicht existieren so wird er erstellt. Andernfalls werden die Dateien darin vom Host überschrieben.
Commands direkt innerhalb eines Containers ausführen:
docker container exec docker-example01 cat /usr/share/nginx/html/index.html
Als Ausgabe erhalten wir den Code unserer zuvor erstellten Html Datei.
Eine Shell im Container starten:
docker container exec -ti docker-example01 /bin/bash
Im obigen Beispiel wird -i für Command Interaktiv Mode und -t für die Ausgabe am Terminal definiert. Wir könnten nun Packages via apt-get installieren oder sogar der Html File andersherum editieren - innerhalb des Containers. Mit exit können wir die Shell wieder verlassen.
Configuration File verwenden
Zwei neue Ordner innerhalb unseres Projektordners erstellen.
mkdir html config
Wir verschieben unsere Index Html in den html Ordner.
mv index.html html/
Wenn wir wissen wo sich des Configuration File befindet, können wir es direkt in unseren config Ordner kopieren - anschließend könnten wir Änderungen daran vornehmen.
und einen neuen Container starten bei dem wir auch dieses File mappen und somit die gewünschten Änderungen wirksam machen.
docker container cp docker-example01:/etc/nginx/nginx.conf ./config/
Um das Configuration File zu verwenden müssen wir auch dieses mit dem Container File mappen.
docker container run --name docker-example01 -v /Users/UserName/Workspace/Docker/Example01/html:/usr/share/nginx/html -v /Users/UserName/Workspace/Docker/Example01/config/nginx.conf:/etc/nginx/nginx.conf -p 8000:80 -d nginx
NOTE: Die meisten offiziellen Docker Images verwenden derzeit Alpine Linux. Der Grund dafür ist die geringe Größe. Im Vergleich zu Debian mit 100MB benötigt Alpine lediglich 4MB - allerdings müssen notwenige Packages womöglich zuerst nachgeladen oder definiert werden. Zusätzlich ist es best practice NICHT die latest Version zu verwenden - da klarerweise die lastest Version sich ändern kann und womöglich Auswirkungen auf die eigene Applikation hat.
Python Beispiel
Wir erstellen einen neuen Ordner - Example02. Und eine Python Datei mit dem Inhalt:
name = input("Wie lautet dein Name:") print("Hallo", name)
Mit dem nachstehenden Command starten wir einen Python Container und vernetzen die Ordnerstruktur erneut. Dieses mal verwenden wir --rm wodurch der Container nach dem Ausführen des Scripts wieder entfernt wird.
docker run -it --rm --name docker-example02 -v /Users/UserName/Workspace/Docker/Example02:/usr/src/myapp -w /usr/src/myapp python:3.7.2-slim python app.py
NOTE: Natürlich ist es notwendig zuerst das entsprechende Image via Docker pull von Docker Hub auf den Host Rechner zu ziehen!
Docker File erstellen
Ein Docker File enthält alle notwendigen Informationen um daraus ein Docker Image zu erzeugen. Aus diesem Image können dann in weiterer folge unzählige Instanzen also Container erzeugt werden.
FROM | Jedes Dockerfile startet mit FROM. Meistens wird als Startpunkt ein offizielles Image wie alpine (e.g. FROM alpine:3.8) verwendet. Wir können aber auch von Grund auf ein neues Image erstellen mit FROM scratch. Es sind mehrere FROM angaben möglich.
COPY und ADD | kopieren von Files und Ordner vom Host zum Image | ADD ist mehr unberechenbar als COPY - mit ADD können Files über eine URL bezogen werden - mit ADD können komprimierte Files integriert werden -
ENV | damit können Umgebungsvariablen gesetzt werden | nicht nur innerhalb des Containers - sondern auch für das Dockerfile selbst
RUN | führt System Commands aus | hier kommt oft apt-get update und apt-get install zum Einsatz - es empfiehlt sich die Commands als Einzeiler anzulegen damit Docker auf den Layer Cache zugreifen kann und nicht pro Zeile ein Image erzeugt und somit einiges an Speicherplatz spart.
VOLUME | definiert ein Volume (Speicher e.g Festplatte) um Daten ausserhalb des Containers zu speichern | dadurch können Daten persistent gespeichert werden und sind somit auch nach dem zerstören eines Containers noch verfügbar
USER | spezifiziert einen neuen User - anders als root - des Images | es empfiehlt sich die Applikationen innerhalb eines Containers nicht als root auszuführen!
WORKDIR | definiert den Working Ordner | also dort wo RUN, CMD, COPY, ADD etc ausgeführt werden - es können mehrere WORKDIR´s angegeben werden | wenn die WORKDIR nicht existiert wird Docker das Verzeichnis anlegen
EXPOSE | gibt Infos der nach außen definierten Ports | Expose gibt lediglich Infos darüber - der eigentliche Prozess dafür wird mit -p definiert
CMD | eine Eingangspunkt zum Container | oft wird hier eine shell definiert
ENTRYPOINT | wenn ein Entrypoint definiert wurde - arbeitet Docker etwas anders - das definierte CMD erweitert den Entrypoint e.g.
ENTRYPOINT ["git"] CMD ["--help"]
Note: Beim erstellen eines Dockerfiles sollten diejenigen Schritte zuerst kommen die mit der geringsten Wahrscheinlichkeit geändert werden müssen.
Geeignetste Reihenfolge der Commands innerhalb eines Dockerfiles:
- Alle für die Applikation notwendigen Tools installieren
- Abhängigkeiten, Libraries, und Packages installieren
- Build Prozess der Applikation
.dockerignore
Docker verwendet alle im selben liegenden Dateien als build context - unbenötigte Dateien sollten deshalb via Docker Ignore daraus entfernt werden. .dockerignore funktioniert dabei wie .gitignore
Eigenes Dockerfile erstellen:
- Basis Image definieren - auf Docker Hub suchen, vergleichen.
- Die Shell verwenden und nach dem Try and Fail Prinzip die notwendigen Bedingungen installieren.
- Wenn ein Part erfolgreich erscheint - diesen direkt ins Dockerfile inkludieren.
- So weiter machen bis das Dockerfile all notwendigen Anforderungen entspricht
Tag, Version, Pfad
docker image build -t dockername/ownname:1.0 .
-t oder --tag | dem Image einen Namen geben + zuvor den Docker Hub Usernamen angeben - dadurch wird er in der eigenen Repository veröffentlicht. | :1.0 = eine Versionsnummer | . der Punkt am Ende stellt den Pfad zum Dockerfile dar - in unserem Fall ein Punkt da sich das File im selben Ordner befindet.
Erweitern eines existierenden Images:
Verwende dafür FROM exisiting_image
Dangling Images
Wenn einem neuen Image der selbe Name gegeben wird, so kann es vorkommen das, dass vorhergehende Image via image ls also <none> angezeigt wird. Diese so genannten dangling images können mit dem Command:
docker image ls --filter "dangling=true"
explizit angezeigt werden. Mit dem Command:
docker image purne
können alle dangling images entfernt werden.
Volumes
Docker erstellt Volumes automatisch wenn der Container startet. Dieses Volume wird ausserhalb des Containers erstellt und ist somit auch nach dem entfernen oder stoppen des Containers verfügbar.
Beim starten eines neuen Containers wird erneut ein neues Volume erstellt. Um das zuvor verwendete Volume wieder zu verwenden muss dem Volume zur Laufzeit ein Name zugeteilt werden. Durch diese Methode können wir beispielsweise die MySQL Datenbank Files persistent auf der Host Maschine speichern.
-v neuervolumename:/var/log/logbeispiel ..
Mit -v können wir einem Volume einen Namen zuteilen.
Note: --rm | wird --rm verwendet wird auch das Volume danach entfernt!
Volume am Host einsehen
Mit dem nachstehenden Command können wir den "Mountpoint" (Pfad des Volumes) in Erfahrung bringen.
docker volume inspect volumename
Anschließend müssen wir als Administrator mit sudo die Datei einsehen.
sudo cat /mountpoint/_data/app.log
Clean up Volumes
Nicht genutzte Verzeichnisse können ähnlich wie Images entfernt werden.
docker volume ls docker volume prune
sed Command
Mit dem Linux Command sed (ist ein Stream Editor) können wir Files inline im Dockerfile editieren. Weitere Informationen über den Stream Editor.
Dateien vom Container auf den Host kopieren
Oft kommt es vor, dass wir innerhalb des Containers über eine Shell NPM oder COMPOSER verwenden. Um die erstellten Dateien und Informationen aber nun auf unserem Host persistent zu sicheren müssen wir diese kopieren.
docker cp container_name:/home/node/app app
Note: Meistens verwenden wir dafür --rm beim Start des Containers deshalb darf die Shell auch nicht einfach verlassen werden. Starte einen 2ten Terminal um die Dateien zu kopieren.
Stop, Remove alle Container und Images
Auflisten aller Container anhand deren ID
docker ps -aq
All laufenden Container stoppen
docker stop $(docker ps -aq)
Alle Container entfernen
docker rm $(docker ps -aq)
Alle Images entfernen
docker rmi $(docker images -q)
Privileged Access
By default, Docker containers are “unprivileged” and cannot, for example, run a Docker daemon inside a Docker container. This is because by default a container is not allowed to access any devices, but a “privileged” container is given access to all devices (see the documentation on cgroups devices).
privileged: true