Skip to main content

Grundlagen

Docker Grundlagen, Compose und Nexus3 Registry

Stand: 25.06.2026

Diese Seite beschreibt die Installation und Grundbedienung von Docker Engine, Docker Compose, Image-Import/-Export und das Pushen von Images in eine Nexus3 Docker Registry.

Wichtige Änderungen gegenüber der alten Seite

  • Docker-Repository-Einrichtung nutzt jetzt /etc/apt/keyrings/docker.asc und /etc/apt/sources.list.d/docker.sources.
  • Docker Compose wird als Plugin installiert und mit docker compose genutzt, nicht mehr mit docker-compose.
  • Portainer nutzt standardmäßig HTTPS auf Port 9443. Port 9000 ist nur noch für Legacy-HTTP-Zugriff nötig.
  • Die Proxy-Konfiguration für den Docker Daemon wird bevorzugt in /etc/docker/daemon.json unter proxies gepflegt.
  • Der Nexus3-Abschnitt enthält jetzt den Ablauf: docker load aus file.tar, Image taggen und nach Nexus3 pushen.

1. Installation

Windows

Für Windows wird Docker Desktop verwendet.

https://www.docker.com/products/docker-desktop/

Proxy-Einstellungen werden bei Docker Desktop über die Docker-Desktop-Oberfläche gesetzt. Die Proxy-Werte aus /etc/docker/daemon.json gelten dort nicht.

Linux: Debian / Ubuntu

Vor der Installation sollten alte oder distributionsfremde Docker-Pakete entfernt werden.

Debian: alte Pakete entfernen

sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-doc podman-docker containerd runc 2>/dev/null | cut -f1)

Ubuntu: alte Pakete entfernen

sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runc 2>/dev/null | cut -f1)

Docker Repository auf Debian einrichten

# Docker GPG-Key und APT-Repository einrichten
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update

Docker Repository auf Ubuntu einrichten

# Docker GPG-Key und APT-Repository einrichten
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update

Docker Engine und Compose Plugin installieren

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Installation prüfen

sudo systemctl status docker
sudo docker run hello-world
docker compose version

Benutzer zur docker-Gruppe hinzufügen

Damit Docker ohne sudo genutzt werden kann, kann der eigene Benutzer zur Gruppe docker hinzugefügt werden.

sudo usermod -aG docker $USER

Danach einmal abmelden und wieder anmelden. Wichtig: Mitglieder der Gruppe docker haben auf dem Host sehr weitreichende Rechte.

2. Docker Daemon konfigurieren

Die zentrale Konfigurationsdatei ist:

/etc/docker/daemon.json

Beispielkonfiguration

{
  "data-root": "/srv/docker",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "storage-driver": "overlay2",
  "registry-mirrors": [
    "https://nexus.unternehmen.de:15000"
  ],
  "insecure-registries": [
    "myregistry.local:5000"
  ],
  "proxies": {
    "http-proxy": "http://10.96.10.145:7070",
    "https-proxy": "http://10.96.10.145:7070",
    "no-proxy": "localhost,127.0.0.1,.mein.netz,nexus.unternehmen.de"
  }
}

Hinweise zur Daemon-Konfiguration

  • data-root verschiebt den Docker-Datenbestand. Bei bestehenden Hosts muss vorher geplant werden, ob alte Images, Container und Volumes migriert werden.
  • log-opts verhindert unbegrenzt wachsende JSON-Logs.
  • registry-mirrors ist für Docker-Hub-Mirrors gedacht. Ein Nexus3 Hosted Repository zum Pushen wird dagegen direkt per docker tag und docker push angesprochen.
  • insecure-registries nur für vertrauenswürdige interne Registries ohne gültiges TLS verwenden.
  • proxies gilt für den Docker Daemon, also zum Beispiel beim Pull von Images durch den Daemon.

Docker neu starten

sudo systemctl restart docker

3. Docker-Befehle: Basics

Befehl Beschreibung
docker ps Laufende Container anzeigen
docker ps -a Alle Container anzeigen
docker images Lokale Images anzeigen
docker pull nginx:latest Image herunterladen
docker run -it ubuntu:24.04 /bin/bash Interaktiven Container mit Shell starten
docker run -d -p 8080:80 nginx:latest Container im Hintergrund mit Portweiterleitung starten
docker logs <container> Logs eines Containers anzeigen
docker logs -f <container> Logs live verfolgen
docker exec -it <container> bash Shell in einem laufenden Container öffnen
docker stop <container> Container stoppen
docker start <container> Container starten
docker rm <container> Container löschen
docker rmi <image> Image löschen

4. Volumes, Ports und Namen

docker run -d \
  --name meinweb \
  -p 8080:80 \
  -v /srv/www:/usr/share/nginx/html:ro \
  --restart unless-stopped \
  nginx:latest
