= Docker
Thomas W. Stütz, credits to Christian Aberger
2.0.0, 2023-04-08: How to use docker in project work @ HTL Leonding college
ifndef::imagesdir[:imagesdir: images]
//:toc-placement!:  // prevents the generation of the doc at this position, so it can be printed afterwards
:sourcedir: ../src/main/java
:icons: font
:sectnums:    // Nummerierung der Überschriften / section numbering
:toc: left
:toclevels: 5
:experimental: true
:linkattrs:   // so window="_blank" will be executed

//Need this blank line after ifdef, don't know why...
ifdef::backend-html5[]

// https://fontawesome.com/v4.7.0/icons/
icon:file-text-o[link=https://raw.githubusercontent.com/htl-leonding-college/docker-lecture-notes/main/asciidocs/{docname}.adoc] ‏ ‏ ‎
icon:github-square[link=https://github.com/htl-leonding-college/docker-lecture-notes] ‏ ‏ ‎
icon:home[link=https://htl-leonding-college.github.io/docker-lecture-notes/docker.html]
endif::backend-html5[]

// print the toc here (not at the default position)
//toc::[]



[[bookmark-document-start]]
== Was ist Docker?

* Eine Technologie, um eine Application und alle ihre Abhängigkeiten in einen
einzelnen, leicht zu transportierenden Container zu packen.

* Wird eine Applikation in einen Docker-Container gepackt, so ist sichergestellt,
dass die Laufzeitumgebung unverändert bleibt, auch wenn der container auf einem
anderen Hostsystem läuft.


== Wie funktioniert Docker?

[plantuml,dockerimage,png]
----
@startuml
file dockerfile [

  Dockerfile

]
artifact image [

  docker
  image

]
artifact container [

  docker
  container

]
dockerfile -right-> image : docker build
image -right-> container : docker run
@enduml
----


[plantuml,dockerbuild,png]
----
@startuml
cloud "Docker Registry" {
artifact "docker\nImage"
}

artifact image [

  docker
  image

]
artifact container [

  docker
  container

]
"docker\nImage" -right-> image : docker pull
image -right-> container : docker run
@enduml
----


== Leichtgewichtige Virtualisierung

.Virtualisierung
[plantuml,virt1,png]
----
@startuml

rectangle fatvirt [
myApp
---
Libraries
---
Guest OS
---
Hardware Emulation
---
VirtualBox / vmware ...
---
Host OS
---
Hardware
]
@enduml
----

.Leichtgewichtige Virtualisierung
[plantuml,virt2,png]
----
rectangle docker [
myApp
---
Libraries
---
Docker
---
Host OS
---
Hardware
]
@enduml
----

image:docker-lightweight-virt.png[]

* Bsp. für "schwergewichtige" Virtualisierung
** VirtualBox
** vmWare
** ...

* Bsp. für leichtgewichtige Virtualisierung
** Docker
** Podman
** ...

== Grundprinzip

* Dockerfile: Kochrezept zum Erstellen des Images
* Image: Immutable Image
* Container: Ein gestartetes Image (mutable)

== Ist Docker installiert?

 docker version

----
% docker version
Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea
 Built:             Wed Nov 13 07:22:34 2019
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.12
  Git commit:       633a0ea
  Built:            Wed Nov 13 07:29:19 2019
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
----

----
sudo usermod -a -G docker jenkins
----


== Docker Registries

* a remote repository for storing Docker images
* public or private
* self-hosted or third-party service
* ie Docker Hub, Quay.io

image:docker-architecture.png[]

== Bind Mounts and Volumes

* *Bind Mounts* ein File oder Verzeichnis des Containers wird in einem File oder Verzeichnis zugänglich gemacht
** docker run -v ${PWD}/directory-on-host:/directory-in-container
* *Named Volumes* existieren am Host. Sie werden durch die Docker CLI manipuliert.
** docker volume create my-volume
** docker run -v my-volume:/directory-in-container

* Volumes verfügen über mehr Features wie *Cloud Storage Backends*


== Erste Beispiele mit Docker

=== Image alpine ausführen

----
docker run alpine echo Hello 4xhix
----


=== Image alpine interaktiv

----
docker run -it alpine /bin/sh
----

* -it -> interaktives Terminal

oder

----
docker run -it ubuntu:21.04 /bin/bash
----

== Ubuntu mit einem Volume

----
docker run -it --name syp_ubuntu -v my-opt:/opt ubuntu:21.04 /bin/bash
----

.ansehen mit
----
docker volume ls
----



=== Ubuntu mit einem bind mount

----
docker run -it --name syp_ubuntu -v ${PWD}/my_opt:/opt ubuntu:21.04 /bin/bash
----

=== Ubuntu mit einem volume

----
docker volume create my_volume
docker run -it --name syp_ubuntu -v my_volume:/opt ubuntu:21.04 /bin/bash
----

* erstelle ein file im opt-folder: `echo 123 > my-file.txt`
* beende container
* lösche container
* erstelle und starte einen neuen Container -> das File befindet sich immer noch im Volume

image:docker-bindmount-vs-volume.png[]

=== Docker Whalesay

----
docker run --rm docker/whalesay cowsay hello 4bhif
----

=== nginx - Step 1

.Starting nginx
----
docker run --rm -p 8081:80 --name nginx nginx
----

image:docker-port-mapping.png[]

=== nginx - Step 2

.Terminal 1: Starting nginx
----
docker run --rm -p 8081:80 --name nginx nginx
----

.Terminal 2: Open a terminal in the docker container
----
docker exec -it nginx /bin/sh
----

=== nginx - Step 3

.Terminal 1: Start nginx with a volume in the current folder
----
docker run --rm -v ${PWD}/data:/usr/share/nginx/html -p 8081:80 --name nginx nginx
----

image:docker-starten-nginx.png[]

.Image + Container (w/ port + volume)
image:docker-image-container.png[]

=== PostgreSQL

----
docker run -it \
           --rm=true \
           --name postgres \
           -v ${PWD}/pgdata:/var/lib/postgresql/data \
           -e POSTGRES_USER=app \
           -e POSTGRES_PASSWORD=app \
           -e POSTGRES_DB=db \
           -p 5432:5432 postgres:10.5
----

=== Minecraft

.https://hub.docker.com/r/itzg/minecraft-server[Minecraft Server]
[source,shell script]
----
docker pull itzg/minecraft-server
docker run -d -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
----

* https://github.com/itzg/docker-minecraft-server/blob/master/README.md[Documentation on github]

== Unterschied zum Arbeiten ohne Docker

* Ohne Docker werden auf einer Maschine mehrere Softwareprodukte installiert
* Bei Verwendung von Docker wird für jedes
Softwareprodukt ein eigener Docker-Container erstellt


== Docker Networks

* Konfiguriert die Verbindung zwischen Container und zum Internet
* Container können ports freigeben und so im Internet verfügbar machen
* Man verwendet die *Docker CLI*
* Network Drivers
** *Bridge*: Virtuelles Netzwerk, um mehrere Container miteinander zu verbinden
** *Host*: Entfernt die Netzwerk-Isolation zwischen Host und Containern. Die Container benutzen
das Netzwerk des Hosts direkt
** *Overlay*: Verbindet Container die auf unterschiedlichen Docker-Hosts laufen
** *Macvlan*: Weist eine MAC-Adresse einem Container zu. Für low-level Netzwerkanforderungen
** *None*: Deaktiviert das Netzwerk zwischen den Containern


image:docker-network.png[]






















