Erste Schritte in Docker

Windows unter Linux, Linux unter Linux, VirtualBox, Qemu, Docker und Co
Administrator
Beiträge: 112
Registriert: Sa 10. Jul 2021, 17:17
Wohnort: Kaarst

Has thanked: 20 times
Been thanked: 8 times

Erste Schritte in Docker

Beitrag von Bommo »

Prolog

Wie auf einem Computer die Software Docker installiert wird, hat Robert in diesem Artikel bereits beschrieben:

Docker - Anwendungen und Systeme unter Linux virtualisieren / isolieren

Bislang habe ich ausschließlich VirtualBox genutzt, um virtuelle Maschinen aufzubauen und etwas auszutesten. Mit Docker verspreche ich mir die Möglichkeit, meine Tests auf kleine Füße zu stellen, um nicht immer mit Kanonen auf Spatzen zu schießen.

Um es vorweg zu nehmen: Aus meiner Sicht ist mein Wunsch in Erfüllung gegangen.

Es hat keinen Zweck sich darüber Gedanken zu machen, ob man die neueste Linuxdistribution in Docker testen kann. Grafischen Oberflächen kann man nicht nutzen - nur eben den Browser, wenn es bunt und anklickbar sein soll. Bedeutet, Docker ist was für serverseitige Programme.

Um mich dem Thema überhaupt nähern zu können, hatte ich mich auf Docker Hub umgesehen. In dem 6-teiligen Tutorial auf dem YouTube-Kanal von heise online gibt es einige gute Hinweise für die ersten Schritte und wo man eben die für Docker notwendigen Dinger (Images) bekommen kann.

Tatsächlich hat es dann etwas gedauert, bis ich die Images, Container und Volumens auseinanderhalten und verwalten konnte.

Natürlich bin ich ganz klein angefangen und habe die Konsolenbefehle gelernt. Damit weiß ich dann eben, was passiert, sollte ich später mit Docker-Compose (yaml-Script, mache ich jetzt) oder Portainer (eine grafischen Oberfläche für Docker) arbeite.

Heute habe ich für mich den ersten Teil meiner Lernphase für Docker abgeschlossen und kann nun via Docker-Compose ein Tool starten und die Anwendungsdaten in einem externen Volume speichern. Das Speichern der Anwendungdsdaten in den Containern ist suboptimal, weil sie schnell verloren gehen. Daher, wenn man Container produktiv einsetzen möchte, ist das Erlernen mit dem Umgang von Volumes wichtig. Diese Volumes gehören dann zwangsläufig in die Backup-Strategie des Computernutzters. ;)

Meine Ausführungen werde ich über mehrere Artikel verteilen. Da wir hier im Wiki sind, bitte für Fragen und Anregungen ein entsprechendes Thema im Forum öffnen. Danke!

Im Docker Hub liegen offizielle Images von Docker und Images aus der Community. Bislang habe ich mich nur mit den offiziellen Images befast. Zum Lernen ist das wirklich ausreichend.

Natürlich wollte ich es mir so einfach wie möglichen machen. Mein Lernmaterial bezieht sich auf Ghost. Ghost ist eine freie Bloggingplattform. Ich kenne das Tool nicht, nur vom Namen her. Zu jedem Docker-Images gibt es eine Webseite, die Informationen zur weiteren Verwendung des jeweiligen Images bereithält.

Auf keinen Fall wollte ich etwas machen, wobei zwei Container gleichzeitig zu nutzen sind. Und nur auf der Konsole hantieren, wollte ich auch nicht.
Früher tanzten wir Wange an Wange, heute Bauch an Bauch. :shock:
Administrator
Beiträge: 112
Registriert: Sa 10. Jul 2021, 17:17
Wohnort: Kaarst

Has thanked: 20 times
Been thanked: 8 times

Re: Erste Schritte in Docker

Beitrag von Bommo »

Teil 1

Der Befehl zum Download des Docker-Images für Ghost ist auf der Webseite zu finden. Auf der Konsole ist der entsprechende Befehl auszuführen. Dieses muss man mit root-Rechten durchführen. Will man als Normaluser die Dockerbefehle ausführen, ist mit root-Rechten der User der Gruppe docker hinzuzufügen:

Code: Alles auswählen

$ usermod -aG docker username
Nach einer Neuanmeldung kann der Normaluser ohne "sudo" arbeiten.

Der einfachste Befehl zum Download eines Images lautet:

Code: Alles auswählen

