559 lines
16 KiB
Markdown
559 lines
16 KiB
Markdown
---
|
||
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 it’s 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 won’t 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
|
||
``` |