← Terug naar tutorials

Herstellen na mislukte Docker-upgrades: socket-, service- en versie-mismatch oplossen

dockerdevopslinuxsystemddocker-socketdocker-serviceversion-mismatchtroubleshootingupgradecontainer-runtime

Herstellen na mislukte Docker-upgrades: socket-, service- en versie-mismatch oplossen

Een mislukte Docker-upgrade kan leiden tot een frustrerende mix van symptomen: Cannot connect to the Docker daemon, een docker.sock die niet meer klopt, dockerd die niet start, of een CLI die een andere versie verwacht dan de daemon. Dit gebeurt vaak na gedeeltelijke upgrades, gemixte repositories, een rollback die niet volledig was, of een systeem dat zowel distro-pakketten (bijv. docker.io) als Docker’s eigen pakketten (docker-ce) door elkaar heeft.

Deze tutorial helpt je systematisch herstellen. Je leert:

Doelplatform: Linux met systemd (Ubuntu/Debian/Fedora/RHEL-achtigen).
Waar relevant worden distro-specifieke verschillen genoemd.


1. Begrijp de onderdelen: CLI, daemon, socket, systemd

Docker op Linux bestaat grofweg uit:

Wanneer upgrades mislukken, zie je vaak:


2. Symptomen en snelle triage

2.1 Veelvoorkomende foutmeldingen

2.2 Snelle statuscheck (kopieerbaar)

# Basis: werkt de CLI überhaupt?
docker version

# Systemd status
systemctl status docker --no-pager
systemctl status docker.socket --no-pager
systemctl status containerd --no-pager

# Logs (meest waardevol)
journalctl -u docker -n 200 --no-pager
journalctl -u containerd -n 200 --no-pager

# Bestaat de socket en wat zijn de rechten?
ls -l /var/run/docker.sock
stat /var/run/docker.sock

# Is dockerd actief en luistert hij?
ps aux | grep -E 'dockerd|containerd' | grep -v grep
ss -xl | grep docker

Interpretatie:


3. Socket- en serviceproblemen: systemd correct krijgen

3.1 docker.service vs docker.socket: wie start wie?

Op veel systemen kan Docker via docker.socket “on-demand” starten. De socket-unit luistert, en als er een connectie komt, start systemd docker.service.

Controleer of socket-activatie aan staat:

systemctl is-enabled docker.socket
systemctl is-active docker.socket
systemctl cat docker.socket
systemctl cat docker.service

Let op:

3.2 Reset een “verkeerd” gestarte service (zonder data te wissen)

Als Docker in een rare toestand zit na een upgrade:

sudo systemctl daemon-reload
sudo systemctl stop docker docker.socket
sudo systemctl stop containerd

# Optioneel: oude runtime restanten opruimen (niet destructief)
sudo rm -f /var/run/docker.pid /run/docker.pid 2>/dev/null || true
sudo rm -f /var/run/containerd/containerd.sock 2>/dev/null || true

sudo systemctl start containerd
sudo systemctl start docker.socket
sudo systemctl start docker

Check daarna:

systemctl --no-pager --full status docker docker.socket containerd
docker info

3.3 Veelvoorkomende oorzaak: fout in /etc/docker/daemon.json

Een upgrade kan strenger worden op JSON of deprecated keys. Valideer je config:

cat /etc/docker/daemon.json
python3 -m json.tool /etc/docker/daemon.json

Herstart en check logs:

sudo systemctl restart docker
journalctl -u docker -n 200 --no-pager

Veelvoorkomende fouten:

Als je "hosts" definieert, wees expliciet en consistent, bijvoorbeeld:

{
  "hosts": ["unix:///var/run/docker.sock"]
}

Let op: als je "hosts" in daemon.json zet, kan dat botsen met systemd unit-parameters. In dat geval moet je de systemd override aanpassen (zie hieronder).

3.4 Systemd override controleren (drop-ins)

Check of er overrides bestaan die na upgrade niet meer passen:

systemctl cat docker
ls -R /etc/systemd/system/docker.service.d || true

