229 lines
8.2 KiB
Markdown
229 lines
8.2 KiB
Markdown
# 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*:
|
||
```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:
|
||
```dockerfile
|
||
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:
|
||
```dockerfile
|
||
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:
|
||
```dockerfile
|
||
# 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:
|
||
|
||
```dockerfile
|
||
# 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):<br>
|
||
[Command Line Arguments and Settings](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/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.<br>
|
||
Relative Pfade:<br>
|
||
```./verzeichnis/auf/...```<br>
|
||
Absolute Pfade:<br>
|
||
```/verzeichnis/auf/...```<br>
|
||
|
||
⚠️ Die Ordner müssen auf dem Host System existieren. ⚠️ <br>
|
||
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:* <br>
|
||
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
|
||
``` |