Docker 2024 04/Image: Unterschied zwischen den Versionen
Drlue (Diskussion | Beiträge) |
Drlue (Diskussion | Beiträge) |
||
| (19 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 2: | Zeile 2: | ||
Um ein Image zu erstellen wird ein '''Dockerfile''' benötigt. Dieses hat standardmäßig den Dateinamen '''Dockerfile'''. | Um ein Image zu erstellen wird ein '''Dockerfile''' benötigt. Dieses hat standardmäßig den Dateinamen '''Dockerfile'''. | ||
Bezüglich der Namenskonvention finden sich [https://docs.docker.com/reference/cli/docker/image/tag/ hier]<ref>https://docs.docker.com/reference/cli/docker/image/tag/</ref> weitere Informationen. | |||
Dockerfiles können auch Mehrstufig (multi-stage) aufgebaut sein. Z.b.: Eine Build Stage und eine Stage für das eigentliche Image. Siehe [https://docs.docker.com/build/building/multi-stage/ hier]<ref>https://docs.docker.com/build/building/multi-stage/</ref> | |||
=== Aufbau des Dockerfiles === | === Aufbau des Dockerfiles === | ||
| Zeile 12: | Zeile 16: | ||
Diese unterscheiden sich maßgeblich durch ihren Funktionsumfang (welche Tools bereits installiert sind). Dadurch verändert sich natürlich die Größe des selbst erstellten Images. Am besten wird das Baseimage gewählt mit dem man am meisten Erfahrung hat. | Diese unterscheiden sich maßgeblich durch ihren Funktionsumfang (welche Tools bereits installiert sind). Dadurch verändert sich natürlich die Größe des selbst erstellten Images. Am besten wird das Baseimage gewählt mit dem man am meisten Erfahrung hat. | ||
Es sei angemerkt, dass das Baseimage auch selbst erstellt werden kann (warum auch immer). | Es sei angemerkt, dass das Baseimage auch selbst erstellt werden kann (warum auch immer). Siehe [https://docs.docker.com/build/building/base-images/ hier]<ref>https://docs.docker.com/build/building/base-images/</ref> | ||
'''Dockerfile''' | '''Dockerfile''' | ||
| Zeile 50: | Zeile 52: | ||
{{BML|code= | {{BML|code= | ||
docker build . -t | docker build . -t image_basics_1:1.0 | ||
# CMD des Dockerfiles verwenden | # CMD des Dockerfiles verwenden | ||
docker run --rm | docker run --rm image_basics_1:1.0 | ||
# CMD des Dockerfiles überschreiben | # CMD des Dockerfiles überschreiben | ||
docker run --rm | docker run --rm image_basics_1:1.0 echo hallo | ||
}} | }} | ||
| Zeile 67: | Zeile 69: | ||
{{BML|code= | {{BML|code= | ||
docker build . -t | docker build . -t image_basics_2:1.0 | ||
# ENTRYPOINT des Dockerfiles verwenden | # ENTRYPOINT des Dockerfiles verwenden | ||
docker run --rm | docker run --rm image_basics_2:1.0 | ||
# ENTRYPOINT des Dockerfiles ergänzen | # ENTRYPOINT des Dockerfiles ergänzen | ||
docker run --rm | docker run --rm image_basics_2:1.0 -a | ||
}} | }} | ||
| Zeile 79: | Zeile 81: | ||
* '''WORKDIR''' - Das Arbeitsverzeichnis wechseln | * '''WORKDIR''' - Das Arbeitsverzeichnis wechseln | ||
* '''USER''' - Benutzer wechseln (dieser muss über useradd erstellt werden) | * '''USER''' - Benutzer wechseln (dieser muss über useradd erstellt werden) | ||
* '''EXPOSE''' - Exponierten Port festlegen, siehe {{docker run -p [Portnummer]}}, der Sinn erschließt sich mir nicht | * '''EXPOSE''' - Exponierten Port festlegen, siehe {{BSL|docker run -p [Portnummer]}}, der Sinn erschließt sich mir nicht | ||
* '''ARG''' - Umgebungsvariable nur gültig während des Build Prozesses<ref>https://vsupalov.com/docker-arg-env-variable-guide/</ref> | * '''ARG''' - Umgebungsvariable nur gültig während des Build Prozesses<ref name="docker_arg_and_env">https://vsupalov.com/docker-arg-env-variable-guide/</ref> | ||
* '''ENV''' - Umgebungsvariable gültig während des Build Prozesses und zur Laufzeit<ref | * '''ENV''' - Umgebungsvariable gültig während des Build Prozesses und zur Laufzeit<ref name="docker_arg_and_env"/> | ||
=== Beispiel 1) Bestehende Anwendung === | === Beispiel 1) Bestehende Anwendung === | ||
Im folgenden soll aus einer | Im folgenden soll aus einer bestehenden Anwendung ein Image erstellt werden. Es handelt sich um eine '''node.js''' '''Express''' Client/Server Webanwendung. | ||
* Der '''Port''' soll während der Buildprozesses und beim Starten konfigurierbar sein | * Der '''Port''' soll während der Buildprozesses und beim Starten konfigurierbar sein | ||
** ''Standard: 10000'' | ** ''Standard: 10000'' | ||
| Zeile 90: | Zeile 92: | ||
** ''Standard: console'' | ** ''Standard: console'' | ||
Das Repository der Anwendung findet sich [https://gitlab.drlue.at/dockerschulung/demoapp.git hier] und kann geklont werden. | Der Datenbankordner in der gebauten Anwendung kann gemounted werden und findet sich unter {{BSL|dist/database/}} | ||
Das Repository der Anwendung findet sich [https://gitlab.drlue.at/dockerschulung/demoapp.git hier]<ref>https://gitlab.drlue.at/dockerschulung/demoapp.git</ref> und kann geklont werden. | |||
==== Dockerfile ==== | ==== Dockerfile ==== | ||
| Zeile 116: | Zeile 120: | ||
RUN npm install | RUN npm install | ||
RUN npm run build | RUN npm run build | ||
#Arguments with default values (can be configured when building: --build-arg PORT=[0-9]* --build-arg JET_LOGGER_MODE=[off{{!}}console{{!}}file{{!}}custom] | #Arguments with default values (can be configured when building: --build-arg PORT=[0-9]* --build-arg JET_LOGGER_MODE=[off{{!}}console{{!}}file{{!}}custom] | ||
| Zeile 129: | Zeile 131: | ||
}} | }} | ||
==== | ==== Image erstellen ==== | ||
Ohne Build Argumente | Ohne Build Argumente | ||
{{BML|code=docker build . -t | {{BML|code=docker build . -t image_example1:1.0}} | ||
Mit Build Argumenten | Mit Build Argumenten | ||
{{BML|code=docker build --build-arg PORT=80 --build-arg | {{BML|code=docker build --build-arg PORT=80 --build-arg JET_LOGGER_MODE=off. -t image_example1:1.0}} | ||
==== | ==== Image verwenden ==== | ||
Ohne Umgebungsvariablen | Ohne Umgebungsvariablen | ||
{{BML|code= | {{BML|code= | ||
docker run --rm --name example_app -d -p 9000:10000 | #Starten | ||
docker run --rm --name example_app -d -p 9000:10000 image_example1:1.0 | |||
#Logs folgen | |||
docker logs -f example_app | |||
#Stoppen | |||
docker container stop example_app | |||
}} | }} | ||
Mit Umgebungsvariablen | Mit Umgebungsvariablen | ||
{{BML|code= | {{BML|code= | ||
docker run --rm --name example_app -e PORT=15000 -e JET_LOGGER_MODE=off -d -p 80:15000 | #Starten | ||
docker run --rm --name example_app -e PORT=15000 -e JET_LOGGER_MODE=off -d -p 80:15000 image_example1:1.0 | |||
#Logs folgen | |||
docker logs -f example_app | |||
#Stoppen | |||
docker container stop example_app | |||
}} | |||
Persistieren der Datenbank | |||
{{BML|code= | |||
#Volume erstellen | |||
docker volume create example_app_data | |||
#Starten | |||
docker run --rm --name example_app -v example_app_data:/app/dist/database/ -d -p 80:10000 image_example1:1.0 | |||
#Daten modifizieren | |||
... | |||
#Container stoppen | |||
docker container stop example_app | |||
#Container starten | |||
docker container start example_app | |||
#Daten sind da | |||
... | |||
}} | }} | ||
Aktuelle Version vom 19. April 2024, 17:38 Uhr
Docker Images bilden die Grundlage um Container zu erstellen. Diese können selbst erstellt werden oder über eine Registry geholt werden.
Um ein Image zu erstellen wird ein Dockerfile benötigt. Dieses hat standardmäßig den Dateinamen Dockerfile.
Bezüglich der Namenskonvention finden sich hier[1] weitere Informationen.
Dockerfiles können auch Mehrstufig (multi-stage) aufgebaut sein. Z.b.: Eine Build Stage und eine Stage für das eigentliche Image. Siehe hier[2]
Aufbau des Dockerfiles
Baseimage
Jedes Dockerfile wird von einem Baseimage abgeleitet. Dies kann ein eigens erstelltes Image sein, wie bereits in den vorhergehenden Kapiteln gezeigt wurde. Oder es kann eines der populären Baseimages verwendet werden:
- Ubuntu
- Alpine
- Busybox
Diese unterscheiden sich maßgeblich durch ihren Funktionsumfang (welche Tools bereits installiert sind). Dadurch verändert sich natürlich die Größe des selbst erstellten Images. Am besten wird das Baseimage gewählt mit dem man am meisten Erfahrung hat.
Es sei angemerkt, dass das Baseimage auch selbst erstellt werden kann (warum auch immer). Siehe hier[3]
Dockerfile
FROM ubuntu:22.04
Dies stellt bereits ein gültiges Image dar. Die Sinnhaftigkeit sei jedoch in Frage gestellt.
Command und Entrypoint
Im Regelfall soll ein Container auch eine Applikation ausführen, ansonsten wird dieser direkt nach dem Starten gestoppt.
Hierfür gibt es zwei verschiedene Möglichkeiten:
- CMD
- Kann durch
docker run [container] [new command]ersetzt werden - Kann in abgeleitetem Image durch
ENTRYPOINToderCMDersetzt werden
- Kann durch
- ENTRYPOINT
- Es können über
docker run [container] [new command]Parameter für den Entrypoint hinzugefügt werden - Kann in abgeleitetem Image ersetzt werden, dies scheint aber keine best practice zu sein
- Es können über
Mittels Entrypoint kann sichergestellt werden, dass eine gewisse Applikation gestartet wird, in jedem Fall.
Der Entrypoint kann in einem abgeleiteten Image ebenfalls ersetzt werden. Die Vorgehensweise ist aber etwas sonderbar:
ENTRYPOINT ["/usr/bin/env"]
CMD ["..."]
Dockerfile - CMD
FROM ubuntu:22.04
CMD ["ls", "-l"]
docker build . -t image_basics_1:1.0
# CMD des Dockerfiles verwenden
docker run --rm image_basics_1:1.0
# CMD des Dockerfiles überschreiben
docker run --rm image_basics_1:1.0 echo hallo
Dockerfile - ENTRYPOINT
FROM ubuntu:22.04
ENTRYPOINT ["ls", "-l"]
docker build . -t image_basics_2:1.0
# ENTRYPOINT des Dockerfiles verwenden
docker run --rm image_basics_2:1.0
# ENTRYPOINT des Dockerfiles ergänzen
docker run --rm image_basics_2:1.0 -a
Weitere Befehle
- RUN - Befehl ausführen
- COPY - Dateien/Ordner vom Host kopieren
- WORKDIR - Das Arbeitsverzeichnis wechseln
- USER - Benutzer wechseln (dieser muss über useradd erstellt werden)
- EXPOSE - Exponierten Port festlegen, siehe
docker run -p [Portnummer], der Sinn erschließt sich mir nicht - ARG - Umgebungsvariable nur gültig während des Build Prozesses[5]
- ENV - Umgebungsvariable gültig während des Build Prozesses und zur Laufzeit[5]
Beispiel 1) Bestehende Anwendung
Im folgenden soll aus einer bestehenden Anwendung ein Image erstellt werden. Es handelt sich um eine node.js Express Client/Server Webanwendung.
- Der Port soll während der Buildprozesses und beim Starten konfigurierbar sein
- Standard: 10000
- Das Loglevel soll während der Buildprozesses und beim Starten konfigurierbar sein
- Standard: console
Der Datenbankordner in der gebauten Anwendung kann gemounted werden und findet sich unter dist/database/
Das Repository der Anwendung findet sich hier[6] und kann geklont werden.
Dockerfile
Inhalt in Datei Dockerfile, teilweise von hier
#Baseimage
FROM ubuntu:22.04
#Don't ask questions apt
ARG DEBIAN_FRONTEND=noninteractive
#Update apt
RUN apt-get update
#Install curl
RUN apt-get -y install curl
#Add new nodejs version to apt repository
RUN curl -sL https://deb.nodesource.com/setup_lts.x | bash -
#Update apt again
RUN apt-get update
#Install nodejs
RUN apt-get -y install nodejs
#Copy application to image
COPY demoapp /app
#Change directory
WORKDIR /app
#Build application
RUN npm install
RUN npm run build
#Arguments with default values (can be configured when building: --build-arg PORT=[0-9]* --build-arg JET_LOGGER_MODE=[off|console|file|custom]
ARG PORT=10000
ARG JET_LOGGER_MODE=console
#Environment (can be overwritten when starting the image: -e PORT=[0-9]* -e JET_LOGGER_MODE=[off|console|file|custom]
ENV PORT=${PORT}
ENV JET_LOGGER_MODE=${JET_LOGGER_MODE}
CMD ["npm", "start"]
Image erstellen
Ohne Build Argumente
docker build . -t image_example1:1.0
Mit Build Argumenten
docker build --build-arg PORT=80 --build-arg JET_LOGGER_MODE=off. -t image_example1:1.0
Image verwenden
Ohne Umgebungsvariablen
#Starten
docker run --rm --name example_app -d -p 9000:10000 image_example1:1.0
#Logs folgen
docker logs -f example_app
#Stoppen
docker container stop example_app
Mit Umgebungsvariablen
#Starten
docker run --rm --name example_app -e PORT=15000 -e JET_LOGGER_MODE=off -d -p 80:15000 image_example1:1.0
#Logs folgen
docker logs -f example_app
#Stoppen
docker container stop example_app
Persistieren der Datenbank
#Volume erstellen
docker volume create example_app_data
#Starten
docker run --rm --name example_app -v example_app_data:/app/dist/database/ -d -p 80:10000 image_example1:1.0
#Daten modifizieren
...
#Container stoppen
docker container stop example_app
#Container starten
docker container start example_app
#Daten sind da
...
- ↑ https://docs.docker.com/reference/cli/docker/image/tag/
- ↑ https://docs.docker.com/build/building/multi-stage/
- ↑ https://docs.docker.com/build/building/base-images/
- ↑ https://stackoverflow.com/questions/41207522/docker-override-or-remove-entrypoint-from-a-base-image
- ↑ 5,0 5,1 https://vsupalov.com/docker-arg-env-variable-guide/
- ↑ https://gitlab.drlue.at/dockerschulung/demoapp.git