IT-Wissen/docker/README.md
2025-04-22 15:16:07 +02:00

559 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
gitea: none
include_toc: true
---
# Docker
Installation: See separate page [Docker Installation](docker-install.md)
## Summary
Docker simplifies the development and deployment of applications by providing a lightweight, portable, and consistent containerized environment. It bridges the gap between development and production, enabling developers to focus on building applications without worrying about environment-specific issues. The applications run consistently across different computing environments, whether on a developer's laptop, a test server, or in production.
## Advantages of Docker
- __Portability:__ Containers ensure applications behave the same regardless of the environment (development, testing, production).
- __Efficiency:__ Containers use shared OS resources, making them faster and less resource-intensive compared to VMs.
- __Scalability:__ Docker enables rapid scaling of applications by spinning up multiple container instances as needed.
- __Isolation:__ Each container runs independently, preventing conflicts between applications.
## Key Concepts of Docker
### Containers:
Containers are lightweight virtualized environments that package an application along with its libraries, dependencies, and configuration files.
Unlike traditional virtual machines (VMs), containers share the host system's kernel, making them faster and more resource-efficient.
### Images:
Docker images are the building blocks for containers. An image is a static snapshot of an environment that contains all necessary dependencies for an application.
Images are created using a Dockerfile and can be stored and shared via a Docker registry like Docker Hub.
### Docker Engine:
The Docker Engine is the runtime responsible for building and running containers.
### Dockerfile:
A text file containing instructions to build a Docker image (e.g., which base image to use, dependencies to install, files to copy).
### Docker Compose:
A tool to define and run multi-container applications using a YAML file.
## How Docker Works
### Build Phase:
Developers write a Dockerfile to specify the base image (e.g., Ubuntu, Node.js, Python) and define how the application and its dependencies should be configured.
Using the command docker build, Docker creates a layered image.
### Run Phase:
Using the docker run command, Docker launches a container based on the built image. Containers start in a matter of seconds.
### Networking:
Docker creates isolated networks for containers to communicate with each other and the outside world securely.
### Storage:
Docker provides volumes for persistent storage, ensuring data remains even if a container is restarted or removed.
### Container Orchestration:
Tools like Docker Compose and Kubernetes are used to manage and scale multiple containers in production environments.
## Workflow example
1. Write a __Dockerfile__ to __package the application__.
2. Build the Docker __image__ using __docker build__.
3. Run the image as a __container__ using __docker run__.
4. Use __Docker Compose__ to manage __multiple containers__ for a complete application (e.g., web server + database).
# Docker Image
Docker images are the building blocks for containers. An image is a static snapshot of an environment that contains all necessary dependencies for an application.
__Images can either be built, or existing images can be pulled from a registry.__
## Docker Registry
By default, Docker __pulls__ images from __Docker Hub__, the default public registry for Docker images. \
For example `image: 'jc21/nginx-proxy-manager:latest'` Docker will search for the image `jc21/nginx-proxy-manager` on Docker Hub and pull the latest tag (or version).
If the image is hosted on a different container registry (e.g., Amazon Elastic Container Registry, Google Container Registry, or a private registry), you must provide the __full registry URL__ as a prefix, like e.g. `image: 'myregistry.example.com/myimage:latest'`. Docker will pull the image from `myregistry.example.com`.
Before attempting to download the image, Docker checks if the image already exists locally in the __cache__. If found, it uses the local copy.
If the registry requires __authentication__, you must log in using `docker login <registry_url>` or configure credentials in the Docker Compose file.
```
docker login
docker pull
etc.
```
## Own App: Dockerfile
`Dockerfile` ist eine einfache Textdatei, mit der man eigene Images bauen kann. Sie basieren immer auf einem bestehenden base Image (z.B. `nginx:latest` oder `node:16.13.0-alpine`). Mit `docker build` wird das image erstellt, bevor man es mit `docker run` starten kann.
Dockerfile documentation: https://docs.docker.com/reference/builder
## Build Docker image
Im Ordner wo das Dockerfile liegt, ausführen:
```
docker build .
```
Um dem Image einen Namen und einen Tag zu geben (1.0 ist im folgenden Beispiel der Tag)
```
docker build -t node-app:1.0 .
```
## Run docker image
Image, which was either pulled from a registry or was built on the system, can be run with:
```
docker run -d -p 3000:80 -e FOO='bar' -FOO2='bar2' --name myApp node-app:1.0
```
- `-d` Optional. For detached mode (run in background)
- `-p 3000:80` Optional. Traffic on port 3000, and port 80 inside the container.
- `-e` Optional. Environment Parameter, that will be passed on to the container
- `--name` Optional. Name for container.
- `--restart` Optional. Restart policy. `no`, `on-failure:5`, `always`
- `node-app:1.0` image/tag to be started.
## Show all docker images
```
docker images
docker image ls # alternativ
```
Example:
```
rogrut@zidbacons02:/$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker dind 0f7ea23310b3 3 weeks ago 397MB
docker <none> 7a9eec921ea3 2 months ago 378MB
cr.gitlab.uzh.ch/dba/digicert/export-digicert/main e9af5b08 95248f27c850 2 months ago 261MB
caddy latest 1b7d0a82297a 3 months ago 48.5MB
alpine <none> b0c9d60fc5e3 3 months ago 7.83MB
curlimages/curl latest 7551dbeefe0d 4 months ago 21.8MB
```
## Delete Docker image
```
docker rmi <REPOSITORY:TAG>
docker rmi ubuntu:2010
```
## Add Tag to Docker image
The following will clone the image with a new tag, but has the same IMAGE ID.
```
docker tag <REPOSITORY>:<TAG> <REPOSITORY>:<new tag, e.g. 1.0 instead of latest>
```
## Push Docker image to repository
the following will clone an image and add a tag that can be used to push to a repository. It will then push it to the repo.
```
docker tag myApp:latest myApp:latest repository-example.com/rogerrutishauser/myApp:latest
docker login
docker push
```
# Docker Container
Ein Container ist ein Image, welches gerade ausgeführt wird. Wenn ein Image mit `docker run nginx` ausgeführt wird, spricht man von einem Container. Es ist vergleichbar mit einem Prozess. Container wird auf Basis eines Ausgangs-Images gestartet.
## Share data
### 1. Möglichkeit: Verzeichnisse mappen (Host-Verzeichnis im Container mappen)
```
docker run -v <HOST DIR>:<DOCKER DIR>
```
Konkret:
```
$ docker run -it -v ~/Desktop/LokaleDaten:/home/daten --name Datentest ubuntu:20.04 /bin/bash
```
### 2. Möglichkeit: Daten-Container verwenden (zwischen Container und Container)
Datencontainer mit Volume `/data/db` erstellen
```
docker create -v /data/db --name datenbox busybox true
```
Neuen Container für Anwendung erstellen
```
$ docker run -it --volumes-from datenbox ubuntu:20.04 /bin/bash
$ cd /data/db
$ touch datei.txt
$ exit
```
Die Datei ist jetzt im Datencontainer unter `/data/db`. Der Datencontainer muss gar nicht gestartet werden um ihn zu verwenden.
## Container verlinken
### Ports verbinden
Beispiel Image martinblaha/testapp starten, localhost Port 4000, docker Port 1337
```
docker run -it -d --name myApp -p 4000:1337 martinblaha/testapp sh -c 'cd /var/www/test/myapp && sails lift'
```
### Environment Variablen
Variante 1
```
$ docker run -it --name TestEnv -e MY_VAR="hello world" ubunut:20.04 /bin/bash
$ env
```
Variante 2
So wird der Wert von MY_VAR vom hostsystem automatisch mitgegeben:
```
$ docker run -it --name TestEnv -e MY_VAR ubunut:20.04 /bin/bash
$ env
```
Variante 3
Env Variable Liste übergeben
```
$ docker run -it --name TestEnv -env-file ./env.list ubunut:20.04 /bin/bash
$ env
```
### Link zwischen 2 Container
Sicherer Tunnel zwischen beiden Container. Ports müssen nicht geöffnet werden. Dabei geschieht folgendes:
- Umgebungsvariablen des Quellcontainers werden im Zielcontainer veröffentlicht.
- Einträge in ''/etc/hosts'' des Zielcontainers gesetzt, die zum Quellcontainer führen.
Beispiel:
Ubuntu 20.04 Image erstellen und mit mongodb:mongo Container verlinken.
```
mongodb: NAMES, mongo: IMAGE (sieht man, wenn man docker ps macht)
$ docker run -it -P --link mongodb:mongo ubuntu:20.04 /bin/bash
```
## Container Commands
### Anzeigen aller Container
```
docker ps -a
docker container ls -a # alternativ
```
Nur laufende:
```
docker ps
docker container ls # alternativ
```
### Ausgabe eines Containers anzeigen
```
docker logs <docker id>
```
Docker Logs generell:
```
journalctl -xu docker.service
```
### Container starten
```
docker run -d -p 3000:80 -e --name <beliebiger_containername> <IMAGE ID>
```
### Container stoppen / neu starten
```
docker stop <containername>
docker restart <containername>
```
### Container (schneller) stoppen und löschen
```
docker kill <containername>
docker rm <containername>
```
### Befehl in Docker Container ausführen
Z.B. MySQL, wobei `wordpress-baumfreunde_db_1` der Container-Name ist, den man mit `docker ps` herausfindet.
```
sudo docker exec -it wordpress-baumfreunde_db_1 mysql -uroot -p
```
### Import DB in docker container
```
sudo docker exec -i wp_db mysql -h 172.17.0.1 -P 3306 --protocol=tcp -uroot -p wp_baum < /var/www/wordpress-from-docker/wp_baum.sql
```
### Backup DB in docker container
```
docker exec -it wordpress-baumfreunde_db_1 mysqldump --add-drop-table -uroot -pXXX wp_baum > /home/roru/wordpress-baumfreunde/wp_baum_backup.sql
```
### Bash in container
```
sudo docker exec it <container-name> /bin/bash
# Alpine
sudo docker exec it <container-name> /bin/sh
# als root
docker exec -u root -it <container-name> /bin/bash
```
### Copy file from host to docker container
```
sudo docker cp "file.txt" c30c199ec89c:/home/actions
```
### Copy folder from docker container to host
```
sudo docker cp "c30c199ec89c:/home/actions/conf /home/rogrut
```
### Get IP of docker container
```
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name
```
### Remove docker container
`docker stop Test_run` und `docker rm Test_run`.
# Docker compose
- __Purpose:__ Defines and manages multi-container Docker applications.
- __Usage:__ Orchestrates multiple services (containers), networks, and volumes for an application.
- __Key Features:__
- Describes how to run one or more containers together.
- Can manage container networking and persistent storage.
- Useful for applications with multiple services (e.g., a web app + database).
- __Output:__ A running application consisting of multiple containers.
`docker-compose.yml` is the file which includes all nescessary information. It can include multiple services like web (built from a Dockerfile) and db (pulled from Docker Hub).
## docker-compose vs docker compose
- If you're using a modern Docker installation (20.10+), use `docker compose`.
- If you're working on a system with an older Docker version or have compatibility concerns, use `docker-compose`.
| Feature | docker compose | docker-compose |
| --- | --- | --- |
| Integration | Integrated into Docker CLI | Standalone binary |
| Compose Specification | Supports Compose V2 | Supports older Compose V1 |
| Performance | Faster and more efficient | Slower compared to Compose V2 |
| Availability | Docker 20.10+ and Docker Desktop | Any Docker version, standalone |
| Future-proof | Actively developed and maintained | Legacy, less maintained |
check your docker compose version (examples):
```
docker compose version
Docker Compose version v2.32.1
# is installed together with docker v27.4.1
docker-compose --version
docker-compose version 1.25.0, build unknown
# separate installation for old version.
```
## Image Location
Example:
```
services:
nproxy-app:
image: 'jc21/nginx-proxy-manager:latest'
build: .
```
### Registry
In docker compose, use `image` to use an existing image from the registry.
```
services:
redis:
image: redis:latest
```
### Local Image
Don't use `image`, but `build`.
```
services:
my-local-app:
build: .
```
`build: .` tells Docker Compose to look for a `Dockerfile` in the same directory as the `docker-compose.yml`.
If the Dockerfile is in a subdirectory, specify the context and Dockerfile path:
```
services:
my-local-app:
build:
context: ./my-app
dockerfile: Dockerfile.dev
```
- `context:` Specifies the directory containing the application code.
- `dockerfile:` Specifies the name of the Dockerfile if its not the default Dockerfile.
You can mix local builds and images from a registry in the same docker-compose.yml file:
```
services:
my-local-app:
build: .
ports:
- "8080:8080"
redis:
image: redis:latest
webapp:
build: .
image: registry.cs.zi.uzh.ch/zi-adb-dba/export-digicert-report:latest
```
## Docker Volumes
There are three volume types:
1. Docker volumes which are stored and handled internally by docker (c.f. docker config to choose where they are actually stored).
```
version: '3.9'
services:
caddy:
image: caddy:2.6.2
volumes:
- caddy_data:/data
volumes:
caddy_data
```
2. Bind mounts which are direct access to the host file system from a container
```
version: '3.9'
services:
caddy:
image: caddy:2.6.2
volumes:
- /opt/docuteam/ssl/certifcate.pem:/cert.pem:ro</code>
3. Bind mounts of remote share which are defined through docker volumes
<code>version: '3.9'
services:
fedora:
image: docker.cloudsmith.io/docuteam/docker/fcrepo:6.2.0
volumes:
- fedora_data:/fcrepo_home
volumes:
fedora_data:
driver_opts:
type: cifs
device: //remote-hostname.com/path/to/share/fedora
o: addr=remote-hostname.com,username=user,password=mysuperpassword,nodev,noexec,nosuid,vers=2.1,uid=1000,gid=1000
```
### Show docker volumes
```
docker volume ls
```
## Commands
### Start
Ins Verzeichnis gehen wo docker-compose.yml liegt, und dann `docker-compose start -d`. Mit `-d` wird es im Hintergrund ausgeführt.
### Stop
- The `docker-compose stop` command will stop your containers, but it wont remove them.
- The `docker-compose down` command will stop your containers, but it also removes the stopped containers as well as any networks that were created.
- You can take down 1 step further and add the `-v` flag to remove all volumes too. This is great for doing a full blown reset on your environment by running `docker-compose down -v`.
### Events
```
docker compose events
```
# Allgemeine Commands
## Aufräumen
Löscht alle Images, Volumes, Netzwerke, die nicht mit mind. 1 Container verbunden sind, sowie den Build Cache.
```
docker system prune --all --volumes
```