Option Bedeutung
--name meinweb Sprechbarer Containername
-p 8080:80 Host-Port 8080 wird auf Container-Port 80 weitergeleitet
-v /srv/www:/usr/share/nginx/html:ro Host-Verzeichnis wird read-only in den Container gemountet
--restart unless-stopped Container startet nach Neustart automatisch, außer er wurde manuell gestoppt

5. Docker Compose

Docker Compose wird heute als Docker-Plugin genutzt:

docker compose version

Beispiel: Nginx

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    restart: unless-stopped

Starten und stoppen

docker compose up -d
docker compose ps
docker compose logs -f
docker compose down

6. Proxy und Netzwerk

Bevorzugte Daemon-Proxy-Konfiguration in /etc/docker/daemon.json:

{
  "proxies": {
    "http-proxy": "http://proxy.example.com:3128",
    "https-proxy": "http://proxy.example.com:3128",
    "no-proxy": "localhost,127.0.0.1,.example.org"
  }
}

Nach Änderung:

sudo systemctl restart docker

Alternative über systemd-Drop-in, wenn die Proxy-Konfiguration bewusst außerhalb von daemon.json gepflegt werden soll:

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://10.96.10.145:7070"
Environment="HTTPS_PROXY=http://10.96.10.145:7070"
Environment="NO_PROXY=localhost,127.0.0.1,.mein.netz,nexus.unternehmen.de"
sudo systemctl daemon-reload
sudo systemctl restart docker

7. Import / Export von Images und Containern

Image sichern und laden

docker save sichert ein Image inklusive Layern, Tags und Image-Metadaten. Das ist der richtige Weg, wenn ein Image auf einen anderen Host übertragen oder später in eine Registry gepusht werden soll.

docker save mein-image:1.0 -o mein-image_1.0.tar

docker load -i mein-image_1.0.tar

Image komprimiert sichern

docker save mein-image:1.0 | gzip > mein-image_1.0.tar.gz

docker load -i mein-image_1.0.tar.gz

Container-Dateisystem exportieren und importieren

docker export exportiert nur das Dateisystem eines Containers. Image-Metadaten wie CMD, ENTRYPOINT, ENV, Labels und Tags gehen dabei verloren. Für normale Image-Transfers ist daher docker save besser.

docker export mein-container | gzip > mein-container.tar.gz

gunzip -c mein-container.tar.gz | docker import - mein-image:from-container
Vergleich save/load export/import
Objekt Docker Image Container-Dateisystem
Layer enthalten flach exportiert
Tags enthalten fehlen
Metadaten wie CMD, ENTRYPOINT, ENV enthalten fehlen
Typische Anwendung Image-Transfer, Offline-Transport, Registry-Push Notfall-Snapshot eines Container-Dateisystems

8. Aus docker save file.tar wieder ein Image zum Pushen nach Nexus3 machen

Dieser Ablauf ist wichtig, wenn ein Image als TAR-Datei vorliegt und danach in Nexus3 als Docker Hosted Repository veröffentlicht werden soll.

Voraussetzungen in Nexus3

  • Es existiert ein Docker Hosted Repository, zum Beispiel docker-hosted.
  • Das Repository hat einen eigenen HTTP- oder HTTPS-Connector-Port, zum Beispiel 15000.
  • Der Benutzer hat Push-Rechte auf dieses Hosted Repository.
  • Der Docker Bearer Token Realm ist in Nexus3 aktiviert, wenn Authentifizierung für Docker genutzt wird.
  • Push ist nur in ein Hosted Repository möglich, nicht in ein Proxy Repository.

Schritt 1: TAR-Datei laden

docker load -i file.tar

Danach prüfen, welches Image geladen wurde:

docker images

Schritt 2: Bei Nexus3 anmelden

Wichtig: Beim klassischen Repository-Connector wird nur Hostname und Port verwendet. Kein /repository/docker-hosted an docker login anhängen.

docker login nexus.unternehmen.de:15000

Schritt 3: Image für Nexus3 taggen

Wenn das geladene Image bereits einen Namen und Tag besitzt:

docker tag mein-image:1.0 nexus.unternehmen.de:15000/mein-team/mein-image:1.0

Wenn das Image nach docker load nur als <none>:<none> oder nur über die Image-ID sichtbar ist:

docker images

docker tag <IMAGE_ID> nexus.unternehmen.de:15000/mein-team/mein-image:1.0

Schritt 4: Image nach Nexus3 pushen

docker push nexus.unternehmen.de:15000/mein-team/mein-image:1.0

Schritt 5: Pull-Test auf einem anderen Host

docker login nexus.unternehmen.de:15000
docker pull nexus.unternehmen.de:15000/mein-team/mein-image:1.0

Komplettbeispiel

# Auf Host A: Image als TAR-Datei sichern
docker save mein-image:1.0 -o mein-image_1.0.tar

# Datei auf Host B kopieren, dann laden
docker load -i mein-image_1.0.tar

# Ggf. Image prüfen
docker images | grep mein-image