$ docker pull ghost
Will man Ghost mit einer bestimmten Version nutzen bzw. ausprobieren, muss man mit sogenannten TAGS arbeiten. Diese TAGS beschreiben im Grunde genommen die Version bzw. die Versionsreihe. Dann könnte der pull-Befehl z.B. so aussehen, wenn es die neueste Version sein soll:

Code: Alles auswählen

$ docker pull ghost:latest
Die Defaulteinstellung lautet wohl immer auf den TAG latest.

Nachdem der einfache Pull-Befehl abgesetzt ist, wird der Download gestartet und durchgeführt. Das Ergebnis sind wie folgt aus:

Code: Alles auswählen

Using default tag: latest
latest: Pulling from library/ghost
e1acddbe380c: Pull complete 
7263c7b7f332: Pull complete 
0e985e216445: Pull complete 
75a9268f63ec: Pull complete 
15b30c5db6de: Pull complete 
46e57f8bb6f3: Pull complete 
76bb54f82d33: Pull complete 
ef365ad3ce09: Pull complete 
d9989d0de9cc: Pull complete 
Digest: sha256:26e68af5cfe2902f7e1524bdb1ac77f1fcd6ffd462a990f80aff595008c1d926
Status: Downloaded newer image for ghost:latest
docker.io/library/ghost:latest
Der interessierte User wird sich nun fragen, wo denn der Download abgelegt wird. Wo liegt das Image?

Leider ist das nicht offensichtlich, denn im Downloadordner liegt es nicht.

Es liegt hier:
screener_01.png
Aber das Images selber interessiert uns nicht, denn damit wird nur auf der Konsole (oder später in einer Docker-Compose-Datei) gearbeitet.

Es gibt sehr viele und unterschiedliche Dockerbefehle.

Nun haben wir einen pull-Befehl abgesetzt und ein Image heruntergeladen. Mit dem folgenden Befehl (incl. Ergebnis) kann man feststellen, ob es wirklich vorhanden ist und welche anderen Images es vielleicht noch gibt:

Code: Alles auswählen

$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
ghost        latest    b05a58075ef6   22 hours ago   448MB
In diesem Fall liegt derzeit nur ein Image auf dem Rechner, hat eine Größe von 448MB und ist vor 22 Stunden zuletzt aktualisiert worden (von den Entwicklern).

Als nächstes steht an, dass dieses Image irgendwie benutzbar gemacht werden muss. Um ein Image zu nutzen, muss der run-Befehl verwendet werden. Es gibt diverse Möglichkeiten, um einen run-Befehl zu kreieren. Es ist immer gut, auf der Webseite des Docker-Images nach der Ausführung des run-Befehls zu schauen.

Die einfachste Ausführung wäre

Code: Alles auswählen

$ docker run -d --name myghost ghost
Was steckt dahinter?

Der run-Befehl wird mit de Option -d gestartet sowie der Option --name gefolgt von einer Bezeichnung, die unser Container haben soll, nämlich myghost. Und zum Schluss kommt der Image-Name hinten dran.

Diesen Befehl setzen wir nicht ab, denn Ghost ist eine Webanwendung. Um eine Webanwendung auch wirklich im Browser starten zu können, muss der Befehl erweitert werden:

Code: Alles auswählen

$ docker run -d --name myghost -e url=http://localhost:3001 -p 3001:2368 ghost
In die Adresszeile des Browsers ist später http://localhost:3001 (oder http://localhost:3001/ghost für Adminzugang) einzugeben.

Das Ergebnis der Befehlsausführung sieht wie folgt aus:

Code: Alles auswählen

a92b1f1e260d72392c211a4d06c8855a6f5d096d0fd92ea7716267be6befd9e0
Mehr ist in der Tat nicht zu sehen, da die Option -d alles unsichtbar im Hintergrund ablaufen lässt. :)

Damit haben wir unseren ersten Container gestartet. Ob das wirklich so ist, und ob vielleicht noch mehr Container vorhanden sind, erfährt man hierüber:

Code: Alles auswählen

$ docker container ls -a
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS                                       NAMES
a92b1f1e260d   ghost     "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:3001->2368/tcp, :::3001->2368/tcp   myghost
Mit folgendem Befehl werden die Container angezeigt, die gerade ausgeführt werden:

Code: Alles auswählen

$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                       NAMES
a92b1f1e260d   ghost     "docker-entrypoint.s…"   4 minutes ago   Up 4 minutes   0.0.0.0:3001->2368/tcp, :::3001->2368/tcp   myghost
Das ist nahezu die gleiche Anzeige wie beim ls-Befehl.

