# Docker Container

**URL:** https://forum.netzwissen.de/t/docker-container/1058
**Category:** DevOps
**Tags:** docker
**Created:** [27. Juli 2025 um 15:35 UTC](https://forum.netzwissen.de/t/docker-container/1058 "2025-07-27T15:35:52Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![mainmod](https://forum.netzwissen.de/user_avatar/forum.netzwissen.de/mainmod/32/1047_2.png) [@mainmod](https://forum.netzwissen.de/u/mainmod)
#### Post date: [27. Juli 2025 um 15:35 UTC](https://forum.netzwissen.de/t/docker-container/1058/1 "2025-07-27T15:35:53Z")

</div>

# Docker

Allgemeine Doku: [https://docs.docker.com/](https://docs.docker.com/)

## Basisinstallation

- Auf SUSE: [Install Docker Engine | Docker Docs](https://docs.docker.com/engine/installation/linux/suse/)
- Auf Ubuntu: [Install Docker Engine on Ubuntu | Docker Docs](https://docs.docker.com/engine/installation/linux/ubuntulinux/)

## Docker Daten auf btrfs Partition

```auto
root@docker3:/etc/docker/daemon.json

{
   "storage-driver": "btrfs",
   "data-root": "/mnt/data/docker"
}

```

# Build

> **[Docker Build: A Beginner's Guide to Building Docker Images - Stackify](https://stackify.com/docker-build-a-beginners-guide-to-building-docker-images/)**
>
> Docker has changed how we create applications, but it isn’t new. If building a Docker image has been daunting for you, read this post.

Ein Build geht immer von einem Dockerfile aus und erzeugt daraus ein Image

```auto
# Use official Alpine release
FROM alpine:3.19.3 as build

# Maintainer
LABEL maintainer="Thomas Rother <thomas.rother@devoteam.com>"
LABEL version="1.2"
LABEL description="radsec proxy server for remote RADIUS operation with TLS security"

ENV RADSECVERSION 1.11.0
ENV RADSECURL https://github.com/radsecproxy/radsecproxy/releases/download/${RADSECVERSION}/
ENV RADSECFILENAME radsecproxy-${RADSECVERSION}.tar.gz

# Change working dir
WORKDIR /root

# Update apk
RUN apk update

# Install buildtools
RUN apk add --no-cache make g++ openssl-dev nettle-dev musl-dev

# Create output dir
RUN mkdir output

# Download radsecproxy source files
RUN wget ${RADSECURL}${RADSECFILENAME}

# Untar radsecproxy
RUN tar xf ${RADSECFILENAME} --strip-components=1

# Configure
RUN ./configure --prefix=/root/output --sysconfdir=/etc

# Make and install to output dir
RUN make && make install

# Create radsecproxy container
FROM alpine:3.19.3

# Update apk
RUN apk update

# Install openssl, ca-certificates, nettle and tini
RUN apk add --no-cache openssl ca-certificates bash nettle tini

# Copy from 'build' stage
COPY --from=build /root/output/ /
# COPY --from=build /root/radsecproxy.conf-example /etc/radsecproxy/radsecproxy.conf

# create config directory and add certs
RUN mkdir /etc/radsecproxy/
COPY radsecproxy/ /etc/radsecproxy/
COPY certs/ /etc/radsecproxy/

# Copy start.sh
COPY start.sh /root/start.sh

# Make start.sh executeable
RUN chmod u+x /root/start.sh

# Create Radsecproxy logging
RUN mkdir /var/log/radsecproxy

# Export volumes
VOLUME /var/log/radsecproxy

# Make Radsecproxy's ports available
EXPOSE 2083

# Set Tini entrypoint
# https://computingpost.medium.com/how-to-use-tini-init-system-in-docker-containers-69283d0099ed
ENTRYPOINT ["/sbin/tini", "--"]

    # Start Radsecproxy
    CMD ["/root/start.sh"]

```

> **[Dockerfile reference](https://docs.docker.com/reference/dockerfile/)**
>
> Find all the available commands you can use in a Dockerfile and learn how to use them, including COPY, ARG, ENTRYPOINT, and more.

Syntax check für ein Dockerfile

```auto
docker build --check .

```

Ein Build wird normalerweise gecacht, das kann man abschalten:

```auto
docker --no-cache build .

```

Docker build ohne cache, dafür aber mit tag:

```auto
docker build --no-cache -t thommie/freeradius01:v1 .

```

Das getaggte Image kann man in eine Registry schieben, z.B. in die Docker Registry.

```auto
docker login

```

## Tag mit Versionsnummer

```auto
docker tag thommie/radsecproxymb psammechinus/radsecproxymb:v1

```

Und dann hochladen:

```auto
thommie@odysseus4:~/Dokumente/docker/radsecproxy> docker push psammechinus/radsecproxymb:v1The push refers to repository [docker.io/psammechinus/radsecproxymb]
fef40b964b90: Pushed
a0cb24bdb2c8: Pushed
a105c78eaead: Pushed
b10598bffc84: Pushed
5e1cdb76f1d7: Pushed
c903625bb716: Pushed
8b191fa4fbcc: Pushed
4b606c4525db: Pushed
7e4e46af816c: Pushed
b895814e9e64: Pushed
v1: digest: sha256:64c0f5a9498a66bb5714efbda60263fd42886d3420b51ec89e3a0b56df08bba3 size: 2404

```

```auto
thommie@odysseus3:~/git/gitea/dockerbuilds/myradius> docker build -f myradius.docker .
Sending build context to Docker daemon 5.632kB
Step 1/3 : FROM freeradius/freeradius-server:latest
 ---> 0a093ead10b6
Step 2/3 : COPY raddb/ /etc/raddb/
 ---> 096f00c66db0
Step 3/3 : EXPOSE 1812-1813/udp
 ---> Running in 6d5f572b0a8b
Removing intermediate container 6d5f572b0a8b
 ---> c6c0d41f944a
Successfully built c6c0d41f944a

```

# Images

Das image ist die Basis für den/die lokalen Container. Images aus Repository runter laden

`docker pull `

Alle Images im lokalen repository zeigen

```auto
root@develd:~# docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
local_discourse/web_only latest 21e8a905ef5c 4 weeks ago 2.65GB
grundic/jamulus latest 9e97d3890ca8 5 weeks ago 90.3MB
discourse/base 2.0.20210217-2235 7027ba787aa6 2 months ago 2.22GB
discourse/base 2.0.20201221-2020 c0704d4ce2b4 4 months ago 2.11GB
local_discourse/data latest c7524a566464 5 months ago 2.44GB
discourse/base 2.0.20201004-2310 b64c37d7ab06 6 months ago 2.4GB
xbrowsersync/api latest a3554c99cc99 12 months ago 119MB

```

Image löschen

```auto
docker image rm [id]

```

Image Repo aufräumen: mit prune werden alle Images gelöscht, die nicht mindestens zu einem Container gehören.

```auto
docker image prune [OPTIONS]

```

# Aufräumen

Zeige den gesamten Speicherbedaf von Images, Containern und Volumes

```auto
docker system df

```

Alle angehaltenen Container und nicht mehr verwendete Images, Volumes und Netzwerke wegwerfen

```auto
docker system prune

```

# Image Migration u. Backups

## Image sichern

```auto
docker save -o mariadb:10.11.tar [Image-ID]

```

Das image kann man dann woanders hin transferieren (scp) und mit docker load dort neu bereitstellen.

## Load: Container neu aus Image erzeugen

Ein schon vorhandenes Image mit gleichem Namen wird umbenannt:

```auto
root@docker3a:/etc/docker/passbolt# docker load -i mariadb_10.11.tar
270a1170e7e3: Loading layer [==================================================>] 80.41MB/80.41MB
6d035e66c4fd: Loading layer [==================================================>] 337.9kB/337.9kB
1a966a87cda4: Loading layer [==================================================>] 16.31MB/16.31MB
76a062be1274: Loading layer [==================================================>] 1.536kB/1.536kB
4cc02cc5cc3f: Loading layer [==================================================>] 5.12kB/5.12kB
d714cd160054: Loading layer [==================================================>] 235.5MB/235.5MB
56f8438cbcbd: Loading layer [==================================================>] 13.82kB/13.82kB
03543ca2a586: Loading layer [==================================================>] 29.7kB/29.7kB
The image mariadb:10.11 already exists, renaming the old one with ID sha256:ba7defb864a8f2bba6824a7991b8569abc8cc053938493e0d559d539103ec6bd to empty string
Loaded image: mariadb:10.11

```

`docker create` **erzeugt** einen Container und startet ihn **nicht,** `docker run` **erzeugt und startet** ihn.

## Container starten/stoppen

`docker start [ID] docker stop [ID] `

**Alle** Container stoppen oder löschen

```auto
docker stop $ (docker ps -a -q) docker rm $(docker ps -a -q)

```

Diese können mit docker rm gelöscht werden

```auto
root@develd:~# docker rm e6e7c809ad34
e6e7c809ad34

```

Alle Container löschen, die nicht laufen

```auto
docker container prune

```

Restart policy ändern

```auto
docker update --restart=no matrix_synapse_1

```

Alle laufenden und gestoppten Container zeigen:

`docker ps -a `

Filtern auf laufende Container

```auto
root@develd:~# docker ps -a -f status=running
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
31f9a6ffcab8 grundic/jamulus "Jamulus" 19 hours ago Up 19 hours jolly_beaver
7c3cd1abf744 local_discourse/web_only "/sbin/boot" 4 weeks ago Up 5 days 127.0.0.1:84->80/tcp web_only
05f7f43d0493 local_discourse/data "/sbin/boot" 5 months ago Up 5 days data

```

Laufende und gestoppte zeigen, aber nur die container id ausgeben

`docker ps -aq `

Container zeigen, die nicht laufen

```auto
root@develd:~# docker ps -aq -f status=exited
b39916cf84e2
e6e7c809ad34

```

# Container Debugging

> **[How to Fix and Debug Docker Containers Like a Superhero | Docker](https://www.docker.com/blog/how-to-fix-and-debug-docker-containers-like-a-superhero/)**
>
> Container errors are tricky to diagnose, but some investigative magic works wonders. Read along to learn how to debug Docker containers.

Allgemeine logs anzeigen

`docker logs [container_id]`

Letzte 100 EInträge

`docker logs --tail 100 [container ID]`

log Tail live

`docker logs -f --tail 10 container_name`

Alle laufenden Prozesse im Container

`docker top [container ID]`

# Globales Container Management

Alle Container auf einmal stoppen

```auto
docker kill $(docker ps -q)
    docker rm $(docker ps -a -q)
    docker rmi $(docker images -q)

```

## Im Container arbeiten

Die meisten Container sind aufs nötigste reduziert, z.B. wenn Alpine Linux die Basis ist. Dann fehlen auch übliche Standardwerkzeuge wie z.B. less - stattdessen nutzt man cat

```auto
docker exec -t -i container_ID /bin/bash

```

Alternativ: stdin/out an den Container hängen:

```auto
docker attach [OPTIONS] CONTAINER

```

Achtung: wieder raus mit \*\*CTRL-p CTRL-q. \*\*Details siehe [https://docs.docker.com/engine/reference/commandline/attach/](https://docs.docker.com/engine/reference/commandline/attach/)

Daten kopieren zwischen drinnen und draussen

1. von **aussen** nach innen

```auto
docker cp ./some_file CONTAINER:/work

```

1. von **innen** nach aussen

# Datenbank aus Docker Container dumpen

Manchmal will man nicht, dass eine Datenbank im Container läuft, sondern lieber auf einem zentralen Datenbank (Cluster). Dann muss man die Datenbank aus dem Container rausholen. Bei postgres geht das so:

```auto
docker exec -t 604415a3e93e pg_dumpall -c -U gitea > dump\_\`date +%Y-%m-%d"\_"%H\_%M\_%S\`.sql

```

# Compose

Docker Compose erzeugt Docker Applikationen, die aus mehreren Containern bestehen können und über die Docker bridge (docher0) miteinander reden. docker compose up startet alles im Verbund.

- Das Dockerfile definiert die Laufzeit-Umgebung
- docker-compose.yml beschreibt die Services, die in Containern zusammen arbeiten
- „docker compose up“ erzeugt und startet die gesamte Applikation

Achtung: In älteren Docker Versionen (V1) mancher Distros war composer eine python basierte Anwendung. Es empfiehlt sich immer, die V2 aus [https://github.com/docker/compose](https://github.com/docker/compose) zu benutzen, die in GOLANG neu geschrieben wurde. Installation siehe [https://github.com/docker/compose/](https://github.com/docker/compose/)

Hinweis: Für Raspis wird das Binary für …-linux-armv7 benutzt (ARM Architektur)

## compose yaml validieren

```auto
docker compose -f docker-compose-pro.yaml config

```

## Update per docker compose

Update der Images, die im compose file referenziert sind

```auto
docker compose -f docker-compose-pro.yaml pull

```

Daraus die Container neu bauen und starten

```auto
docker compose -f docker-compose-pro.yaml up --build

```

Bauen **ohne** caching und dann starten

```auto
docker compose -f docker-compose-pro.yaml up --force-recreate --build

```

Docker Compose startet Container nicht daemonisiert. Wenn der Container dauerhaft laufen soll, dann -d hinzufügen:

```auto
docker compose up --force-recreate --build -d

```

Um Container als Daemon zu starten, nimmt man systemd.

# Netzwerke

Standardmässig werden drei Netze bridge, host, none angelegt.

- über _bridge_ kann man mit allen lokalen Containern und mit anderen Servern reden
- über _host_ kann nur mit lokalen Containern reden

```auto
root@docker1:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
54e670dd998d bridge bridge local
5b1cd745d5a3 docker_back bridge local
b56f108784b3 docker_dbnet bridge local
f3619965eb7b docker_front bridge local
c91196bf89eb host host local
b4f69adafbb3 none null local

```

Container werden normalerweise an die „docker0“ bridge auf dem Host gebunden, solange nicht beim docker create ein anderes Netzwerk gewählt wurde (`docker create –network=<NETWORK>`). Mit

Dies zeigt den Zustand eines Docker networks

```auto
docker network inspect bridge

```

## Custom networks

Ausserdem gibt es custom networks, die z.B. über compose angelegt werden können. docker network create erzeugt ein eigenes Netzwerk:

```auto
docker network create –subnet 192.168.82.0/24 –driver bridge bridge2

```

Danach anschauen

```auto
locutus:/home/thommie # docker network inspect bridge2 [{ "Name": "bridge2", "Id": "9c353bcf0c2c6ccee0b821e1ff4d1740a074bdea94e93959c522d46a4e6fde8e", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.82.0/24" }] }, "Internal": false, "Containers": {}, "Options": {}, "Labels": {} } ]

```

Mit

```auto
docker attach container1

```

sieht man das Netzwerk aus Sicht des Containers

# Volumes

Volumes sind Verzeichnisse/Dateien, die vom lokalen Docker Host in den Container gemappt werden und Daten enthalten, die unabhängig vom Container persistent gehalten werden. Volumes werden vom Docker Dämon gemanagt, die Daten liegen innerhalb des vom Docker Dämon verwalteten Speicherbereichs, z.B: auf /var/lib/docker.

Doku: [https://docs.docker.com/engine/admin/volumes/](https://docs.docker.com/engine/admin/volumes/)

Docker volumes in eine compose file:

```auto
services:
  frontend:
    image: node:lts
    volumes:
      - myapp:/home/node/app
volumes:
  myapp:
    external: true

```

Allgemeine Syntax:

**[lokales volume Verzeichnis Host]:[Verzeichnis im Container]**

Verzeichnisorte werden immer **relativ zum Ort des compose file** gesehen!

# Logging

Docker logs direkt lesen, analog zu tail -f:

```auto
docker logs --follow [containerid]

```

Umleiten der log Ausgabe nach journald mit setting in der daemon.json

```auto
{
 "data-root": "/mnt/data/docker",
  "log-driver": "journald"
}

```

```auto
journalctl -f -b CONTAINER_NAME=radiusclient

```

# commit - Container auf neue Maschine migrieren

Auf der Quellmaschine wir der Container in ein image commited. Während des Commits wird der Container pausiert.

```auto
'' docker commit [CONTAINER_ID_OR_NAME] [new_image_name]''

```

Danach packt man das image in einen tarball

```auto
'' docker save -o [path_to_save]/[image_name].tar [image_name]''

```

Der Container wird auf die neue Maschien transferiert und dort ausgepackt.

```auto
'' docker load -i /path/to/[image_name].tar''

```

Danach baut man aus dem transferierten Image einen neuen Container.

```auto
'' docker run -d [other_options] [image_name]''

```

**Achtung: volumes und Netzwerke werden nicht transferiert!**
