Donnerstag, 3. März 2022

Dockerfile - Image für den Container selbst bauen

Das hier ist mehr ein persönliche Machbarkeitsstudie und soll kein Ansatz für ein dauerhaft gepflegtes Dockerimage werden. Ich wollte wissen wie es geht und den Vorgang verstehen. herausgekommen ist erstmal ein kurzes Beispiel und ein minimales FHEM Image.

Kurz vornweg: Hier ein Script welches die gesamte docker Umgebung und das FHEM Image baut. Damit hat man auf einem Intel PC in weniger als 2 min (Pi3 ca. 6 min) ein funktionierendes FHEM. 

Man braucht nicht viel: Ein Dockerfile, dazu eine Umgebung (Context) - das ist der Pfad mit dem Dockerfile und ein paar Scipts o.ä.

Achtung: Der Context (das Verzeichnis wo das Dockerfile liegt) wird beim build Prozess an den docker Prozess gesendet, dieser sollte also nur die notwendigen Dateien enthalten! Sehr lesenswert ist dieses dockerfile best practice Guide.

Fingerübung zum Einstieg

Ein erstes praktisches Beispiel: ein aktueller debian Container mit ein paar Packages. Zunächst einen leeren Context erzeugen.

myPath=fingerExercise && mkdir -p $myPath && cd $myPath

Man erzeugt eine Datei Dockerfile mit diesem Inhalt.