Damit haben wir ein Image heruntergeladen und einen Container gestartet. Das ein Image sowie ein Container vorhanden sind, können wir nun prüfen.

Das Ergebnis unserer Bemühungen sollte eine laufende Instanz von Ghost in unserem Browser sein:
screener_02.png
Früher tanzten wir Wange an Wange, heute Bauch an Bauch. :shock:
Administrator
Beiträge: 112
Registriert: Sa 10. Jul 2021, 17:17
Wohnort: Kaarst

Has thanked: 20 times
Been thanked: 8 times

Re: Erste Schritte in Docker

Beitrag von Bommo »

Teil 2

Der erste Container läuft. Was man damit jetzt weiter macht, spielt im Moment noch keine Rolle.

Das Handling von Images und Containern ist noch nicht beendet, denn Container können gestoppt, gestartet und gelöscht werden. Letztlich können Images nur gelöscht werden, wenn man sie nicht mehr benötigt.

Um einen Container zu stoppen, könnte man so vorgehen:

Code: Alles auswählen

$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                       NAMES
a92b1f1e260d   ghost     "docker-entrypoint.s…"   26 minutes ago   Up 26 minutes   0.0.0.0:3001->2368/tcp, :::3001->2368/tcp   myghost
$ docker stop a92b1f1e260d
a92b1f1e260d
$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
1. Mit dem ersten Befehl wird geprüft, ob der zu stoppende Container überhaupt läuft.
2. Der zweite Befehl stoppt die Ausführung des Container über seine ID.
3. Mit dem dritten Befehl wird das Ergebnis der Bemühungen überprüft.

Das Ergebnis ist, dass der Container nicht mehr aktiv ist.

Natürlich kann man einen Container auch wieder starten. Das sieht dann wie folgt aus:

Code: Alles auswählen

$ docker start a92b1f1e260d
a92b1f1e260d
$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS        PORTS                                       NAMES
a92b1f1e260d   ghost     "docker-entrypoint.s…"   29 minutes ago   Up 1 second   0.0.0.0:3001->2368/tcp, :::3001->2368/tcp   myghost
Damit ist der Container wieder aktiv und ebenfalls lässt sich die Webseite wieder anzeigen.

Der letzte Befehl, der noch im Handling der Container wichtig ist, betrifft das Löschen. Damit ein Container gelöscht werden kann, muss er stoppt sein. Ingesamt kann das so ablaufen:

Code: Alles auswählen

$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS         PORTS                                       NAMES
a92b1f1e260d   ghost     "docker-entrypoint.s…"   32 minutes ago   Up 2 minutes   0.0.0.0:3001->2368/tcp, :::3001->2368/tcp   myghost
$ docker stop a92b1f1e260d
a92b1f1e260d
$ docker container rm a92b1f1e260d
a92b1f1e260d
$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
$ docker container ls -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
1. Prüfung, ob der zu löschende Container aktiv ist.
2. Wenn ja, wird der Container gestoppt.
3. Dann wird der Container gelöscht.
4. - 6. Es wird geprüft, ob der Container noch vorhanden ist (ich nutze meist Befehl Nr. 6 nach dem Löschen).

Der Container ist nun weg. Geblieben ist das Image. Denn mit dem Image kann man jederzeit einen neuen Container erstellen (run-Befehl).

Wären in dem Container Anwendungsdaten vorhanden gewesen, so wären sie jetzt weg. Sobald der Container gelöscht wird, sind auch die Anwendungsdaten gelöscht. Gestoppte Container behalten die Daten.

Generell sollte man in Containern keine Anwendungsdaten speichern. Diese Daten gehören in ein Volume, das außerhalb des Containers liegt.

Das Löschen von Images wird zu einem späteren Zeitpunkt behandelt.
Früher tanzten wir Wange an Wange, heute Bauch an Bauch. :shock:
Administrator
Beiträge: 112
Registriert: Sa 10. Jul 2021, 17:17
Wohnort: Kaarst

Has thanked: 20 times
Been thanked: 8 times

Re: Erste Schritte in Docker

Beitrag von Bommo »

Teil 3

Anwendungsdaten können gespeichert werden. Allerdings nicht im Container, da gehören sie nicht hin, sondern dafür verwendet man Volumes.

Der generelle Befehl zum Anlegen eines Volumes lautet wie folgt:

Code: Alles auswählen

