HelperSheets/docker/Docker.md
2024-08-26 18:09:02 +02:00

8.2 KiB

Docker getting started

Im ersten Teil geht es darum, ein Docker image zu erstellen und im zweiten darum dieses auszuführen.

Image erstellen

Es gibt mehrere Methoden ein Docker Image zu erstellen. Man fängt aber immer damit an eine Dockerfile zu erstellen.

Auswahl des Basis-Images

Nun öffnen wir die Dockerfile und wählen ein Basis-Image aus. Das Basis-Image kann beliebig sein und darauf baut dann das Image auf. Beispiele für solch ein Basis-Image kann z.B. sein:

  • Ubuntu: ubuntu
    • Debian: debian
    • CentOS: centos
    • Alpine Linux: alpine
    • Fedora: fedora
    • OpenSUSE: opensuse
    • Oracle Linux: oraclelinux
    • Windows Server Core: mcr.microsoft.com/windows/servercore
    • Windows Nano Server: mcr.microsoft.com/windows/nanoserver
  • Webserver:
    • NGINX: nginx
    • Apache HTTP Server: httpd
    • Node.js: node
    • Python: python
    • Ruby: ruby
  • Datenbanken:
    • MySQL: mysql
    • PostgresSQL: postgres
    • MongoDB: mongo
    • Redis: redis
    • MariaDB: mariadb
  • Weitere Anwendungen:
    • Java: openjdk
    • PHP: php
    • Go: golang
    • .NET Core: mcr.microsoft.com/dotnet/core/sdk
    • WordPress: wordpress
    • Django: django

So nutzt man z.B. ein Image in der Dockerfile:

FROM ubuntu:latest

Hinzufügen von Anweisungen

nachdem in der ersten Zeile unser verwendetes Basis-Image steht werden wir uns nun den gängigsten Anweisungen widmen, welche wir nutzen, um das Image zu konfigurieren und Daten oder Anwendungen hinzuzufügen. Hier sind die gängigsten Anweisungen:

  • RUN: Führt Befehle aus, um Pakete zu installieren oder Anwendungen innerhalb des Images zu konfigurieren.
  • COPY: Kopiert Dateien oder Verzeichnisse vom Host in das Image.
  • ADD: Ähnlich wie COPY, kann aber auch URLs und TAR-Archive verarbeiten.
  • ENV: Setzt Umgebungsvariablen innerhalb des Images.
  • EXPOSE: Gibt an, auf welchem Port die Anwendung in dem Container lauscht.
  • CMD: Definiert den Befehl, der ausgeführt wird, wenn der Container gestartet wird.
  • ENTRYPOINT: Gibt den ausführbaren Befehl oder das Skript an, das beim Start des Containers ausgeführt wird.

Nun können wir z.B. git in unser Image installieren, nachdem der Container gestartet worden ist:

FROM ubuntu:latest
# Git installieren
RUN apt-get update && apt-get install -y git

Danach können wir die bash starten damit sich die Konsole öffnet:

FROM ubuntu:latest
# Git installieren
RUN apt-get update && apt-get install -y git
# Arbeitsverzeichnis
ENTRYPOINT [ "bash" ]

Note: Der ENTRYPOINT ist das erste auszuführende Skript im Container!

Nun können das Image etwas weiter ausbauen und z.B. Stable Diffusion von AUTOMATIC1111 herunterladen und ausführen:

# Verwende das offizielle Ubuntu-Basisimage mit dem Tag "latest"
FROM ubuntu:latest

# Aktualisiere das Paket-Repository und installiere Git
RUN apt-get update && apt-get install -y git

# Lege das Arbeitsverzeichnis im Container fest
WORKDIR /app

# Klone das Git-Repository in das Arbeitsverzeichnis im Container
RUN git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git /app

# Navigiere in den Ordner des Git-Repositories
WORKDIR /app/stable-diffusion-webui

# Führe das Shell-Skript "webui.sh" aus
CMD ["/app/webui.sh"]

Dies war natürlich ein naiver Ansatz, denn so müssen wir auch beachten, was wir später in unserer ausführbaren Datei brauchen.

⚠️Wenn wir das Programm mithilfe von einer GPU ausführen lassen wollen brauchen wir nvidia-docker. Das muss aber auf dem Host-System installiert werden. ⚠️

So sieht nun schlussendlich unsere fertige Dockerfile aus:

# Verwende das offizielle Ubuntu-Basisimage mit dem Tag "latest"
FROM ubuntu:latest

# Aktualisiere das Paket-Repository und installiere Git und Python 3
RUN apt-get update && apt-get install -y git python3 python3.10-venv

