Instalacja Dockera i Docker Compose na Debianie i Ubuntu

Opublikowano 14 min czytania

Dlaczego docker.io jest na Debianie 12 za stary, a na Ubuntu w zupełności wystarcza, jak podpiąć oficjalne repozytorium z keyringiem zamiast apt-key, dlaczego Compose to wtyczka i dlaczego grupa docker faktycznie oznacza roota.

Instalacja Dockera zajmuje pięć minut. Instalacja Dockera w taki sposób, żeby rok później serwer nadal dostawał aktualne poprawki bezpieczeństwa, dysk systemowy się nie zapełnił, a przy okazji nie okazało się, że każdy użytkownik chodzi po systemie z uprawnieniami roota, trwa nieco dłużej. Ten poradnik opisuje drugi wariant, sprawdzony na Debianie 13 (Trixie), Debianie 12 (Bookworm), Ubuntu 24.04 (Noble) i Ubuntu 22.04 (Jammy).

docker.io czy Docker CE: różnica, którą mało kto uczciwie wyjaśnia

Do Dockera prowadzą dwie drogi. Pakiet docker.io pochodzi ze źródeł pakietów dystrybucji, buduje go i utrzymuje odpowiednio Debian albo Ubuntu. Pakiet docker-ce pochodzi z repozytorium samego Dockera. Oba dostarczają to samo oprogramowanie, różnią się jednak mocno wiekiem wersji.

Takie wersje leżą obecnie w źródłach dystrybucji (zmierzone poleceniem apt-cache policy w świeżych kontenerach):

Systemdocker.io w źródłach dystrybucji
Debian 13 (Trixie)26.1.5
Debian 12 (Bookworm)20.10.24
Ubuntu 24.04 (Noble)29.1.3
Ubuntu 22.04 (Jammy)29.1.3

To jest sedno sprawy, a w niemal wszystkich poradnikach skraca się je do jednej ogólnej rekomendacji. Prawda jest bardziej złożona:

  • Ubuntu 24.04 i 22.04: docker.io stoi na 29.1.3, czyli praktycznie na poziomie aktualnej wersji upstream. Jeśli nie masz szczególnych wymagań, możesz tu bez wyrzutów sumienia sięgnąć po pakiet z dystrybucji. Poprawki bezpieczeństwa przychodzą wtedy zwykłym kanałem Ubuntu.
  • Debian 13: wersja 26.1.5 jest używalna, ale sporo za upstreamem. Do większości zastosowań w zupełności wystarczy.
  • Debian 12: 20.10.24 to przypadek problematyczny. Ta gałąź od lat jest w upstreamie na końcu cyklu życia. Debian wprawdzie nanosi poprawki bezpieczeństwa, ale po prostu brakuje wielu nowoczesnych funkcji, między innymi aktualnej wersji BuildKit i sporej części zgodności z Compose.

Dochodzi do tego różnica czysto praktyczna: docker-ce przynosi Buildx i Compose jako osobne pakiety wtyczek, dopasowane do silnika. Przy docker.io musisz te elementy pozbierać osobno z docker-buildxdocker-compose-v2, a docker-compose-v2 leży wyłącznie w źródłach Ubuntu, w Debianie tego pakietu w ogóle nie ma.

Czego zrobić nie można: użyć obu naraz. Pakiet containerd.io z repozytorium Dockera stoi w konflikcie z pakietem containerd z dystrybucji. Musisz się zdecydować.

Zasada praktyczna: na Ubuntu docker.io jest wyborem uzasadnionym. Na Debianie 12 już nie. Dla serwerów, które prowadzą stosy Compose z aktualną składnią, Docker CE wszędzie jest lepszą decyzją.

Usuń stare pakiety, zanim wydarzy się cokolwiek innego