$ docker volume create
Mit diesem Befehl wird ein Volume angelegt, dessen "Name" aus zufälligen Ziffern und Buchstaben besteht und ellenlang ist.

Es wäre schon besser, wenn man dem Kind einen Name gibt:

Code: Alles auswählen

$ docker volume create meinvolume
Der letzte Teil des Befehls "meinvolume" ist nun der Name des Volumes. Ob Volumes vorhanden und wie sie benannt sind, lässt sich wie folgt feststellen:

Code: Alles auswählen

$ docker volume create meinvolume
meinvolume
$ docker volume ls
DRIVER    VOLUME NAME
local     0bf98e29f96b7bf612a0b183bc4b43007142f3244eb3e9cd0033dae29f92ee57
local     445e2c5a1e8f0b7319bca133189a910ce388566bec53968f87adfb8ee1e2f640
local     a36d2c024a46485c50549b59a6da30da3d110530d9555c3e92a02bff9e0adb3c
local     meinvolume
Aus meiner Sicht ist der lesbare Volumenname angenehmer als die 3 bereits bestehenden Volumes aus meiner Testphase, die ich absichtlich habe bestehen lassen. Natürlich lassen sich, analog zu Images und Containern, Volumens löschen.

Die Volumes werden im Hostsystem abgelegt und können ganz normal benutzt werden. Wie bereits weiter oben angedeutet, sind diese Volumes durchaus in die Sicherungsroutinen einzubauen, wenn wichtige Daten in den Volumens erzeugt und gehalten werden. Die Volumens liegen standardmäßig hier:
screener_03.png
Bitte beachten, dass auch ein in der Gruppe docker angelegter Normaluser den Ordner docker nicht sieht. Hier muss mit sudo gearbeitet werden.

Volumens enthalten die Anwendungsdaten. Natürlich muss man beim Löschen von Volumens aufpassen. Im Grunde genommen ist das nichts anderes wie das Löschen der eigenen Systemfestplatte. 8-)

Folgender Befehl löscht ein Volume:

Code: Alles auswählen

$ docker volume rm meinvolume
meinvolume
$ docker volume ls
DRIVER    VOLUME NAME
local     0bf98e29f96b7bf612a0b183bc4b43007142f3244eb3e9cd0033dae29f92ee57
local     445e2c5a1e8f0b7319bca133189a910ce388566bec53968f87adfb8ee1e2f640
local     a36d2c024a46485c50549b59a6da30da3d110530d9555c3e92a02bff9e0adb3c
Mit dem ersten Befehl wurde das Volume gelöscht. Mit dem zweiten Befehl wurde überprüft, ob das Volume tatsächlich gelöscht wurde.

Es ist nicht wirklich vorteilhaft, wenn die Volumes irgendwo in den Tiefen des Systems versteckt liegen. Es macht Sinn, dass man eine Struktur aufbaut, die alle Volumes beinhaltet und somit auch einfach in die Sicherungsroutinen eingefügt werden kann.

Dazu lenkt man das Volume an einen definierten Ort. Im Home-Verzeichnis meines Users habe ich einen Ordner dockerdata sowie einen Unterordner ghost angelegt. Ich möchte erreichen, dass die Anwendungsdaten im Unterordner gespeichert werden. Dort kann ich sie jederzeit sehen und benutzen wie alle anderen Daten auch.

Das Verlinken des Volumes auf den Unterordner ghost kann während der Ausführung des run-Befehls erfolgen. Das sieht dann sehr kryptisch aus:

Code: Alles auswählen

docker run -d --name myghost -e url=http://localhost:3001 -p 3001:2368 -v ~/dockerdata/ghost:/var/lib/ghost/content ghost
Wie mit dem run-Befehl ein Container erzeugt wird, wurde weiter oben schon beschrieben. Der aktuelle Befehl wurde um den Zusatz
-v ~/dockerdata/ghost:/var/lib/ghost/content
erweitert. Die Option - steht für Volume. Hinter dem Doppelpunkt wird der Originalort angegeben, an dem das Volume liegt.

In dem Unterordner ghost unter /home/django/dockerdata wurden nun weitere Ordner angelegt:
screener_04.png
Alle Anwendungsdaten, die von nun an in Ghost erstellt oder hingebracht werden, werden in diesen Ordnern gespeichert.