# Installiere die erforderlichen NVIDIA-Bibliotheken und -Treiber innerhalb des Containers
RUN apt-get install -y nvidia-cuda-toolkit

# Lege das Arbeitsverzeichnis im Container fest
WORKDIR /app

# Klone das Git-Repository in das Arbeitsverzeichnis im Container
RUN git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git /app/stable-diffusion-webui

# Navigiere in den Ordner des Git-Repositories
WORKDIR /app/stable-diffusion-webui

# Erstelle einen neuen Benutzer "sduser" im Container
RUN useradd -ms /bin/bash sduser

# Ändere den Besitzer des Arbeitsverzeichnisses auf den Benutzer "sduser"
RUN chown -R sduser:sduser /app

# Wechsle zum Benutzer "sduser"
USER sduser

# Lege einen *temporären* Argument an, damit NUR die CPU benutzt wird
ENV COMMANDLINE_ARGS="--use-cpu all --skip-torch-cuda-test --precision full --no-half --listen"

# Führe das Shell-Skript "webui.sh" aus
CMD ["bash", "/app/stable-diffusion-webui/webui.sh"]

Beachte aber das hier die GPU NICHT mit eingebunden worden ist, da die Flag: --skip-torch-cuda-test gesetzt worden ist. Die weiteren Flags sind da um die Probleme mit einer nicht vorhanden GPU zu beheben. Diese sollten auch entfernt werden, sobald man eine GPU benutzen will.

Wenn die GPU funktioniert startet man den Container später mit dem flag --gpus all.

Hier sind alle Flags, welche man bei Stable Diffusion WebUI verwenden kann (von AUTOMATIC1111):
Command Line Arguments and Settings

Container aus dem Image erstellen

Navigiere in den Ordner wo die Dockerfile liegt und baue das Image. Mit unserem vorherigen Beispiel sähe der Befehl nun z.B. so aus:

docker build -t stablediffown .

⚠️ Beachte jedoch das Docker dafür gestartet sein muss. ⚠️

Mit dem -t-Flag kann man einem Image einen benutzerdefinierten Namen geben. Anschließend kann man überprüfen, ob das Image erstellt worden ist:

docker images

Hier sollte normalerweise das aktuelle Image angezeigt werden.

Erstmaliges starten des Containers

Starte nun den Container und gebe diesen Container einen Namen, wenn dies gewünscht ist. Gleichzeitig konfiguriere den Container. Also Portweiterleitung, etc. .

Hier sind mehrere Konfigurationsmöglichkeiten:

  • mit GPU-Support (--gpus)
  • mit Namensgebung (--name)
  • mit Portweiterleitung (-p)
  • mit einem Volumen zur permanenten Datenspeicherung (-v)
  • mit Aufrechterhalten der Konsole (-it)
docker run --gpus all -p PORT_AUF_HOST:PORT_IM_CONTAINER -v /pfad/auf/host:/pfad/im/container -it my_image_name

Man kann sowohl relative Pfade als auch absolute Pfade verwenden.
Relative Pfade:
./verzeichnis/auf/...
Absolute Pfade:
/verzeichnis/auf/...

⚠️ Die Ordner müssen auf dem Host System existieren. ⚠️
Die relativen Pfade gelten immer von dort aus wo der Befehl docker run ausgeführt wird. Falls manche Ordner im Container noch nicht existieren sollten werden diese automatisch angelegt.

Ohne GPU:

docker run --name MeinEigenerContainer -p 7860:7860 -it stablediffown

Mit GPU:

docker run --name MeinEigenerContainer --gpus all -p 7860:7860 -it stablediffown

Finaler Command beim erstmaligen Starten des Containers ohne GPU:
Hier wird nun der Name des Containers festgelegt, eine Portweiterleitung durchgeführt und die jeweiligen Volumen mounted.

docker run --name SDTest -p 8080:7860 -v C:\Users\Name\Desktop\Docki\ds\extensions:/app/stable-diffusion-webui/extensions -v C:\Users\Name\Desktop\Docki\ds\models:/app/stable-diffusion-webui/models -v C:\Users\Name\Desktop\Docki\ds\outputs:/app/stable-diffusion-webui/outputs -it stablediffown

Stoppen eines Containers

Es gibt 2 Methoden, entweder über die ID, oder über den Container-Namen:

Zeige alle laufenden Container an:

docker ps

Mit ID stoppen:

docker stop CONTAINER_ID

Mit Container-Namen stoppen:

docker stop CONTAINER_NAME

Erneutes starten eines Containers

Hier brauchen die Konfigurationen nicht erneut angegeben werden. Man kann diese aber natürlich, wenn man diese ändern will dennoch angeben.

docker start SDTest

Komplettes entfernen eines Containers

docker rm --name=CONTAINER_NAME