Een typische override die problemen veroorzaakt is een oude ExecStart= regel. Als je een override hebt, controleer dat hij past bij jouw installatie.

Je kunt tijdelijk alle overrides “neutraliseren” door ze te hernoemen (veilig, om te testen):

sudo mv /etc/systemd/system/docker.service.d /etc/systemd/system/docker.service.d.bak.$(date +%F) 2>/dev/null || true
sudo systemctl daemon-reload
sudo systemctl restart docker

Als dit het oplost, zet dan een correcte override terug in plaats van de oude.

3.5 Socket permissies en docker-groep

Als de daemon wel draait maar je krijgt permissieproblemen:

# Socket rechten
ls -l /var/run/docker.sock

# Groepen
getent group docker
id

Als je user niet in de docker groep zit:

sudo usermod -aG docker "$USER"
newgrp docker

Let op: newgrp werkt in de huidige shell; anders opnieuw inloggen.

3.6 Rootless Docker vs rootful Docker (veelgemaakte verwarring)

Soms “werkt Docker niet”, maar je zit in de verkeerde context: rootless gebruikt vaak een socket onder je home:

Check je context:

docker context ls
docker context show
docker info

Als je per ongeluk naar een rootless context wijst, zet terug:

docker context use default

Of expliciet:

export DOCKER_HOST=unix:///var/run/docker.sock
docker info

4. Versie-mismatch: client en server weer in lijn

4.1 Diagnose: docker version en API-versies

Voer uit:

docker version

Voorbeeld van mismatch:

Of fout:

Dit kan gebeuren als:

4.2 Controleer welke binary je draait

which docker
type -a docker
docker --version
dpkg -S "$(which docker)" 2>/dev/null || true
rpm -qf "$(which docker)" 2>/dev/null || true

Als type -a docker meerdere paden toont (bijv. /usr/bin/docker en /usr/local/bin/docker), kan er een oude/handmatige installatie in de weg zitten.

Verwijder/rename de “vreemde” binary (bijv. in /usr/local/bin) als die niet door je pakketbeheer wordt beheerd:

ls -l /usr/local/bin/docker /usr/local/bin/dockerd 2>/dev/null || true

4.3 Controleer geïnstalleerde pakketten (Debian/Ubuntu)

dpkg -l | grep -E 'docker|containerd|runc' | sed -e 's/\s\+/ /g'
apt-cache policy docker.io docker-ce docker-ce-cli containerd.io

Typische probleemcombinatie:

4.4 Controleer geïnstalleerde pakketten (RHEL/Fedora)

rpm -qa | grep -E 'docker|containerd|runc'
dnf list installed | grep -E 'docker|containerd|runc'

5. Herstelstrategie: kies één “lijn” en maak het consistent

Er zijn grofweg twee gezonde paden:

  1. Distro-pakketten (bijv. docker.io op Ubuntu/Debian)
  2. Docker’s officiële repo (docker-ce, docker-ce-cli, containerd.io)

Meng deze niet.

5.1 Data veiligstellen vóór je ingrijpt

Docker-data staat meestal in:

Maak een snelle back-up (kan groot zijn):

sudo systemctl stop docker containerd

# Back-up naar een andere schijf/locatie
sudo tar -C /var/lib -cpf /root/docker-backup-$(date +%F).tar docker containerd 2>/dev/null || true

# Start later weer
sudo systemctl start containerd
sudo systemctl start docker

Als je weinig ruimte hebt, back-up dan minimaal je volumes of specifieke paden.


6. Oplossen door opschonen en herinstalleren (zonder data te verliezen)

Hieronder staan “harde” stappen die vaak het snelst herstellen na een mislukte upgrade. Ze verwijderen pakketten, maar laten data in /var/lib/docker staan zolang je geen purge + data-delete doet.

6.1 Debian/Ubuntu: conflicterende pakketten verwijderen

Stop services:

sudo systemctl stop docker docker.socket containerd

Verwijder bekende conflictbronnen:

# Verwijder zowel oude als mogelijke mix
sudo apt-get remove -y docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc || true
sudo apt-get remove -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin || true

Ruim “kapotte” dependencies op:

sudo apt-get -f install -y
sudo apt-get autoremove -y

Controleer dat /var/lib/docker nog bestaat:

sudo ls -la /var/lib/docker | head

Doe geen apt-get purge als je niet zeker weet wat er weg mag; purge kan configs verwijderen (meestal oké), maar data staat doorgaans elders. Verwijder ook niet /var/lib/docker tenzij je bewust alles wilt wissen.

6.2 Installeer opnieuw: kies distro of Docker repo

Optie A: Distro-pakket (Ubuntu/Debian: docker.io)

sudo apt-get update
sudo apt-get install -y docker.io
sudo systemctl enable --now docker
docker version

Optie B: Docker’s officiële repo (meestal aanbevolen voor recente features)

Installeer prerequisites:

sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg

Keyring en repo (voorbeeld voor Ubuntu; pas codenaam aan indien nodig):

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
docker version

Controleer dat client en server nu matchen (major/minor hoeven niet exact gelijk, maar moeten compatibel zijn).


7. Socket-mismatch: wanneer /var/run en /run door elkaar lopen

Op moderne systemen is /var/run een symlink naar /run. Toch kunnen upgrades scripts of overrides achterlaten die naar een niet-bestaande socket wijzen.

Check:

ls -ld /var/run /run
readlink -f /var/run
ls -l /var/run/docker.sock /run/docker.sock 2>/dev/null || true

Als je DOCKER_HOST hebt gezet naar een oud pad:

echo "$DOCKER_HOST"
unset DOCKER_HOST
docker info

Als je in /etc/docker/daemon.json een socket pad hebt dat niet klopt, corrigeer dat.


8. Docker start niet: gerichte loganalyse

8.1 “failed to start daemon” door storage driver

Een upgrade kan de default storage driver veranderen of je kernel/FS support beïnvloeden. Check in logs:

journalctl -u docker -n 200 --no-pager | sed -n '1,200p'

Zoek naar:

Oplossingen verschillen:

Check huidige driver (als Docker nog start):

docker info | grep -i "Storage Driver"

8.2 “iptables/nftables” problemen na upgrade

Soms faalt Docker door firewall backend-wissels.

Check in logs op iptables/nft errors. Relevante checks:

sudo iptables -V
sudo nft --version

Op Debian/Ubuntu kan iptables naar nftables wijzen:

sudo update-alternatives --display iptables

Docker werkt meestal met nftables tegenwoordig, maar combinaties kunnen breken. Als je bewust legacy wilt:

sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
sudo systemctl restart docker

Doe dit alleen als logs duidelijk wijzen op nft/iptables incompatibiliteit. Anders creëer je nieuwe problemen.

8.3 “containerd is not running” of containerd socket errors

Docker hangt sterk af van containerd. Check:

systemctl status containerd --no-pager
journalctl -u containerd -n 200 --no-pager

Herstart:

sudo systemctl restart containerd
sudo systemctl restart docker

Als containerd faalt door config, check:

sudo test -f /etc/containerd/config.toml && sudo head -n 50 /etc/containerd/config.toml

Je kunt een default config genereren (pas op: dit overschrijft je bestaande config als je redirect gebruikt):

containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl restart docker

9. Compose en plugin-mismatch (docker compose vs docker-compose)

Na upgrades zie je vaak verwarring tussen:

Check:

docker compose version
docker-compose version || true

Als scripts nog docker-compose gebruiken, installeer óf de v1 binary (niet aanbevolen), óf update je scripts naar docker compose.

Op Ubuntu met Docker repo:

sudo apt-get install -y docker-compose-plugin
docker compose version

10. Verifieer herstel: functionele tests

10.1 Basis testcontainer

docker run --rm hello-world

10.2 Netwerk en volume test

docker network create testnet
docker volume create testvol

docker run --rm -it --network testnet -v testvol:/data alpine sh -lc \
  'echo "ok" > /data/health && cat /data/health'

docker network rm testnet
docker volume rm testvol

10.3 Controleer dat je oude resources er nog zijn

docker ps -a
docker images
docker volume ls

Als je containers “weg” lijken, controleer of Docker naar een andere data-root wijst:

