Perl on Docker - Perl commandline Programm als Docker Container erstellen und nutzen
Veröffentlicht von Thomas Fahle am (Permalink)
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/ # Remember, in order to use CMD values as ENTRYPOINT arguments, ENTRYPOINT must be defined in exec form. 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
- W3C Link Checker - Check links and anchors in Web pages or full Web sites
- Link Checker Documentation
- Metacpan: W3C Link Checker
- Metacpan: checklink - check the validity of links in an HTML or XHTML document
- Paket: w3c-linkchecker
- Docker
- Docker Docs
- Docker run reference
- Specify an init process
- Tini - A tiny but valid init for containers
- Distributing Command Line Tools with Docker
- Official Docker Perl
- Github docker-perl
- Perl on Docker - Dancer2 Hello World Beispiel
- Perl on Docker - Offizielle Perl Docker Images als Grundlage eigener Images
- Perl on Docker - Multi-stage Builds zur Verkürzung von Build-Laufzeiten
- Perl on Docker - Dancer2 und Redis docker-compose Beispiel
Source-Code der Beispiele im Github Repo perl-howto-code.
Bildnachweis
Resized Photo by Vera Davidova on Unsplash