# Tutorial 6: Container, Docker, Podman ASE WS 2023/24 In diesem Tutorial werden wir: * die Grundlagen von Containern wiederholen * die beiden wichtigsten Container-Plattformen, Docker und Podman, anschauen * mit verschiedenen Quellen für Images arbeiten * Images mit Dockerfiles selbst bauen * mit docker-compose mehrere zusammenhängende Container starten und überwachen * die Integration von Docker/Podman in CI/CD-Workflows mit Gitlab/GitHub anschauen **Achtung:** Dieses Dokument unterstützt lediglich die Übung und ist keine vollständige Anleitung ## Setup Wir arbeiten dieses Mal mit einer lokalen Docker/Podman-Installation Wichtig: auf segfault.net kann man Docker nur als normaler User (`sudo - user`) mit `udocker` starten. Das funktioniert aber dann auch nicht. Deshalb arbeiten wir über das VPN auf unserem Server rinfmi2.ur.de. Benutzernamen gibt's im Kurs. ## Docker und Podman [Docker](https://docker.io/) und [Podman](https://podman.io/) sind beides Tools zur Erstellung, Ausführung und Verwaltung von Containern. Sie ermöglichen es, Anwendungen und deren Abhängigkeiten in isolierten Umgebungen auszuführen, ohne dass sie sich gegenseitig beeinflussen. ### Docker Docker ist das am weitesten verbreitete Container-Management-System. Es nutzt eine daemonbasierte Architektur, bei der der Docker-Daemon auf dem Host-System läuft und die Container verwaltet. Docker erfordert Root-Rechte, um den Daemon auszuführen. Die einfachste Art, Docker unter Windows und macOS zu installieren, ist [Docker Desktop](https://www.docker.com/products/docker-desktop/) Unter Linux: Installation über Paketmanager (apt install docker.io) ### Podman Podman ist ein neueres, von Redhat entwickeltes Tool, das eine ähnliche Funktionalität wie Docker bietet, aber ohne die Verwendung eines Daemons auskommt. Es ermöglicht es, Container als normale Benutzer auszuführen und erfordert keine Root-Rechte. Installation auf verschiedenen Betriebssystemen am einfachsten über [Podman Desktop](https://podman-desktop.io/) oder: * Windows: https://www.redhat.com/sysadmin/run-podman-windows * macOS via [Homebrew](https://brew.sh/): brew install podman. * Linux: apt install podman Podman speichert Images und Container-Konfiguration im Verzeichnis /var/lib/containers wenn es als Root gestartet wird. Für normale User landen die Images unter $HOME/. local/share/containers/storage/ (spezifiziert durch Open Container Initiative (OCI)). ## Aufgabe 1 - Container starten Tipp 1: in allen Beispielen kann man docker auch durch podman ersetzen Tipp 2: statt Debian kann man auch das sehr kleine `alpine` [Docker-Image](https://hub.docker.com/_/alpine) verwenden. * Installiere Docker und/oder Podman * zeige mit `docker --help` die Hilfe zu allen Befehlen an. * Starte einen neuen Docker-Container mit eigenem Namen: `docker run -it --name Max_Mueller_test debian:latest /bin/bash` * Installiere in diesem Container ein Paket (z.B. `python3`) und logge dich aus (Tipp: erst `apt update` im Container ausführen. * erzeuge einen neuen Docker-Container `start_test2` mit `docker create` * starte den Container mit `docker start` - dieser beendet sich gleich wieder, weil er nichts zu tun hat. * Schaue nach, ob der Container noch läuft mit `docker ps` * Erzeuge einen neuen Container und lasse ihn im Hintergrund laufen: `docker run -it -d --name test_bg debian:latest /bin/bash` * Starte eine Shell in diesem Container mit `docker exec test_bg -sh /bin/bash` - wenn Du dich ausloggst, läuft der Container weiter. * Stoppe den Container * Lösche alle Container ## Dockerfiles Ein Dockerfile erlaubt es, ein eigenes Image zu generieren und diesem Dateien und Befehle hinzuzufügen: # Use the official Debian image as the base image FROM debian:latest # Update the package list and install additional packages RUN apt update && apt install -y cowsay # Add any necessary files or scripts COPY app/entrypoint.sh /entrypoint.sh # Set the working directory WORKDIR / # Set the entrypoint that will be run when the container starts ENTRYPOINT ["/entrypoint.sh"] Das Script `app/entrypoint.sh` enthält z.B. folgendes: #!/bin/bash while [[ 1 ]]; do /usr/games/cowsay "HELLO!" sleep 2 done Wichtig: das Script muss ausführbar sein (`chmod +x entrypoint.sh`) Mittels `docker build -t my_image .` erzeugt man aus der Datei `Dockerfile` ein Image Tipp: Unser Image gibt auf stdout jetzt kontinuierlich die "HELLO"-sagende Kuh aus. Um die Ausgabe eines laufenden Containers zu sehen: `docker logs -f ` [Dockerfile-Referenz](https://docs.docker.com/engine/reference/builder/) ## Aufgabe 2 Erstellen eine Dockerfile, das einen simplen Webserver startet: * in einem Verzeichnis /srv/www sollen einige hübsche Bilder liegen * eine Python-Installation ist vorhanden * ein Start-Script startet einen Webserver, der die Dateien aus dem Verzeichnis bereitstellt (`python -m http.server`) **Tipp:** damit man vom Host aus auf den Webserver im Container zugreifen kann, muss man die Container-Ports auf Host-Ports mappen ([`-p 8123:8000`](https://docs.docker.com/config/containers/container-networking/)) Tipp: [ADD vs COPY](https://docs.docker.com/develop/develop-images/instructions/#add-or-copy) ## docker-compose docker-compose verwendet die Spezifikation in einer YAML-Datei um mehrere Container gemeinsam zu konfigurieren und zu administrieren. Achtung: in aktuelleren Docker-Versionen ist docker-compose schon als Subbefehl integriert. Bei älteren Versionen muss man `docker-compose` anstelle von `docker compose` verwenden * ggf. separat zu installieren: `apt install docker-compose` * `docker compose up -d` (starte alle Services und 'detache' vom Output) * `docker compose down` * `docker compose logs -f` (zeige die Log-Ausgaben der Container an) * `docker compose scale` erlaubt es, weitere Container für einen Dienst bereitzustellen Beispiel-Konfiguration: [WikiBase Docker images](https://github.com/wmde/wikibase-release-pipeline/tree/wmde.14/example) ## Aufgabe 3 Erstelle eine Datei `docker-compose.yml`, die den Server aus Aufgabe 2 baut, startet und auf Port 1234 des Hosts antworten lässt. ## Docker-Integration in Gitlab und GitHub * https://docs.docker.com/build/ci/ * https://www.digitalocean.com/community/tutorials/how-to-set-up-a-continuous-deployment-pipeline-with-gitlab-ci-cd-on-ubuntu-18-04