Docker
Docker ist ein mächtiges Werkzeug, um plattformübergreifend und ohne Installation von Servern etc. diese laufen zu lassen. Es bedient sich dabei ganz ok, dennoch: die Lernkurzve ist sinusförmig
- Doku: https://docs.docker.com/
- Hub: https://hub.docker.com
- Docker-CLI: https://docs.docker.com/engine/reference/commandline/cli/
- Compose-CLI: https://docs.docker.com/compose/reference/overview/
- Dockerfile: https://docs.docker.com/engine/reference/builder/
- Compose-File: https://docs.docker.com/compose/compose-file/
Installation
Docker installieren
Docker-CE nehmen, Installationsanleitung:
Den GPG-Key installieren und den Fingerprint 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
verifizieren:
$ sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - $ sudo apt-key fingerprint 0EBFCD88 pub 4096R/0EBFCD88 2017-02-22 Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 uid Docker Release (CE deb) <docker@docker.com> sub 4096R/F273FCD8 2017-02-22
Dann die deb-Zeile für die Paketverwaltung herauskriegen:
$ echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
Unter LinuxMint noch mal schauen, ob $(lsb_release -cs)
den richtigen Wert geliefert hat.
Das Ergebnis in die Paketverwaltung eintragen und installieren:
- docker-ce
- docker-ce-cli
- containerd.io
Docker-Compose installieren
Binary runterladen, ablegen und ausführbar machen:
Zunächst herusfinden, welche die aktuelle Version von docker-compose ist:
Die Versionsnummer dann hier ergänzen:
$ sudo curl -L https://github.com/docker/compose/releases/download/<version>/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose
Die Code-Completion aus Faulheit gleich noch dazu:
$ sudo curl -L https://raw.githubusercontent.com/docker/compose/<version>/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
Testen
$ docker-compose --version docker-compose version 1.17.1, build 6d101fb
Docker-Gruppe
Wenn die aktuelle Nutzerin nicht in der docker-Gruppe ist, muss docker immer als root gestartet werden: unbequem, Sicherheitsrisiko und Problem mit Dateizugriffsrechten.
Gruppen auflisten, nach docker filtern und Gruppen anzeigen, zu denen die aktuelle Nutzerin gehört:
$ cat /etc/group $ cat /etc/group | grep docker $ groups $USER $ cat /etc/group | grep $USER
Gruppe anlegen (wenn sie nicht existiert) und Nutzerin hinzufügen:
$ sudo groupadd docker $ sudo usermod --append --groups docker $USER
Jetzt am besten neu starten, damit Code Completion und Gruppenzugehörigkeit übernommen werden. It's the only way to be sure.
Wordpress-Entwicklung mit Docker
Statt die Produktivumgebung zu zerstören, kann man prima ein Plugin mit Docker entwickeln, testen und dann ausliefern.
- Docker-Compose-Konfigurationsdatei erstellen
- Container mit docker-compose starten
- Container mit docker-compose stoppen
Die Schritte 4 und 5 dann immer, wenn entwickelt werden soll.
Docker-Compose-Konfigurationsdatei erstellen
Einstellungen für die Seite. Eigentlich fast direkt aus Doku kopiert:
Dateiname: docker-compose.yml
Hier sind die Entwicklungsdateien korrekt einzubinden.
Dafür wird bei volumes
ein Mapping angelegt vom Dateisystem in das Docker-Dateisystem.
Im Beispiel liegen die Entwicklungsdateien des Plugins postpone-posts
im Verzeichnis ../postpone-posts/
relativ zur Konfigurationsdatei.
Dieses Verzeichnis wird von Docker für Wordpress in das Verzeichnis /var/www/html/wp-content/plugins/postpone-posts
gemappt.
Zusätzlich binde ich noch phpmyadmin ein, um die Änderungen an der Datanbank nachverfolgen zu können.
version: '3' services: db: image: mysql:5.7 volumes: - db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress volumes: - "../postpone-posts/:/var/www/html/wp-content/plugins/postpone-posts" phpmyadmin: image: phpmyadmin/phpmyadmin container_name: phpmyadmin environment: PMA_ARBITRARY: 1 PMA_HOST: db PMA_PORT: 3306 PMA_USER: wordpress PMA_PASSWORD: wordpress restart: always ports: - 8080:80 volumes: - /sessions volumes: db_data:
Docker starten
Der Start erfolgt über Docker-Compose, beim ersten Start werden alle benötigten Dateien heruntergeladen.
$ sudo docker-compose up -d
Die Wordpress-Installation ist danach verfügbar unter
phpmyadmin ist erreichbar unter
Docker stoppen
Auch das Stoppen erledigt Docker-Compose.
$ sudo docker-compose down
Wordpress-Debugging
Für den Test eines Plugins muss man die debug-Variable WP_DEBUG
auf true
setzen.
Dies geschieht über die Datei wp_config.php
, die im Root-Verzeichnis der Wordpress-Installation liegt.
Diese Datei muss man aus dem Container extrahieren und dann einbinden oder in den Container zurückkopieren, wie man möchte.
Dazu findet man zuerst die ID oder den Namen des Containers heraus:
$ sudo docker container ls CONTAINER ID IMAGE ... NAMES 032d18e6d816 wordpress:latest dev_wordpress_1 56aabe83c2f2 mysql:5.7 dev_db_1 49d804195636 phpmyadmin/phpmyadmin phpmyadmin
Wordpress ist also unter der ID 032d18e6d816
oder dem Namen dev_wordpress_1
ansprechbar.
Wir kopieren die Datei in das lokale Verzeichnis:
$ sudo docker cp dev_wordpress_1:/var/www/html/wp-config.php .
Jetzt können wir die Datei editieren und dann zurückspielen.
Ich bevorzuge das Zurückkopieren in den Container nach jeder Änderung, damit Änderungen durch das System erfasst werden (die theoretisch nicht auftreten sollten, aber...)
$ sudo docker cp wp-config.php dev_wordpress_1:/var/www/html/
Dabei muss man "nur" daran denken, vor jeder Änderung wieder eine Kopie aus dem Container zu holen und diese zu modifizieren.
Will man testen, ob der debug-Modus eingeschaltet ist, hilft folgender Code:
if (defined('WP_DEBUG') && true === WP_DEBUG) { echo '<p>Debug mode</p>'; }
Docker-Netzwerk / Zugriff zwischen Containern
Ausgangslage
- zwei Docker-Container
- Apache auf Port 8080
- Python
Problem
- Zugriff auf Apache vom Rechner aus über http://localhost:8080/ möglich, sowohl im Browser als auch per direktem Aufruf aus Python
- Zugriff auf Apache vom Python-Docker-Container nicht möglich (connection refused)
- eine gute Beschreibung des zugrundeliegenden Problems: https://pythonspeed.com/articles/docker-connection-refused/
Lösung
- Docker-Container, die aufeinander zugreifen sollen, müssen im selben Netzwerk laufen
- docker selbst über explizites Erstellen und Nutzen eines Netzwerks
- im Python-Container erfolgt der Zugriff dann über http://myserver:80/
$ sudo docker network create mynetwork $ sudo docker run --publish 8080:80 --network mynetwork --rm --name myserver httpd:alpine & ... $ sudo docker run --rm --interactive --tty --network mynetwork --volume "${PWD}":/usr/src/myapp --workdir /usr/src/myapp python:rc-alpin script.py ... $ sudo docker container stop myserver $ sudo docker network rm mynetwork
- in docker-compose kann das Netzwerk über
networks:
erstellt und genutzt werden
Shell/bash in Container starten
Container normal starten, via docker oder docker-compose, dann:
$ docker exec --interactive --tty <container_name> bash