Jeżeli jakiś Docker już w systemie jest, musi zniknąć, inaczej instalacja rozbije się o konflikty pakietów. Poniższa pętla usuwa wszystkich zwykłych podejrzanych i po drodze przechwytuje pakiety, które wcale nie są zainstalowane albo w twojej dystrybucji w ogóle nie istnieją:

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove -y $pkg || true; done

Fragment || true w ciele pętli nie jest kosmetyką, tylko koniecznością. Na Debianie apt-get przerywa pracę przy wpisie docker-compose-v2 komunikatem E: Unable to locate package docker-compose-v2 i kodem wyjścia 100, bo ten pakiet istnieje wyłącznie w źródłach Ubuntu, a nie w bookworm czy trixie (ani w bullseye, gdzie brakuje dodatkowo podman-docker). Pętla wprawdzie leci dalej, ale zostawia po sobie kod wyjścia różny od 0, i właśnie na tym umiera skrypt z set -e albo łańcuch spięty przez &&. Komunikaty w rodzaju „Unable to locate package” są więc w tym miejscu normalne i można je zignorować, tak samo traktuje je oficjalna dokumentacja Dockera.

Warto wiedzieć: nic przy tym nie przepada. Twoje obrazy, kontenery i wolumeny leżą w /var/lib/docker, a tego katalogu apt-get remove nie rusza. Po instalacji Docker CE twoje kontenery znów są na miejscu. Dopiero sudo rm -rf /var/lib/docker kasuje naprawdę, i to nieodwracalnie.

Klucz na właściwym miejscu: apt-key to już przeszłość

Wiele poradników w sieci zawiera jeszcze taki wiersz:

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -

Na żadnym z czterech omawianych tu systemów nie ma to już sensu. apt-key jest wycofany, a na Debianie 13 w ogóle go nie ma. Powód nie jest kosmetyczny: klucz w /etc/apt/trusted.gpg podpisuje wszystkie repozytoria, nie tylko to, dla którego był przeznaczony. Przejęty serwer lustrzany mógłby ci w ten sposób podrzucić dowolne pakiety.

Poprawne rozwiązanie to własny pęk kluczy w /etc/apt/keyrings/, przypisany przez Signed-By do dokładnie jednego źródła.

sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings

Poniższe polecenie pobiera właściwy klucz i działa zarówno na Debianie, jak i na Ubuntu, bo odczytuje identyfikator dystrybucji z /etc/os-release:

sudo curl -fsSL "https://download.docker.com/linux/$(. /etc/os-release && echo "$ID")/gpg" -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

A teraz krok, którego praktycznie nikt nie opisuje: sprawdź odcisk palca klucza, zanim powierzysz mu swój system.

gpg --show-keys /etc/apt/keyrings/docker.asc

W wyniku musi znaleźć się odcisk 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 oraz identyfikator Docker Release (CE deb) <docker@docker.com>. Jeśli się nie zgadza, przerwij instalację. Coś jest wtedy nie tak z twoim połączeniem albo ze źródłem.

Instalacja Docker CE, jednym fragmentem dla wszystkich czterech systemów

Oficjalna dokumentacja pokazuje osobne bloki dla Debiana i dla Ubuntu. To niepotrzebne. Poniższy blok zapisuje źródło pakietów w nowoczesnym formacie deb822 i sam ustala dystrybucję, nazwę kodową oraz architekturę:

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

Dwa szczegóły, które oszczędzają czas. Po pierwsze ${UBUNTU_CODENAME:-$VERSION_CODENAME}: na pochodnych Ubuntu, takich jak Linux Mint, w VERSION_CODENAME stoi nazwa pochodnej, a nie nazwa z Ubuntu. Po drugie wiersz Architectures: bez niego apt na systemach z włączoną obcą architekturą i386 sypie długim ostrzeżeniem o nieistniejących listach pakietów.

Sprawdź wynik, zanim ruszysz dalej:

cat /etc/apt/sources.list.d/docker.sources

Suites musi stać trixie, bookworm, noble albo jammy. Jeśli jest tam coś innego, kolejny krok wpadnie w błąd. Potem następują aktualizacja i instalacja:

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

