Skip to content

Instantly share code, notes, and snippets.

@denkspuren
Last active November 24, 2021 20:42
Show Gist options
  • Save denkspuren/ed2415ac6d83b273b1610b6db88115bf to your computer and use it in GitHub Desktop.
Save denkspuren/ed2415ac6d83b273b1610b6db88115bf to your computer and use it in GitHub Desktop.
Bereitstellung einer aktuellen JShell via Docker

Bereitstellung einer aktuellen JShell via Docker

Dieser Text dokumentiert die Bereitstellung einer aktuellen JShell mittels Docker und kombiniert das mit einigen grundsätzlichen Infos zu Docker. Der konkrete Anwendungsfall ist, die aktuelle JShell in der CloudShell von Google verwenden zu können. Wenn man bereit ist, sich auf Google als Dienstleister einzulassen, steht einem über die CloudShell kostenfrei ein Linux-Rechner zur Verfügung (→ Kurzes Video zur Einrichtung), wo Docker, etliche Cloud-Werkzeuge und Theia als Entwicklungsoberfläche vorinstalliert sind.

Allgemeines zu Docker

Docker kapselt Prozesse in sogenannten Containern, die als gewöhnliche Prozesse im Kernel des Gast-Systems laufen. Ein Container ist keine virtuelle Maschine und verschwendet deswegen auch keine Ressourcen. (Mahn, 2021, S. 147)

Container sehen weder andere Prozesse noch ein Dateisystem. Sie werden mit einem virtuellen Dateisystem ausgestattet (und zwar in Form einer tar-Datei), das als Image bezeichnet wird. Zudem können Zugriffe auf virtuelle Hardware-Komponenten (z.B. Netzkarte) eingerichtet werden. Solche, vom Image abweichenden Konfigurationen, können mit Hilfe eines Dockerfiles vorgenommen werden. Ein Docker Daemon, auch Docker-Host, verwaltet die Container zur Laufzeit. (S. 147 f.).

Da ein Container nur genau einen Prozess ausführt, sind mehrere Container mittels Docker Compose (docker compose bzw. docker-compose) zusammenstellbar. Mit einer YAML-Datei, standardmäßig docker-compose.yaml, konfiguriert man die Container und ihre Einstellungen. Üblich ist es, die YAML-Dateien für die verschiedensten Zusammenstellungen in separaten Verzeichnissen einzupflegen. (S. 152)

Der Docker Hub bietet vorbereitete Images an. Vorsicht ist bei der Auswahl der Images geboten, da jeder dort Images bereitstellen kann. Offizielle Images sind gekennzeichnet, wie z.B. das OpenJDK-Image. (S. 148 f.)

Image beziehen

Mit docker pull zieht man sich ein Image, hier das offizielle OpenJDK-Image. Hinter dem Namen openjdk folgt optional ein Doppelpunkt mit einem Tag, das in dem Fall die Version kennzeichnet.

docker pull openjdk:17

Container starten

Der Befehl docker run startet einen Container mit einem Image (→ Befehlsübersicht):

docker run --rm -it -v $(pwd):$HOME openjdk:17-jdk /bin/jshell -R-ea

Die Optionen bedeuten Folgendes:

  • -it ist notwendig für interaktive Prozesse wie eine Shell; die Kurzform steht für -i -t:
    • -i hält STDIN für Eingaben offen
    • -t stellt ein Terminal bereit
  • -v bindet ein VOLUME, einen Datenträger ein; hier ist es das Heimverzeichnis $(pwd):$HOME. Auf diese Weise teilen sich das Gastsystem und der Container Verzeichnisse und Dateien zum gemeinschaftlichen Zugriff
  • --rm entfernt (remove) den Container, wenn der Prozess endet

Mit -w bzw. --workdir (auch als WORKDIR in einem Dockerfile) kann man statt des Wurzelverzeichnisses ein Arbeitsverzeichnis setzen.

Mit -u= bzw. --user= (USER) können der Username, die UserId und die Usergruppe gesetzt werden.

Statt sogleich die JShell zu starten, ist es klüger, eine "normale" Shell aufzurufen, von der aus die JShell aufgerufen und beeendet werden kann. Beendet man die bash-Shell mit einem exit, sorgt das --rm dafür, dass in Folge auch der Container mit diesem Ausstieg beendet wird.

docker run --rm -it -v $(pwd):$HOME openjdk:17-jdk /bin/bash

Man kann diesen Befehl auch sehr gut als Bash-Script in eine Datei z.B. namens jshell.sh packen:

#!/bin/bash
docker run --rm -it -v $(pwd):$HOME openjdk:17-jdk /bin/bash

Übrigens lädt der Befehl das Image selbsttätig aus dem Internet nach, wenn es lokal nicht (mehr) vorhanden sein sollte.

Container auflisten

Die Container, die ja Prozesse sind, werden mit docker ps aufgelistet (→ Befehlsübersicht)

docker ps -a
  • -a bzw. --all zeigt alle Container an; in der Grundeinstellung werden nur die aktiven angezeigt

Container stoppen/beenden

Einen aktiven Container kann man mit dem Befehl docker stop (→ Befehlsübersicht) anhalten und mit docker rm (→ Befehlsübersicht) entfernen. Man kann nur nicht aktive Container entfernen. Als Argument gibt man den Container-Namen oder die Container-ID an. Beispiele:

docker rm competent_haslett
docker stop beautiful_hellman

Docker Daemon stoppen und starten

In Googles CloudShell läuft der Docker Daemon (Docker Host) standardmäßig. Er lässt sich stoppen (dann kann z.B. docker run nicht mehr ausgeführt werden) und wieder starten.

sudo service docker stop
sudo service docker start

Die Übersicht über den Status der verschiedensten Services weist laufende Dienste mit einem [ + ] aus, angehaltene mit einem [ - ] und Dienste, die keinen Status-Befehl unterstützen, mit einem [ ? ].

service --status-all

Quellen

Mahn, Jan (2021). Zu neuen Ufern. Nach dem Hype: Docker verstehen und loslegen, c't, Nr. 24, Hannover: Heise Medien, S. 146-152

Bei meinen ersten Docker-Gehversuchen haben mich die Studierenden Lars Wächter, René Gentzen und Ahmet Cetin mit ihren Hilfestellungen unterstützt. Vielen Dank!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment