Perl on Docker - Perl commandline Programm als Docker Container erstellen und nutzen

Veröffentlicht von Thomas Fahle am (Permalink)

Camel led by a guide - Wahiba Sands, Oman, Wahiba desert

 

Einführung

Bei Perl-Programmen werden oft eine Menge zusätzlicher Bibliotheken (z.B. CPAN-Module) benötigt, die eigens installiert werden müssen.

Manchmal stehen nur ältere Modul- und Programmversionen zur Verfügung, die von anderen Anwendungen genutzt werden und daher nicht ohne weiteres aktualisiert werden können. Gelegentlich ist es auch umgekehrt: ein altes Tools, das sich nicht oder nur schwer aktualisieren lässt, wird in einer neuen Umgebung mit aktuelleren Bibliotheken benötigt.

Hier bietet es sich geradzu an, die Kommandozeilenanwendung in einen eigenen Container zu verfrachten und diesen als Kommandozeilentool zu verwenden. Auch, wenn man dafür eigens Docker installieren muss. Der Geschwindigkeitsunterschied, der sich durch den Containeroverhead ergibt, ist i.d.R. zu vernachlässigen

 

Beispiel: W3C Link Checker

Den W3C Link Checker - Check links and anchors in Web pages or full Web sites gibt es neben der Onlineversion auch als Ubuntu/Debian Paket in Version version 4.81 und in Version 5.0.0 auf MetaCPAN.

In diesem Beispiel wird das Kommandzeilenprogramm checklink - check the validity of links in an HTML or XHTML document in der neuesten Version per cpanm als /usr/local/bin/checklink in einem eigenen Container mit dem neuesten Perl installiert.

Zu Vergleichszwecken wird das Paket w3c-linkchecker mit installiert, welches eine ältere Version als /usr/bin/checklink liefert.

Der Sourcecode des Beispiels findet sich auch im Github Repo perl-howto-code.

 

Docker Image bauen

Datei Dockerfile

FROM perl:latest

LABEL maintainer="Thomas Fahle <perlhowto.github.io@gmail.com>"
LABEL version="0.10"
LABEL description="W3C::LinkChecker checklink Docker Image"


# apt-get
# Upgrade already installed packages (security)
# Install w3c-linkchecker (/usr/bin/checklink)
# Autoremove unused packages
# Clean local repos
#
# cpanm
# Install W3C::LinkChecker (/usr/local/bin/checklink)
# Install LWP::Protocol::https to enable linkckecking of HTTPS websites
#
# Free disk space to decrease image size
ARG DEBIAN_FRONTEND=noninteractive
RUN set -ex; \
       apt-get update && \
       apt-get dist-upgrade -y && \
       apt-get -y --no-install-recommends install \
       w3c-linkchecker && \
       apt-get -y autoremove && \
       apt-get clean ; \
       /usr/local/bin/cpanm  \
        W3C::LinkChecker \
        LWP::Protocol::https \
        ; \
    rm -rf /var/lib/apt/lists/* ; \
    rm -rf /tmp/* ; \
    rm -rf /root/.cpanm/

ENTRYPOINT ["/usr/local/bin/checklink"]
CMD ["--help"]

Das neue Container-Image basiert auf Official Docker Perl Images, die bereits in Perl on Docker - Offizielle Perl Docker Images als Grundlage eigener Images beschrieben wurden, als Basis. (FROM perl:latest).

Die LABEL-Anweisungen setzen diverse Metadaten, welche die Verwaltung der Images erleichtern sollen.

Mittels apt-get werden zunächst alle installierten Pakete auf den neuesten Stand gebracht und das Ubuntu/Debian Paket w3c-linkchecker in Version version 4.81 installiert. Die Umgebungsvariable DEBIAN_FRONTEND wird per ARG temporär – also nur während des Builds – gesetzt. (Bei der Verwendung von ENV werden Umgebungsvariablen dauerhaft (unveränderlich) im Image gesetzt.)

Im nächsten Schritt werden die CPAN Module W3C Link Checker und LWP::Protocol::https mittels cpanm installiert.

Danach werden noch alle temporären Dateien und apt-repos gelöscht, um das Image so klein wie möglich zu halten.

Im letzten Schritt wird mittels ENTRYPOINT die Anwendung gesetzt, die mit dem Start des Containers gestartet werden soll (/usr/local/bin/checklink). Die CMD-Anweisung setzt die Vorgabe-Parameter für die Startanwendung - hier --help. Diese Parameter können später sehr einfach auf der Kommandozeile überschrieben werden.

Das Image kann jetzt gebaut werden:

sudo DOCKER_BUILDKIT=1 docker build -t w3c-checklink .

 

Docker Container nutzen

Der Container läuft als Wegwerfcontainer. Der Parameter --rm löscht den Container automatisch nach Beendigung.

Ohne Parameter

sudo docker run --rm w3c-checklink

wird die Hilfe von /usr/local/bin/checklink ausgegeben

W3C Link Checker version 5.0.0 (c) 1999-2019 W3C

Usage: checklink <options> <uris>
Options:
 -s, --summary              Result summary only.
 -b, --broken               Show only the broken links, not the redirects.

 .....

Kommandozeilenparameter werden an /usr/local/bin/checklink weitergereicht. So gibt

sudo docker run --rm w3c-checklink --version

die Versionsnummer aus

W3C Link Checker version 5.0.0 (c) 1999-2019 W3C

Die Option --summary

sudo docker run --rm w3c-checklink --cookies tmp --summary https://perl-howto.github.io

zeigt nur eine Zusammenfassung der Ergebnisse an

Processing	https://perl-howto.github.io/

This may take some time if the document has many links to check.
.....
List of broken links and other issues:
.....

Durch Überschreiben des Entrypoints kann auch die die Systemversion von checklink verwendet werden. So gibt

sudo docker run --rm --entrypoint='/usr/bin/checklink' w3c-checklink --version

folgende Versionsnummer aus

W3C Link Checker version 4.81 (c) 1999-2011 W3C

 

PID 1 und Signale im Container oder warum lässt sich das Programm nicht mit CRTL-C abbrechen

Wie bereits in Perl on Docker - Offizielle Perl Docker Images als Grundlage eigener Images dargelegt, laufen Prozesse im Docker Container mit PID 1. Das bedeutet, das Signale im Dockercontainer nicht an die laufenden Programme weitergereicht werden. Ein Abruch mit SIGTERM/CRTL-C ist daher nicht möglich.

Bei aktuellen Dockerversionen (>1.13) ist es möglich tini - A tiny but valid init for containers als Init-Prozess zu verwenden, so daß Signale wie gewohnt durchgereicht werden. Dazu dient der Parameter --init.

sudo docker run --init --rm w3c-checklink --summary https://perl-howto.github.io

Jetzt kann das laufende Programm wieder mit STRG+C abgebrochen werden, so wie man es halt von Kommandozeilenprogrammen gewohnt ist.

 

Convenience Shell Wrapper Script

Damit man sich den langen – und daher fehleranfälligen – Aufruf nicht merken muss, bietet sich die Verwendung eines kleinen Wrapper-Scripts für die Shell an.

#!/bin/bash
# A wrapper script to run checklink (1p) from within a Docker image
sudo docker run --init --rm w3c-checklink "$@"

 

Siehe auch

 

Source-Code der Beispiele im Github Repo perl-howto-code.

 

Bildnachweis

Resized Photo by Vera Davidova on Unsplash

 

Weitere Posts