Ich habe mich als Admin angemeldet und einen ersten Artikel geschrieben, in dem ein Bild eingefügt wurde. Dieses Bild wird im Unterordner images abgelegt.
screener_05.png
Auf der Webseite ist das Ergebnis der Artikelerstellung auch zu bewundern:
screener_06.png
Früher tanzten wir Wange an Wange, heute Bauch an Bauch. :shock:
Administrator
Beiträge: 112
Registriert: Sa 10. Jul 2021, 17:17
Wohnort: Kaarst

Has thanked: 20 times
Been thanked: 8 times

Re: Erste Schritte in Docker

Beitrag von Bommo »

Teil 4

Das Arbeiten in/auf der Konsole macht durchaus Spaß. Das Handling von Images, Containern und Volumes in der einfachsten Art und Weise, wie bislang beschrieben, ist eine wichtige Grundlage zum Kennenlernen von Docker und seinen vielen Möglichkeiten.

Aber man muss auch die Zeit bedenken, die es kostet, immer wieder diese Befehle einzutippen. Inbesondere die Aktionen aus Teil 3 lassen sich sehr gut automatisieren. Und das funktioniert mit docker-compose.

Bei der Installation von Docker wird dieses Tool nicht installiert. Es lässt sich aber ganz flott nachinstallieren:

Code: Alles auswählen

sudo apt-get install docker-compose
Die 3 wichtigsten Befehle von docker-compose sind:

1. docker-compose up -d
2. docker-compose stop
3. docker-compose down

Mit dem ersten Befehl wird das Tool im Hintergrund gestartet. Der zweite Befehl stoppt das Tool. Der dritte Befehl fährt das Tool herunter. Sobald das erfolgt, wird auch sofort der Container, der beim Start erzeugt wurde, gelöscht. Man muss eigentlich als User nichts mehr machen, um im Container zu arbeiten bzw. die Arbeit mit dem Container zu beenden. Das macht eben docker-compose.

Das funktioniert aber alles nur, wenn eine entsprechende Konfigurationsdatei vorhanden ist. Diese Konfigurationsdatei muss den Namen docker-compose.yaml haben, sonst läuft docker-compose nicht. Die Einrückungstiefe der Programmzeilen sollte mit je zwei Leerzeichen erfolgen. Tabs gehe auch, können aber Problem verursachen.

Der Inhalt der Datei ist nun so aufgebaut, dass das gleiche erreicht wird, wie in den obigen Beschreibungen dargestellt. So sieht es aus:
version: '3.1'

services:

meinghost:
image: ghost
restart: always
ports:
- 8081:2368
volumes:
- ./ghost:/var/lib/ghost/content
environment:
url: http://localhost:8081
Die Ausführung von docker-compose zum Start des Tools ist dann wie folgt vorzunehmen:

Code: Alles auswählen

$ docker-compose up -d
Creating network "dockerdata_default" with the default driver
Creating dockerdata_meinghost_1 ... done
Es wird bei der Ausführung ein Default-Netzwerk eingerichtet. Auch Netzwerke kann man in Docker wie Images, Container und Volumes selber erstellen und verwalten. In dem Script ist das aber nicht erfolgt, daher wird ein Default-Netzwerk ausgeführt.

Ob die Ausführung des Befehl gelungen ist, zeigt wieder eine Überprüfung der laufenden Container:

Code: Alles auswählen

$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                       NAMES
3311a4b8aa24   ghost     "docker-entrypoint.s…"   4 minutes ago    Up 4 minutes    0.0.0.0:8081->2368/tcp, :::8081->2368/tcp   dockerdata_meinghost_1
52e8545e09eb   ghost     "docker-entrypoint.s…"   32 minutes ago   Up 32 minutes   0.0.0.0:3001->2368/tcp, :::3001->2368/tcp   myghost
Hier ist zu sehen, dass zwei Container laufen. Der erste Container ist der mit docker-compose erzeugte Container, der auf Port 8081 läuft. Der zweite Container ist der vorhin erstellte Container, der auf Port 3001 gelegt wurde.

Auch der mit dem Script erzeugte Container nutzt das vorhandene Volume und zeigt die gleiche Webseite an.
screener_07.png
Egal, was mit den Containern passiert, solange das Volume unangetastet bleibt, kann man mit jedem Container auf das Volume zugreifen. Allerdings muss man beim Wechsel des Image aufpassen. Man kann nicht einfach so eine andere Version des Images nutzen. Dazu später irgendwann mal mehr.
Früher tanzten wir Wange an Wange, heute Bauch an Bauch. :shock:
Gesperrt Vorheriges ThemaNächstes Thema

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste