Docker Grundlagen

##Was ist Docker? Mit Docker können wir unsere Anwendung und die dazugehörende Plattform ( Betriebsystem, Laufzeitumgebung, Libraries … ) in ein Image packen und diese von jedem Gerät abspielen lassen. Grundvoraussetzung ist, dass auf dem Gerät Docker installiert ist. Docker kann das Image lesen und erstellt einen Container, der auf allen Geräten, sowohl auf einem Computer, Laptop oder Cloud läuft.

##Docker installieren Damit Docker auf dem Mac und Windows installiert werden kann und auch funktioniert, benötigen wir ein zusätzliches Programm: boot2docker. Sobald boot2docker heruntergeladen und installiert ist, kann es gestartet werden. Im Terminal müssen wir boot2docker init boot2docker up eingeben. Sobald im Terminal: docker ps ausgeführt wird und es kommt keine Fehlermeldung wie: no such file or directory. Are you trying to connect to a TLS-enabled daemon without TLS? ist alles in Ordnung.

Was muss ich tun, falls ich doch eine Fehlermeldung bekomme?

In deinem Terminal Fenster musst du boot2docker initialisieren: Führe dafür folgenden Befehl aus: boot2docker up und versuche es nochmal mit docker ps. Wenn du magst kannst du $(boot2docker shellinit) in dein .bash_profile hinzufügen. Danach sollte boot2docker bei jedem neuen Terminal Fenster automatisch starten.

##Docker unter Linux installieren

Docker läuft auf Linux nativ. Dafür einfach die Distribution auswählen und der Anweisung folgen: Docker installation

##Docker Image

Bei einem Image handelt es sich um eine Art Template. Dieses Template kann ein Betriebsystem ( z.B Ubuntu ) sein, welches wiederum eine NGINX, PHP oder Node.js Installation beinhaltet. Auch die Anwendung selbst kann in einem Image stecken. Unser Image können wir ganz einfach mit anderen Entwicklern teilen. Das Image kann überall mit Docker verwendet werden. Des Weiteren bietet Docker ein eigenes für Images an.

Wir können auch unseren Terminal verwenden, um nach Images zu suchen: docker search nginx

###Image laden

Sobald wir docker pull nginx ausführen, können wir unserem Docker ein Image hinzufügen. Mit docker images können wir alle Images auflisten.

##Docker Container

Ein Container ist ein Image, welches gerade ausgeführt wird. Wenn ein Image mit docker run nginx ausgeführt wird, spricht man von einem Container. Es ist vergleichbar mit einem Prozess. Wir können mit docker ps alle Container auflisten (ähnlich wie bei Linux ps).

###Container steuern

Mit docker stop ContainerID kann ein Container gestoppt werden. Wird zusätzlich eine docker rm ContainerID ausgeführt, wird der Container dadurch entfernt. Wenn ein Container gestartet werden soll, muss man zuerst die ID des Containers herausfinden. docker ps zeigt nur laufende Container an. Falls du aber zusätzlich alle beendeten Container sehen willst, gebe folgendes ein: docker ps -a. Mit docker start containerID wird dein Container erneuet gestartet. Andernfalls funktioniert das auch mit docker run nginx.

##Container vs Images

###Was ist der unterschied zwischen Image und Container?

Ein Image ist ein Bauplan für Docker. Ein Image besitzt nur "read-only" Rechte und kann nur gelesen werden. Ein Container ist eine Instanz von einem Image und kann zur Laufzeit verändert werden.

##Image erzeugen

Es gibt zwei Möglichkeiten ein Image zu erzeugen oder zu erweitern. Einmal mit Dockerfile oder mit "Commits", wobei das letzte etwas mehr Bedarf als ein commit. Aber dazu später mehr. Beginnen wir zuerst mit dem Dockerfile.

##Dockerfile

Wir erstellen ein "Dockerfile" in unserem Projekt Ordner. mkdir my-project && touch Dockerfile Ein Dockerfile beinhaltet alle Befehle für die Erstellung eines Images. In der folgenden Liste, habe ich eine Auswahl der Dockerfile Befehle aufgelistet.

###FROM From beinhaltet ein Image, welches wir verwenden wollen. Als Basis können wir ein Betriebssystem verwenden z.B. FROM ubuntu:latest. Voraussetzung dafür ist, dass das Image davor gepullt wurde!

###RUN Run enthält ein Linux-Befehl für die Shell z.B. RUN mkdir /www && touch index.html

###ADD

Mit add können Dateien in den Container geladen oder überschrieben werden. Nützlich wenn Config Dateien überschrieben werden müssen. Beispiel: ADD ./unser-config/nginx.conf /etc/nginx/nginx.conf.

###EXPOSE

Mit Expose können Container an einen bestimmten Port gebunden werden. z.B EXPOSE 80

Hier mal Dockerfile Beispiel:

# nginx als Basis Image verwenden
# nginx wiederum verwendet das debian Betriebssystem!
FROM nginx:latest 
 
# Paketliste aktualisieren
RUN apt-get -y update
 
# php5-fpm installieren
RUN apt-get -y install php5-fpm # php installieren
 
# config files überschreiben
ADD ./php-config/www.conf /etc/php5/fpm/pool.d/www.conf
ADD ./nginx-config/default.conf /etc/nginx/conf.d/default.conf
ADD ./nginx-config/nginx.conf /etc/nginx/nginx.conf
 
# Einen www Ordner erzeugen
RUN mkdir /www
 
# index.php in den www Ordner kopieren 
ADD /www/index.php /www
 
# php5fpm starten
RUN service php5-fpm start
 
# nginx webserver neustarten
RUN service nginx restart
 
# Container auf Port 80 binden
EXPOSE 80

Sobald wir unser Dockerfile haben, können wir daraus ein Image machen, indem wir folgenden Docker Befehl verwenden: docker build [path/to/dockerfile] docker build -t mein-image-name

Mit -t können wir unserem Image ein tag-Namen zuweisen. Image als Container starten:

docker run -d mein-image-name

Das "-d" sorgt dafür, dass der Container im Hintergrund läuft.

Wenn wir im Browser http://127.0.0.1 aufrufen, sollte unser "mein-image-name" laufen. Wenn du meine Beispiel Datei verwendest, sollest du "echo phpinfo()" sehen. Bei denjenigen die boot2docker verwenden, wird http://127.0.0.1 nicht funktionieren. Dafür muss im Terminal vorerst boot2docker ip aufgerufen und die angezeigte IP verwendet werden. Bei mir ist es die: 192.168.59.103

##Alternative zu Dockerfile

Images und Container können auch ohne Dockerfile erstellt werden, indem der docker commit Befehl verwendet wird. Im nächstem Abschnitt erkläre ich, wie ein Node.js Image erstellt wird. Dafür verwende ich kein Dockerfile, sondern docker commit.

###Ubuntu aus dem Repository laden

Wir öffnen unseren Terminal. Der erste Schritt mit Docker, ist das pullen eines Betriebssystems.

Wir holen uns das ubuntu Image: docker pull ubuntu. Danach starten wir den Ubuntu Container: docker run -t -i ubuntu. Das "-i" und "-t" erlauben uns, die Konsole von ubuntu zu steuern. Bei manchen Images ist ein zusätzliches "/bin/bash" erforderlich! docker run -t -i nginx /bin/bash. Danach sollten wir uns im Ubuntu befinden.

###Ubuntu Container starten

Zuerst müssen wir unsere Paketliste erneuern. Denn davor können keine Pakete installiert werden. apt-get update. Nach dem update können wir "nodejs" und "npm" Pakete herunterladen. apt-get install -y nodejs apt-get install -y npm

Wenn wir npm -v und nodejs -v ausführen, sollten wir Versionsnummern sehen. Danach erstellen wir ein /www Ordner und in diesem speichern wir eine index.js Datei.

mkdir -p www && touch www/index.js

Jetzt muss die index.js Datei beschrieben werden. Entweder bearbeiten wir es im Container oder auf unserem System und überschreiben die index.js mit docker cp. Wenn es auf dem Server bearbeitet werden soll, sollte davor ein Editor installiert werden:

apt-get install -y nano

Danach kann mit nano die index.js bearbeitet werden:

nano /www/index.js

oder falls sich auf eurem System bereits eine index.js befindet, kann auch diese auf den Container geladen werden. Doch das werde ich an dieser Stelle erstmal überspringen. Am Ende sollte die index.js so aussehen:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello from Docker!');
 
}).listen(8888);

###Docker commit

Jetzt ist nodejs und npm auf unserem Container installiert. Zusätzlich auch noch eine index.js, welche unsere Anwendung repräsentieren soll. Jetzt wollen wir aus unserem Container ein Image machen. Dafür verlassen wir ubuntu, mit dem exit Befehl. Mit exit schließen wir den Container. Wenn wir docker ps ausführen, sollte kein Container mehr laufen. Allerdings brauchen wir für den nächsten schritt die ubuntu Container ID. Diese können wir mit docker ps -a aufrufen. Wir führen docker ps -a aus und merken uns die Container ID (copy)

Mit docker commit können wir aus unserem Container ein Image machen.

docker commit -m "add node and npm" containerID image-name

Wenn du ubuntu Image überschreiben möchtest:

docker commit -m "add node and npm" a0f87d36b1b6 ubuntu:latest

Wenn du ein neues Image anlegen möchtest:

docker commit -m "add node and npm" a0f87d36b1b6 my-nodejs:0.1

Jetzt sollten wir ein "my-nodejs" Image haben. Diesen können wir im Hintergrund starten:

docker run -d -p 8000:8888 my-nodejs:0.1 nodejs /www/index.js

Wenn wir http://127.0.0.1:8000 bzw. http://192.168.59.103:8000 im Browser aufrufen, sollten wir unsere Anwendung sehen.

Kleiner Hinweis noch zu index.js:

Mit docker cp my-nodejs:0.1:/www/index.js /unsere/node-app/index.js können wir die index.js durch unsere lokale ersetzen, anstatt mit nano editieren zu müssen.

Zurück