FROM debian
RUN apt update && apt install -y \
    sendemail \
    libcpanel-json-xs-perl \
    libcrypt-rijndael-perl \
    libfile-homedir-perl \
    libhtml-treebuilder-xpath-perl \
    libimage-librsvg-perl \
    libnet-telnet-perl \
    libsoap-lite-perl \
    libxml-simple-perl \
    libxml-xpath-perl \
 && rm -rf /var/lib/apt/lists/*

Anschließend wird das Image gebaut, entweder namenlos oder mit Namen (tag) und Version. Der Punkt steht für den Pfad wo das Dockerfile liegt, den kann man auch komplett angeben.

docker build .
docker build -t debiantest:Basis .

Dieses Image ist nur nützlich, um es interaktiv auszuführen, es tut (startet) selbst nichts. 

Beispiel: starte eine shell:

docker run -it debiantest /bin/sh


Minimales FHEM Image

Grundlage ist ein Alpine Image, in dem Dockerfile werden 

  • einige Pakete installiert, 
  • ein paar Einstellungen (Zeitzone, Konsole) gemacht, 
  • der User fhem erzeugt,
  • ein Startscript und ein Hilfscript eingebaut. 

2 Möglichkeiten

  1. Man zieht den Dockerfile (und ev. die Scripts) vom Github , kann Anpassungen vornehmen und der build Befehl ist analog zu oben. 
  2. Oder man baut das Image einfach direkt mit der url ohne context:

docker build -t minifhem https://raw.githubusercontent.com/heinz-otto/fhem-docker/main/Dockerfile

Anmerkung: Es gibt viele Varianten wie man docker build aufrufen kann: siehe Dokumentation. 

Der build Vorgang kann mit der Option --build-arg PACKAGE_SIZE=full  angepasst werden.

Jetzt kann man einen FHEM Container starten, dazu wird noch ein Volume- und Port-Mapping angefügt. Will man eine vorhandene FHEM Installation verwenden, muss die vor dem Start nach ${HOME}/docker/fhem kopiert werden.

Den (leeren) FHEM Arbeitspfad erzeugen:

mkdir -p ~/docker/fhem

Entweder den Pfad mit einer frischen Version initialisieren oder ein Backup, im Homedir oder im lokalen /opt/fhem/backup mit restore einbinden:

docker run -v "${HOME}/docker/fhem:/opt/fhem" -p "8083:8083" minifhem init tar
tar -xvzf ${HOME}/FHEM-20xxxxxx_xxxxxx.tar.gz -C ${HOME}/docker/fhem/
tar -xvzf /opt/fhem/backup/FHEM-20xxxxxx_xxxxxx.tar.gz -C ${HOME}/docker/fhem/

FHEM Container  starten:

docker run -v "${HOME}/docker/fhem:/opt/fhem" -p "8083:8083" minifhem

FHEM Image auf debian Basis

Das wird sicher auf Dauer besser ankommen und zu pflegen sein. Ich habe hier auch noch ein paar Erweiterungen zum Test eingebaut. Der Start erfolgt analog zu oben. 

Argument PACKAGE_SIZE:

  • small - fhem.cfg.demo läuft, das Installermodul sagt: es fehlt an nichts!
  • full - meine FHEM Umgebung läuft damit (als default im Dockerfile gesetzt)
  • full_audio - pulseaudio integriert und Sound über Pulseaudio möglich (Imagesize fast verdoppelt)


docker build -t debianfhem --build-arg PACKAGE_SIZE=small https://raw.githubusercontent.com/heinz-otto/fhem-docker/main/DockerfileDeb
docker run -v "${HOME}/docker/fhem:/opt/fhem" -p "8083:8083" --name testfhem debianfhem

Mit dem Installer Modul kann man mit diesem Image seine cfg testen. Diese muss dazu einfach im docker/fhem Pfad (auf dem Host) liegen: Im Beispiel fhem.cfg.test

Achtung: Im aktuellen Homedir (Arbeitspfad) braucht man auch das ausführbare Script fhemcl.sh.

So sieht der Testablauf aus:

InstallerModul im frischen FHEM definieren 

echo "define installer Installer"|./fhemcl.sh
echo "attr installer installerMode developer"|./fhemcl.sh

apt-file aktualisieren (einmalig zur Laufzeit des Containers), dann die fehlenden Module ermitteln.

docker exec testfhem apt-file update
cfg='fhem.cfg.test'
s=$(./fhemcl.sh 8083 "get installer checkPrereqs $cfg"|grep -oE 'installPerl.*&fwcsrf'|grep -oE '\s[a-z,A-Z,:]+\s')
echo $s|tr ' ' "\n"|sed '/^JSON/d;s/$/./;s/^/\//'|docker exec -i testfhem apt-file search -l -f -

Hat man die benötigten Module gefunden, kann man sie selbst im DockerfileDeb im Abschnitt "full" integrieren und anschließend sein persönliches Image erzeugen.

Den Testcontainer kann man per FHEM Kommando auch wieder beenden

echo "shutdown"|./fhemcl.sh 


Was läuft?

  • FHEM läuft grundlegend, ich habe keine weiteren Modulabhängigkeiten getestet. Aber es ist simpel weitere System Packages in das Image einzubinden.
  • FHEM wird wie "im richtigen Leben" mit user fhem gestartet
  • Beim Aufruf des Containers kann das default Kommando start überschrieben werden. Details dazu gibt es in der Readme in github. Man kann z.B. das verbundene Verzeichnis (${HOME}/docker/fhem) initialisieren: 
    • Entweder über svn checkout die aktuelle Version,
    • oder der tarball 6.1 von der fhem.de Homepage.
  • Um FHEM zu überwachen wird attr global pidfilename ./log/fhem.pid gesetzt. Die damit verbundene, eventuelle Veränderung der Konfiguration wird nicht gespeichert. Achtung: Ist der Eintrag nicht in der config, klappt ein shutdown restart nicht.
  • Das Eigentumsrecht des gesamten gemappten Pfades (${HOME}/docker/fhem) wird beim Start auf User fhem gesetzt.
  • Telnetport 7072 wird nicht benötigt, es wird alles über HTTP Port 8083 gesteuert. Sollte dies mit allowed geschützt werden, müsste das Script entry.sh angepasst werden.

Größe der Basis

In debian ist von Haus aus wesentlich mehr drin.

debian       latest    xxx  5 weeks ago    100MB

alpine       latest    xxx   3 months ago   3.81MB

Tipp: In den "Bauphasen" empfehle ich jedesmal vorm build ein löschen der "Build Cache Umgebung"

docker image rm debianfhem -f
docker system prune

Wenn das Dockerfile fehlerhaft ist und "parse" Fehler auftreten, muss man den build Prozess mit --force-rm starten:

docker build --force-rm ...


ToDo?

Code Block


Keine Kommentare:

Kommentar veröffentlichen