docker info | grep -i "Docker Root Dir"

Standaard is dat /var/lib/docker. Als dat veranderd is (bijv. door een override of daemon.json "data-root"), zet het terug of verplaats data zorgvuldig.


11. Veelvoorkomende scenario’s en concrete fixes

Scenario A: “Cannot connect … docker.sock” maar docker.service is actief

  1. Check socket pad en context:
docker context show
echo "$DOCKER_HOST"
ls -l /var/run/docker.sock
  1. Check permissies:
id
getent group docker
  1. Test als root:
sudo docker info

Als sudo docker info werkt, is het een permissie/groep-issue.


Scenario B: “client is newer than server”

  1. Bekijk versies:
docker version
  1. Check pakketten:
dpkg -l | grep -E 'docker|containerd'
apt-cache policy docker.io docker-ce docker-ce-cli containerd.io
  1. Kies één lijn:

Meestal: installeer alles uit dezelfde repo en verwijder mix.


Scenario C: Docker start niet na upgrade door unit override

  1. Check unit:
systemctl cat docker
  1. Verwijder/disable overrides tijdelijk:
sudo mv /etc/systemd/system/docker.service.d /etc/systemd/system/docker.service.d.disabled.$(date +%s) 2>/dev/null || true
sudo systemctl daemon-reload
sudo systemctl restart docker
journalctl -u docker -n 100 --no-pager
  1. Bouw daarna een nieuwe override met systemctl edit docker (netjes beheerbaar):
sudo systemctl edit docker

Voorbeeld (alleen als je weet dat je dit nodig hebt), bv. extra host:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H unix:///var/run/docker.sock

Belangrijk: de lege ExecStart= regel reset de vorige definitie; zonder die krijg je dubbele ExecStart en faalt de unit.


Scenario D: Rootless en rootful door elkaar

  1. Check of je rootless service draait:
systemctl --user status docker --no-pager
  1. Check rootful:
sudo systemctl status docker --no-pager
  1. Kies bewust welke je gebruikt. Voor servers meestal rootful; voor desktops soms rootless.

12. Preventie: zo voorkom je herhaling

  1. Gebruik één bron voor Docker pakketten (distro óf Docker repo).
  2. Pin versies als je productie draait:
    • Debian/Ubuntu: apt-mark hold docker-ce docker-ce-cli containerd.io
  3. Controleer overrides na upgrades:
    • systemctl cat docker
  4. Bewaar daemon.json simpel; documenteer elke niet-standaard setting.
  5. Monitor na upgrades:
    • docker info
    • journalctl -u docker -n 50
  6. Maak periodiek back-ups van /var/lib/docker/volumes en je compose-projecten.

13. Checklist: “Docker werkt weer” in 2 minuten

Gebruik deze checklist als eindcontrole:

# 1) Services actief
systemctl is-active containerd
systemctl is-active docker

# 2) Socket bestaat
test -S /var/run/docker.sock && echo "socket ok"

# 3) Versies en connectie ok
docker version
docker info | head -n 30

# 4) Run test
docker run --rm hello-world

Als alle vier slagen, zijn socket, service en versie-keten weer consistent.


14. Extra: wanneer je écht schoon wilt beginnen (destructief)

Alleen als je bewust alles wilt verwijderen (containers/images/volumes):

sudo systemctl stop docker containerd

# WAARSCHUWING: dit wist alle Docker data
sudo rm -rf /var/lib/docker /var/lib/containerd

# Daarna opnieuw installeren (zie sectie 6)

Afsluiting

De kern van herstel na mislukte Docker-upgrades is bijna altijd: consistentie. Zorg dat:

Als je wilt, kun je de output plakken van:

docker version
systemctl status docker docker.socket containerd --no-pager
journalctl -u docker -n 120 --no-pager
systemctl cat docker
ls -l /var/run/docker.sock
dpkg -l | grep -E 'docker|containerd|runc' || rpm -qa | grep -E 'docker|containerd|runc'

Dan kan ik gericht aangeven welke mismatch jij precies hebt en welke stappen je het best overslaat of juist wél uitvoert.