- Installation
- Docker-Images
- Eigener Container für Node.js
- Eigener PHP Docker-Container
- Dockerfile für Django
- Server-Installation aus Docker-Hub
- Export und Import von Docker-Containern
- Docker-Befehle
- Links
Typisches Beispiel: Backend-Anwendungen im Web
Eine solche Anwendung läuft in einem Container. Auf einem Host können mehrere Container laufen.
- Ein Docker-Container läuft auf einer lokalen Maschine, isoliert von den anderen Prozessen dieser Maschine.
- Der Docker läuft im Gegensatz zu einer virtuellen Maschine auf dem vorhandenen Linux-Kernel des Gastgebers.
- Ein Container ist eine Instanz von einem Image. Das Image ist schreibgeschützt und kann so die Basis mehrerer Container bilden. Es enthält ein isoliertes Dateisystem. Das Image muss alles enthalten, was der Container zu seiner Ausführung benötigt. Um eigene Container laufen zu lassen, muss also ei Image erzeugt werden.
- Docker-Container sind portierbar, können auf anderen Linux-Maschinen und virtuellen Maschinen laufen. Sie laufen sogar unter Windows. Allerdings muss Docker dann eine virtuelle Maschine mit einem Linux-Kernel zur Verfügung stellen.
Installation
Die Docker-Software wird im Repository von Debian, Ubuntu und Linux Mint im Paket docker.io zur Verfügung gestellt und kann entsprechend direkt von dort installiert werden.# apt update # apt install docker.ioAnmerkung: Es gibt auch ein Paket docker. Das ist aber eine komplett andere Software.
Docker-Images
Der Befehl docker pull lädt ein Image aus dem Docker-Hub herunter. Auf den Docker-Hub werden wir weiter unten noch eingehen. Das folgende Beispiel holt sich das aktuellste Ubuntu-Image.# docker pull ubuntu:latest latest: Pulling from library/ubuntu a48641193673: Pull complete Digest: sha256:6042500cf4b44023ea1894effe7890666b0c5c7871ed83a97c36c76ae560bb9b Status: Downloaded newer image for ubuntu:latest docker.io/library/ubuntu:latestDer Befehl docker images zeigt alle auf dem Host verfügbaren Images. Nach dem obigen Pull-Befehl steht natürlich das Ubuntu-Image zur Verfügung.
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 174c8c134b2a 2 weeks ago 77.9MBInteressant ist die Größe! Nur knapp 80 MB. Das liegt daran, dass nur das minimale System geladen ist (kein Office) und der Kernel des lokalen Linux verwendet wird.
Mit dem Befehl docker run kann ein Container auf der Basis des Images ubuntu gestartet werden. Hier wird eine Bash gestartet.
# docker run -it ubuntu /bin/bash root@5aee8b6ff6b3:/#Sollte das Ubuntu-Image noch nicht geladen sein, wird es durch diesen Befehl auch heruntergeladen.
Mit der Bash kann man nun das Image beispielsweise durch apt-Aufrufe erweitern. Eine Web-Anwendung kann also direkt im Image angelegt werden und als Container gestartet werden.
Docker-Hub
Das Basis-Image ubuntu, das mit docker pull geladen wurde, kommt aus dem Docker-Hub. Im Docker-Hub werden viele Images für verschiedenste Zwecke angeboten, auf deren Basis eigene Images erstellt werden kann.https://hub.docker.com/search?type=image
Eigener Container für Node.js
Node.js ist eine Laufzeitumgebung, mit der Webanwendungen in JavaScript erstellt werden können.Gerade Webanwendungen bestehen aus mehreren Komponenten, die in Containern zusammengefasst werden können, um damit Versionskonflikte auszuschließen.
Direkterzeugung eines Images
Als Basis des Node.js-Containers wird ein Ubuntu-Image vom Docker-Hub geladen. Darin werden die Node.js-Komponenten installiert und schließlich die eigene Anwendung angelegt.Basis: Laden des Ubuntu-Images
# docker pull ubuntu:latestHier dem Doppelpunkt kann explizit eine Version angegeben werden. Die Angabe latest verwendet die neueste verfügbare Version.
Um das Image zu ändern, wird mit docker run eine Shell aufgerufen:
# docker run -it ubuntu /bin/bash root@cb977a2459b5:/#Die Shell läuft innerhalb des Ubuntu-Containers. Von der Shell aus kann im Docker eine Node.js-Umgebung installiert werden:
# apt update # apt install nodejs npm vimDie eigene Anwendung muss man natürlich selbst erstellen. Als sehr einfaches Beispiel wird ein kleines Testprogramm index.js im Verzeichnis /var/www des Containers angelegt:
# mkdir /var/www # vi /var/www/index.jsDas kleine Beispielprogramm liefert lediglich ein Hallo an den Browser, der den Server abfragt.
var http = require('http'); http.createServer(function(req, res) { res.end('Hallo'); }).listen(8080);Damit ist alles vorbereitet. Das Verlassen des Containers erfolgt über die Tastenkombination [Strg}+[P] [Strg]+[Strg]+[Q] oder dem Befehl exit.
Das veränderte Image soll nun unter einem neuen Namen gespeichert werden.
- Dazu muss zunächst die ID des Containers ermittelt werden:
# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fd05e3473b6f ubuntu "/bin/bash 12 minutes ago
- Anhand dieser kann ein neues Image erzeugt werden:
# docker commit -m "NodeJs" fd05e3473b6f meinnodejs:0.1
# docker run -d -p 8080:8080 meinnodejs:0.1 nodejs /var/www/index.js
- Option -p: Portnummern freigeben.
- -p 8080:8080: Die Portnummer 8080 des Containers wird auf den Port 8080 des Gastgeber-Ports durchgereicht.
Installation per Dockerfile
Anstatt die Installation innerhalb des Containers Schritt für Schritt zu vollziehen, kann auch eine Batch-Datei namens Dockerfile verwendet werden. Dafür nehmen wir als Beispiel das gleiche Node.js-Programm index.js wie bei der Direkterzeugung.var http = require('http'); http.createServer(function(req, res) { res.end('Hallo'); }).listen(8080);Es wird außerdem die Datei Dockerfile benötigt, in der steht, auf welchem Basis-Image aufgesetzt wird, was gestartet und was kopiert werden muss, um das fertige Image zu erzeugen.
# Der Basis-Container, auf dem der Container aufsetzen soll: FROM ubuntu # Starte alle Befehle, die in dem neuen Container ablaufen sollen: RUN apt update && apt install -y nodejs npm RUN mkdir /var/www # Kopiere die lokal erstellte Datei nach /var/www in den Container!: COPY index.js /var/www
- FROM: Der Basis-Container auf dem das neue Image basieren soll.
- RUN: Programme innerhalb des Containers starten. Mit apt wird die Node.js-Umgebung installiert. Ebenfalls mit RUN legen Sie ein Verzeichnis an, in dem das NodeJS-Programm abgelegt werden soll, hier /var/www.
- COPY: Dateien des lokalen Systems werden in den Container kopiert. Die Syntax entspricht dem Befehl cp.
# docker build -t meinnodejs .In der Liste der Images taucht nun das eigene Image neben ubuntu auf.
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE meinnodejs latest e2c096a1936c 4 minutes ago 978MB ubuntu latest 08d22c0ceb15 2 weeks ago 77.8MBDas Starten des Images funktioniert wie gehabt. Getestet wird wieder über Firefox mit der URL localhost:8080.
# docker run -d -p 8080:8080 meinnodejs:latest nodejs /var/www/index.js
Eigener PHP Docker-Container
Eine andere Programmierumgebung für Web-Anwendungen ist PHP. Auch dafür soll ein Docker-Container erstellt werden. Allerdings bietet hier Docker-Hub ein gut angepasstes Basis-Image an.Als erstes legen wir ein Verzeichnis an, in dem wir eine PHP-Datei erstellen.
$ mkdir docker-lamp $ cd docker-lamp/ $ vi index.phpDie PHP-Datei index.php enthält verschiedene PHP-Anweisungen und wird beim Aufruf verschiedene Parameter des Servers anzeigen.
<!DOCTYPE html> <html> <head> <title>Hallo Docker</title> </head> <body> <h1>Mein erster Container</h1> <?php $load = sys_getloadavg(); ?> Serverzeit: <?php echo date("c"); ?><br /> Serverauslastung (load): <?php echo $load[0]; ?> </body> </html>Nun wird die Datei Dockerfile erzeugt, die angibt, dass das Image php die Basis bildet und dass die Datei index.php in das Image kopiert werden soll.
FROM php:7-apache ENV TZ="Europe/Berlin" COPY index.php /var/www/htmlDurch den Befehl docker build werden folgendes passieren:
- FROM: Das Basis-Image wird vom Docker-Hub geladen.
- ENV: Environment-Variablen setzen
- COPY: Kopieren der Quelldateien in das Image.
# docker build -t mein-erster-container . Install the buildx component to build images with BuildKit: https://docs.docker.com/go/buildx/ Sending build context to Docker daemon 3.072kB Step 1/3 : FROM php:7-apache 7-apache: Pulling from library/php a603fa5e3b41: Pull complete c428f1a49423: Pull complete d2c43c5efbc8: Pull complete ... ab590b48ea47: Pull complete 80692ae2d067: Pull complete 05e465aaa99a: Pull complete Digest: sha256:c9d7e608f73832673479770d66aacc8100011ec751d1905ff63fae3fe2e0ca6d Status: Downloaded newer image for php:7-apache ---> 20a3732f422b Step 2/3 : ENV TZ="Europe/Berlin" ---> Running in ac5e1f656ce0 Removing intermediate container ac5e1f656ce0 ---> 4abad7f79cee Step 3/3 : COPY index.php /var/www/html ---> 818226e52869 Successfully built 818226e52869 Successfully tagged mein-erster-container:latest} Das erstellte Image kann nun gestartet werden. Der Port wird dabei auf 8080 umgeleitet.
# docker run -p 8080:80 mein-erster-containerAuf dem lokalen Host wird Firefox mit der URL http://localhost:8080 aufgerufen. Es erscheint folgendes Bild:
Quelle: https://goneuland.de/docker-einfache-beispiel-container
Dockerfile für Django
Django ist ein Framework zur Erstellung von Web-Anwendungen in Python. Die Erstellung des Django-Projekts ist auf der Seite über Django genauer beschrieben. Hier soll es in erster Linie um die Erstellung des Dockerfile und der Erzeugung des Images gehen.
FROM python:3.9 #Install Django and other required packages RUN pip install django # Copy the Django project files into the image COPY . /app # Set the working directory WORKDIR /app # Start the Django development server CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]Docker-Hub empfielt zur Zeit (Januar 2024) explizit nicht die Verwendung des Basis-Images django. Stattdessen wird das Image python verwendet und mithilfe des Installationsprogrammes pip Django automatisch nachinstalliert.
Quelle: https://hackernoon.com/de/wie-man-Django-Anwendungen-dockerisiert-und-bereitstellt
Server-Installation aus Docker-Hub
Docker-Hub bietet auch vollständige Server-Images, die in einem Docker quasi out of the box lauffähig sind. Als Beispiel soll hier die Installation eines GitLab-Servers vorgestellt und diskutiert werden.Tatsächlich lässt sich das Image einer Community-Edition von GitLab direkt als Image mit docker pull herunterladen.
# docker pull gitlab/gitlab-ceDer Start des Dockers dauert eine Weile.
# docker run -p 8081:80 gitlab/gitlab-ce
- docker run erzeugt aus dem Image einen Container und startet ihn.
- -p 8081:80 Der Docker-Port 80 wird auf den Host-Port 8081 gelegt.
Hier unterscheidet sich die native Einrichtung erheblich. Denn dort wird beim ersten Start das Passwort des Administrators gesetzt. Das ist in der Docker-Variante aber bereits geschehen. Nun muss ermittelt werden, welches Passwort vergeben wurde. Dazu wird die Konfigurationsdatei durchsucht.
- Der Befehl docker container ps -a: liefert die benötigte Container-ID
# docker container ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS 67b8091f5d3a gitlab/gitlab-ce "/assets/wrapper" 42 minutes ago Up
- Der Befehl docker exec ruft den Befehl grep im Container auf
und durchsucht damit die entsprechende Konfigurationsdatei nach dem Stichwort "Passwort".
# docker exec -it 67b8091f5d3a \ grep 'Password:' /etc/gitlab/initial_root_password Password: U/TETbV04MDqp3+YRtwSSZ7IGMIBwAU0HLr3NsdWP5E=
- Dieses Passwort merken Sie sich kurz. Falls Ihnen das nicht gefällt, können Sie es natürlich auch mit der Maus markieren und mit der Tastenkombination [Strg]+[Shift]+[C] kopieren.
- In der Eingabemaske geben Sie das Passwort ein (oder fügen es mit [Strg]+[V] ein).
Fazit:
- Der Aufwand einer direkten Installation mit einer Docker-Installation ist zumindest unter Linux vergleichbar.
- Vorteil aufeinander abgestimmter Versionen der Komponenten: Ist bei einem Linux-System durch das Repository gegeben.
- Interessant ist die Verwendung von Docker vor allem für Installation eines Servern auf Windows-Rechnern, vor allem, wenn es dafür keine native Installation gibt.
- Nachteile einer solchen Installation auf einem Windows-Servers:
- Stabilität und Sicherheit: Windows dient nur als Plattform, um darauf einen Linux-Kern in einer VM laufen zu lassen, um darauf den Docker zu betreiben, auf dem der eigentliche Server installiert ist.
- Overhead
- Performanceverlust: aufgrund des Overheads und des für Windows obligatorischen Virenscanners
Export und Import von Docker-Containern
Für den Export eines Containers muss dessen Name bekannt sein. Die Ausgabe des Befehls docker container ls -a wurde hier etwas verkürzt.# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b92715d33551 mein-erster-container "docker 15 hour Exited zen_khayyam 3d504a19e6ec mein-erster-container "docker 15 hour Exited sad_poitras b5b6e0f48a2a mein-erster-container "docker 15 hour Exited elated_bartik ba672f4d5ef7 mein-erster-container "docker 15 hour Exited exciting_moser 5aee8b6ff6b3 ubuntu "/bin/b 5 days Exited focused_johnson e7f4f23a421f ubuntu "-it /b 5 days Created priceless_mendelÜber diesem Namen wird exportiert. Das Ergebnis wird mit gzip gepackt in einer Datei abgelegt.
# docker export sad_poitras | gzip > sad_poitras.gzDie erzeugte Datei sad_poitras.gz kann nun auf eine andere Maschine (bspw. per scp) übertragen werden, um sie dort wieder zu importieren.
# zcat sad_poitras.gz | docker import - sad_poitras sha256:6bc7c3db6c08a742f109b1493d825bc584ba6d77da215c79178b0bb0c21fd1aaMan kann den Container betrachten:
# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 90079c31e5e4 sad_poitras "/bin/bash" 23 seconds ago Exited (0) 11 seconds ago lucid_perlman # docker images REPOSITORY TAG IMAGE ID CREATED SIZE sad_poitras latest 6bc7c3db6c08 About a minute ago 446MBUnd natürlich auch starten:
# docker run -i -t sad_poitras /bin/bash root@90079c31e5e4:/#
Docker-Befehle
Die Kommandos von docker kann man sich mit dem folgenden Befehl anzeigen lassen.$ docker help | more
Links
- Einführung in Docker: docs.docker.com/get-started
- Dockerfile: https://www.ionos.de/digitalguide/server/knowhow/dockerfile
- Export und Import von Docker-Containern: https://www.techrepublic.com/article/how-to-exportimport-containers-with-docker
- Informationen zu Node.js: http://willemer.de/informatik/web/nodejs.htm