Te pięć pakietów to: daemon, narzędzie wiersza poleceń, środowisko uruchomieniowe kontenerów, nowoczesny builder obrazów oraz Compose.

Po czym poznasz, że naprawdę działa

To, że apt-get przeszedł bez błędu, znaczy tylko tyle, że pliki leżą na dysku. Poniższe cztery sprawdzenia pokazują, czy system faktycznie pracuje.

Po pierwsze: czy klient dosięga daemona?

docker version

Decydujący nie jest fragment Client, tylko to, żeby poniżej pojawiła się sekcja Server: Docker Engine - Community z numerem wersji. Jeśli jej brakuje, daemon nie działa albo nie masz prawa dostępu do socketu.

Po drugie: który sterownik magazynu jest aktywny?

docker info --format '{{.Driver}}'
docker info --format '{{.CgroupVersion}}'

Tu czai się nowość, na którą wiele starszych poradników odpowiada błędnie. Od Docker Engine 29 przy nowych instalacjach domyślnie włączony jest magazyn obrazów containerd. Sterownik nazywa się wtedy overlayfs, a nie overlay2. Obie wartości są w porządku. Czego nie chcesz zobaczyć, to vfs: ten awaryjny sterownik kopiuje każdą warstwę w całości, pożera wielokrotnie więcej miejsca na dysku i jest dojmująco wolny. Pojawia się zwykle wtedy, gdy Docker pracuje w środowisku bez odpowiedniego wsparcia w kernelu. Wersja cgroup musi na wszystkich czterech systemach dawać 2.

Jeśli zaktualizowałeś istniejący system i nagle wygląda na to, że wszystkie obrazy zniknęły: one nie zostały skasowane. Przy zmianie magazynu obrazów zasoby drugiego składu są jedynie ukrywane i wracają po przełączeniu z powrotem. Przełączyć się z powrotem można przez /etc/docker/daemon.json:

{
  "features": {
    "containerd-snapshotter": false
  }
}

Po trzecie: czy kontener naprawdę startuje?

docker run --rm hello-world

Po czwarte: czy w kontenerze działa sieć i rozwiązywanie nazw? Tego testu brakuje w niemal każdym poradniku, chociaż to właśnie tutaj rodzi się większość późniejszych problemów:

docker run --rm alpine:3 ping -c 2 1.1.1.1
docker run --rm alpine:3 nslookup deb.debian.org

Jeśli ping odpowiada, a rozwiązywanie nazw zawodzi, przyczyną jest zwykle serwer DNS nasłuchujący wyłącznie na 127.0.0.53. Z wnętrza kontenera ten adres jest nieosiągalny. Pomaga wpis w /etc/docker/daemon.json"dns": ["9.9.9.9"] i restart daemona.

Compose to wtyczka, a nie osobny program

Stare docker-compose z łącznikiem było osobnym programem w Pythonie. Jego wsparcie się skończyło i nie jest już dostarczane. Następcą jest wtyczka napisana w Go, wywoływana jako podpolecenie Docker CLI, czyli docker compose ze spacją.

docker compose version

Uwaga na temat numeru wersji, bo to regularnie wprowadza zamieszanie: określenie „Compose V2” oznacza nową implementację w Go, a nie numer wersji. Dziś polecenie zwraca wersję z gałęzi 5. To poprawne i nie chodzi tu o żaden inny produkt.

Przy przesiadce rzucają się w oczy dwie rzeczy. Po pierwsze klucz version: na początku pliku docker-compose.yml stał się zbędny i wywołuje ostrzeżenie:

WARN[0000] docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion

Po prostu skasuj ten wiersz. Po drugie zmienia się nazewnictwo: Compose wyprowadza nazwę projektu z nazwy katalogu i tworzy kontenery z łącznikiem zamiast podkreślenia, czyli mojprojekt-web-1 zamiast mojprojekt_web_1. Skrypty, które odwołują się do kontenerów po sztywnych nazwach, na tym padają. W takich przypadkach ustaw nazwę projektu jawnie przez name: w pliku Compose albo przez -p.

Jeśli świadomie chcesz zostać przy pakietach z dystrybucji, właściwy pakiet nazywa się docker-compose-v2 i dostarcza to samo podpolecenie. Jest jednak dostępny tylko w źródłach Ubuntu. Sprawdź wcześniej dostępną wersję:

apt-cache policy docker-compose-v2

Na Ubuntu 24.04 i 22.04 pojawia się tabelka z wersją zainstalowaną i kandydującą. Na Debianie 13 i Debianie 12 polecenie nie wypisuje nic, pusty wynik z kodem wyjścia 0. To nie błąd, tylko odpowiedź: w Debianie tego pakietu nie ma, tam droga do Compose prowadzi przez docker-compose-plugin z repozytorium Dockera.

Grupa docker to root, tylko okrężną drogą

Żeby zwykły użytkownik mógł obsługiwać Dockera bez sudo, zwykle dopisuje się go do grupy docker:

sudo groupadd -f docker
sudo usermod -aG docker $USER

Przynależność do grupy zaczyna działać dopiero przy nowym logowaniu. Po ponownym zalogowaniu sprawdzisz to poleceniem id -nG. Kto nie chce logować się od nowa, uruchamia poleceniem newgrp docker shell z nową grupą.

Teraz fragment, który musisz zrozumieć: przynależność do grupy docker jest równoznaczna z uprawnieniami roota na całym serwerze. To nie jest ocena teoretyczna, tylko bezpośredni skutek zasady działania. Kto może rozmawiać z socketem Dockera, może wydawać dowolne polecenia daemonowi, a ten pracuje jako root. Wystarczy jedno polecenie:

docker run -it -v /:/hostfs alpine:3 chroot /hostfs sh

W efekcie dostajesz shell roota na systemie hosta, bez sudo, bez pytania o hasło, bez wpisu w logu sudo. Odczyt /etc/shadow, podłożenie kluczy SSH, podmiana usług: wszystko możliwe. Dokumentacja Dockera ujmuje to krótko i jednoznacznie: „The docker group grants root-level privileges to the user.”

Praktyczne konsekwencje dla serwera dostępnego z internetu:

  • Do grupy dopisuj wyłącznie te konta, którym i tak powierzyłbyś roota.
  • Użytkownik, na którym pracuje aplikacja webowa albo runner CI, do nich nie należy. Włamanie do aplikacji byłoby wtedy automatycznie włamaniem na serwer.
  • Jeśli potrzebujesz możliwości prześledzenia zdarzeń, zrezygnuj z grupy i wywołuj Dockera przez sudo docker. Wtedy przynajmniej samo wywołanie trafi do logu.
  • Dla prawdziwego rozdzielenia uprawnień jest tryb rootless. Konfiguruje się go pakietem docker-ce-rootless-extras i narzędziem dockerd-rootless-setuptool.sh install, potrzebny jest dodatkowo uidmap. Cena: portów poniżej 1024 nie zajmiesz bez dodatkowej konfiguracji, a część funkcji sieciowych zachowuje się inaczej.

Autostart: pułapka nazywa się docker.socket

Standardowe polecenie jest znane:

sudo systemctl enable --now docker.service
sudo systemctl enable --now containerd.service

Mniej znane jest to, dlaczego wyłączanie często nie skutkuje. Docker przynosi obok docker.service także docker.socket. Ten unit nasłuchuje na sockecie i przy pierwszym dostępie automatycznie startuje daemona. Kto więc wykona systemctl disable docker.service, a potem stwierdzi, że Docker mimo wszystko działa, nie zobaczył ducha: pierwsze docker ps podniosło daemona z powrotem przez unit socketu. Do pełnego wyłączenia potrzeba obu:

sudo systemctl disable --now docker.service docker.socket

Stan sprawdzisz poleceniem systemctl is-enabled docker.service, które musi zwrócić enabled.

Druga sprawa dotyczy twoich kontenerów. O tym, czy kontener wróci po restarcie, decyduje nie systemd, tylko polityka restartu. Kryje się w tym różnica, która regularnie zaskakuje: always uruchamia kontener ponownie także wtedy, gdy świadomie zatrzymałeś go przed restartem. unless-stopped respektuje twoje ręczne zatrzymanie także po restarcie. Dla serwerów unless-stopped jest z reguły właściwym wyborem:

services:
  web:
    image: nginx:stable
    restart: unless-stopped

Testem nie jest docker ps, tylko prawdziwy restart serwera i sprawdzenie stanu po nim.

Rotacja logów: najczęstsza przyczyna zapełnionego dysku systemowego

Docker domyślnie zapisuje wyjście każdego kontenera do pliku JSON w /var/lib/docker/containers/. Ten plik rośnie w ustawieniach domyślnych bez ograniczeń. Gadatliwy reverse proxy potrafi tak przez kilka miesięcy uzbierać dwucyfrową liczbę gigabajtów, aż serwer stanie z komunikatem no space left on device. Winowajcę trudno potem znaleźć, bo du w katalogu aplikacji nie pokazuje niczego podejrzanego.

To ustawienie powinno trafić na każdy serwer, i to zanim pojawi się pierwszy problem:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json > /dev/null <<'EOF'
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
EOF

Jeśli daemon.json już istnieje, to polecenie go nadpisze. Sprawdź wcześniej jego zawartość i w razie potrzeby dopisz klucze ręcznie. Potem:

sudo systemctl restart docker

Trzy miejsca, w których mimo to potrafi się posypać:

  • Wartości muszą stać jako ciągi znaków w cudzysłowach. "max-file": 3 bez cudzysłowów sprawi, że daemon w ogóle nie wystartuje.
  • Ustawienie obowiązuje wyłącznie dla nowo utworzonych kontenerów. Istniejące zachowują starą konfigurację, dopóki nie powstaną od nowa, przy Compose przez docker compose up -d --force-recreate.
  • Skasowanie przepełnionego pliku logu poleceniem rm nie odzyska miejsca na dysku, bo daemon trzyma ten plik nadal otwarty. Użyj zamiast tego sudo truncate -s 0 <ścieżka>.

Czy ustawienie działa na konkretnym kontenerze, sprawdzisz tak:

docker inspect --format '{{json .HostConfig.LogConfig}}' mojkontener

Sprzątanie przez docker system prune, bez utraty danych

Nieużywane obrazy, przerwane buildy i cache BuildKit sumują się. Najpierw zobacz, gdzie ucieka miejsce:

docker system df
docker system df -v

Standardowe polecenie sprzątające usuwa zatrzymane kontenery, nieużywane sieci, obrazy bez nazwy oraz cache buildów:

docker system prune

Dwa przełączniki zasługują na szacunek. -a kasuje dodatkowo wszystkie obrazy, z których w danej chwili nie korzysta żaden kontener, a więc także starannie pielęgnowane obrazy bazowe. Na serwerze z wąskim łączem ich ponowne pobranie potrafi potrwać. Wyraźnie groźniejszy jest --volumes: ten przełącznik usuwa nazwane wolumeny bez przypisanego kontenera. Jeśli twój kontener bazy danych właśnie został skasowany, a wolumen wciąż zawiera dane, po tej operacji ich nie ma. Kosza tutaj nie znajdziesz.

Nigdy nie używaj --volumes w automatycznym zadaniu sprzątającym.

Rozsądny jest okres karencji, żeby znikał tylko naprawdę stary materiał:

docker system prune -a --filter "until=168h"
docker builder prune --filter "until=168h"

Jako cotygodniowe zadanie, oszczędnie nocą i bez kasowania wolumenów, wystarczy jeden wiersz w /etc/cron.d/docker-prune:

15 4 * * 0 root /usr/bin/docker system prune -af --filter "until=168h" > /dev/null 2>&1

Dowodem skuteczności jest ponowne docker system df ze zmniejszoną kolumną „RECLAIMABLE”.

Komunikaty błędów w oryginalnym brzmieniu i co się za nimi kryje

permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
Użytkownik nie należy do grupy docker albo przynależność do grupy nie działa jeszcze w bieżącej sesji. Zaloguj się od nowa albo użyj newgrp docker.

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
Daemon nie działa. Przyczynę i dokładne brzmienie poda systemctl status docker, a obszerniej journalctl -u docker -n 50 --no-pager. Bardzo często kryje się za tym błędny /etc/docker/daemon.json. Ten plik musi być poprawnym JSON-em, wystarczy jeden przecinek za dużo.

docker: 'compose' is not a docker command.
Brakuje wtyczki. Doinstaluj albo docker-compose-plugin z repozytorium Dockera, albo, tylko na Ubuntu, docker-compose-v2 z dystrybucji.

E: Conflicting values set for option Signed-By regarding source https://download.docker.com/linux/debian/ trixie: /etc/apt/keyrings/docker.asc != /etc/apt/keyrings/docker.gpg
Klasyk po przerobieniu kilku poradników naraz: obok siebie istnieją stary /etc/apt/sources.list.d/docker.list i nowy docker.sources. Skasuj stary plik i powtórz sudo apt-get update. Ogólny obraz da ci ls -l /etc/apt/sources.list.d/.

The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 8D81803C0EBFCD88
Klucz nie leży tam, gdzie oczekuje go Signed-By, albo pobrany plik jest niekompletny (na przykład dlatego, że proxy podało stronę błędu w HTML). gpg --show-keys /etc/apt/keyrings/docker.asc od razu pokaże, czy w ogóle jest w nim jakiś klucz.

E: The repository 'https://download.docker.com/linux/debian trixie Release' does not have a Release file.
Nazwa kodowa nie pasuje do źródła. Zdarza się to na dystrybucjach pochodnych oraz wtedy, gdy miesza się poradniki dla Debiana i dla Ubuntu. Sprawdź wiersze URIs oraz Suitesdocker.sources.

Bind for 0.0.0.0:80 failed: port is already allocated
Port zajmuje inna usługa, często serwer WWW zainstalowany bezpośrednio w systemie. sudo ss -tulpn | grep :80 wskaże sprawcę.

Docker a firewall: słowo o bezpieczeństwie

Osobliwość, która na publicznie dostępnym serwerze potrafi drogo kosztować: Docker wpisuje swoje reguły przekierowań do tablicy NAT i omija w ten sposób reguły, które pielęgnujesz w ufw. Kontener uruchomiony z -p 5432:5432 jest osiągalny z internetu, nawet jeśli ufw status nigdzie nie zezwala na ten port. Obowiązuje to nadal, chociaż Docker Engine 28 ogólnie utwardził zachowanie sieciowe i zablokował dostęp z zewnątrz do portów nieopublikowanych.

Najprostszym i najpewniejszym środkiem zaradczym jest jawne przypięcie usług potrzebnych wyłącznie lokalnie do adresu loopback:

services:
  db:
    image: postgres:17
    ports:
      - "127.0.0.1:5432:5432"
    restart: unless-stopped

Jeszcze lepiej: w ogóle nie publikuj takich portów i pozwól kontenerom rozmawiać ze sobą przez wspólną sieć Dockera. Wynik najlepiej sprawdzić z drugiej maszyny, bo test z samego serwera nie odpowiada na decydujące pytanie.

Krótkie podsumowanie

Na Debianie 12 sięgnij zdecydowanie po Docker CE, na Ubuntu możesz wybierać między docker.io a Docker CE. Podepnij repozytorium z własnym keyringiem i sprawdzonym odciskiem palca, a nie przez apt-key. Używaj docker compose ze spacją. Traktuj grupę docker jak nadanie roota, bo dokładnie tym ona jest. I ustaw rotację logów oraz cotygodniowe zadanie prune, zanim serwer pierwszy raz padnie na zapełnionym dysku.

W tym samym temacie: konfiguracja firewalla UFW na Debianie i Ubuntu oraz instalacja Nginx na Debianie i Ubuntu.

Najczęstsze pytania

Mam zainstalować docker.io czy docker-ce?
Na Debianie 12 zdecydowanie Docker CE, bo pakiet z dystrybucji stoi tam na 20.10.24, a ta gałąź w upstreamie już się skończyła. Na Debianie 13 docker.io daje 26.1.5, a na Ubuntu 24.04 i 22.04 nawet 29.1.3, czyli praktycznie stan aktualny. Tam pakiet z dystrybucji jest wyborem uzasadnionym, o ile doinstalujesz osobno Buildx i Compose. Pakiet docker-compose-v2 istnieje jednak tylko w źródłach Ubuntu, w Debianie droga do Compose prowadzi przez docker-compose-plugin z repozytorium Dockera.
Dlaczego docker-compose z łącznikiem już nie działa?
Stare docker-compose było samodzielnym programem w Pythonie i nie jest już dostarczane. Następcą jest wtyczka Docker CLI napisana w Go, wywoływana jako docker compose ze spacją. Siedzi w pakiecie docker-compose-plugin (repozytorium Dockera) albo, tylko na Ubuntu, w docker-compose-v2 z dystrybucji. Sprawdzisz to poleceniem: docker compose version.
Czy grupa docker jest naprawdę tak groźna, jak się mówi?
Tak. Kto ma dostęp do socketu Dockera, może wydawać dowolne polecenia daemonowi pracującemu jako root, na przykład podmontować katalog główny hosta do kontenera i otworzyć w nim shell roota. Dokumentacja Dockera nazywa to wprost root-level privileges. Dopisuj do grupy tylko te konta, którym i tak powierzasz roota, albo korzystaj z trybu rootless.
Dlaczego docker info pokazuje u mnie overlayfs zamiast overlay2?
Od Docker Engine 29 przy nowych instalacjach domyślnie włączony jest magazyn obrazów containerd. Jego snapshotter nazywa się overlayfs. To poprawne i nie jest to błąd. Problematyczna byłaby dopiero wartość vfs, która wskazuje na brak wsparcia w kernelu i zużywa bardzo dużo miejsca na dysku.
Moje obrazy zniknęły po aktualizacji, czy zostały skasowane?
Z reguły nie. Przy przejściu między klasycznym magazynem obrazów a magazynem containerd zasoby drugiego składu są tylko ukrywane, dane zostają na dysku. Przełącz się testowo z powrotem przez features containerd-snapshotter w /etc/docker/daemon.json, a obrazy znów się pojawią.
Jak nie dopuścić, żeby logi kontenerów zapełniły dysk?
Sterownik json-file domyślnie nie rotuje plików. Wpisz w /etc/docker/daemon.json log-opts z max-size 10m i max-file 3, wartości muszą stać jako ciągi znaków w cudzysłowach. Po systemctl restart docker obowiązuje to tylko dla nowo utworzonych kontenerów, istniejące trzeba utworzyć od nowa przez docker compose up -d --force-recreate.
Czy docker system prune jest bezpieczny?
Bez przełączników w dużej mierze tak, usuwa zatrzymane kontenery, nieużywane sieci, obrazy bez nazwy i cache buildów. Przełącznik -a kasuje dodatkowo wszystkie obrazy, z których akurat nikt nie korzysta. Groźny jest --volumes, bo znikają wtedy nazwane wolumeny bez przypisanego kontenera, a więc być może twoja baza danych. W automatycznych zadaniach --volumes nie ma czego szukać.

Docker Docker Compose Debian Ubuntu Serwer Linux containerd apt Administracja serwerem