# Bei Nexus3 anmelden
docker login nexus.unternehmen.de:15000

# Für Nexus3 taggen
docker tag mein-image:1.0 nexus.unternehmen.de:15000/mein-team/mein-image:1.0

# Push in Nexus3 Hosted Repository
docker push nexus.unternehmen.de:15000/mein-team/mein-image:1.0

Typische Fehler beim Nexus3-Push

Fehlerbild Wahrscheinliche Ursache Lösung
unauthorized Nicht angemeldet oder keine Push-Rechte docker login prüfen, Benutzerrechte in Nexus3 prüfen
unknown: Repository does not allow updating assets Tag existiert bereits und Redeploy ist verboten Neuen Tag verwenden oder Deployment Policy prüfen
server gave HTTP response to HTTPS client Registry ist HTTP, Docker erwartet HTTPS Registry mit TLS betreiben oder als insecure-registries eintragen
requested access to the resource is denied Falsches Zielrepository, falscher Port oder fehlende Rechte Hosted-Connector-Port und Rechte prüfen
login mit /repository/docker-hosted schlägt fehl Docker-Client erwartet Registry Root /v2/ Bei klassischem Connector nur nexus-host:port verwenden

9. Aufräumen

Vorsicht: Prune-Befehle löschen ungenutzte Objekte. Vorher prüfen, ob Images, Container oder Volumes noch benötigt werden.

# Ungenutzte Container, Netzwerke, dangling Images und Build-Cache löschen
docker system prune

# Zusätzlich alle ungenutzten Images löschen
docker image prune -a

# Ungenutzte Volumes anzeigen
docker volume ls -f dangling=true

# Ungenutzte Volumes löschen
docker volume prune

10. Eigene lokale Registry

Für einfache Tests kann eine lokale Docker Registry gestartet werden.

docker run -d \
  -p 5000:5000 \
  --restart always \
  --name registry \
  registry:2

Image taggen und pushen:

docker tag nginx:latest localhost:5000/nginx:latest
docker push localhost:5000/nginx:latest

11. Management-Tools

Portainer CE

Portainer CE wird standardmäßig über HTTPS auf Port 9443 bereitgestellt.

docker volume create portainer_data

docker run -d \
  --name portainer \
  -p 8000:8000 \
  -p 9443:9443 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  --restart=always \
  portainer/portainer-ce:sts

Aufruf:

https://SERVERNAME:9443

Falls aus Legacy-Gründen HTTP benötigt wird, kann zusätzlich Port 9000 veröffentlicht werden:

-p 9000:9000

Nexus3 als Docker Registry

Beispiel für Nexus3 mit Weboberfläche auf Port 8081 und Docker Hosted Connector auf Port 15000.

mkdir -p ./nexus-data
sudo chown -R 200:200 ./nexus-data
services:
  nexus:
    image: sonatype/nexus3:latest
    container_name: nexus
    ports:
      - "8081:8081"
      - "15000:15000"
    volumes:
      - ./nexus-data:/nexus-data
    restart: unless-stopped

Start:

docker compose up -d

Nexus3-Weboberfläche:

http://SERVERNAME:8081

Docker Hosted Repository in Nexus3 anlegen:

  1. In Nexus3 anmelden.
  2. Settings → Repository → Repositories → Create repository.
  3. docker (hosted) auswählen.
  4. Name festlegen, zum Beispiel docker-hosted.
  5. HTTP- oder HTTPS-Connector aktivieren, zum Beispiel Port 15000.
  6. Deployment Policy festlegen.
  7. Speichern.

12. Beispiele

Beispiel: Jenkins Agent

services:
  jenkins_agent:
    image: nexus.unternehmen.de:15000/ci/jenkins-agent:2.15.0
    environment:
      JENKINS_AGENT_NAME: jenkins01
      JENKINS_URL: http://jenkins:8080
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    restart: unless-stopped

Beispiel: MongoDB

services:
  mongodb:
    image: mongo:7
    ports:
      - "27017:27017"
    volumes:
      - ./data:/data/db
    restart: unless-stopped

Beispiel: Apache mit PHP

Für PHP-Anwendungen ist ein offizielles PHP-Apache-Image oft sauberer als ein selbst gebautes Ubuntu-Image mit Apache und PHP.

FROM php:8.3-apache

RUN apt-get update \
  && apt-get install -y --no-install-recommends ca-certificates msmtp-mta \
  && rm -rf /var/lib/apt/lists/*

COPY default.conf /etc/apache2/sites-available/000-default.conf
RUN a2enmod rewrite headers

VOLUME ["/data"]
EXPOSE 80

Beispiel: Docker Compose mit Build

services:
  recursor:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      PDNS_RECURSOR_API_KEY: ${PDNS_RECURSOR_API_KEY}
    ports:
      - "2053:53"
      - "2053:53/udp"
      - "8082:8082"
    restart: unless-stopped

13. Geprüfte Quellen