Instalacja Dockera i pierwszy kontener
Moduł 9: Docker i docker compose · Czas czytania: 11 min
Cel lekcji: Po tej lekcji potrafią Państwo zainstalować Docker Engine z oficjalnego repozytorium pakietów, uruchamiać, przeglądać, zaglądać do środka i usuwać kontenery, a także wiedzą Państwo, dlaczego grupa docker jest równoznaczna z rootem.
Kluczowe pojęcia: Docker Engine, Docker Desktop, oficjalne repozytorium apt, docker.io z Debiana, grupa docker, rootless mode, docker run, -d, -p, -v, --name, docker ps, docker logs, docker exec, docker stop, docker rm, docker image prune, docker system df
Który Docker?
Na serwerze instalują Państwo Docker Engine: usługę działającą w tle (dockerd) oraz polecenie docker. Docker Desktop to coś innego: program z oknami dla Windows, macOS i desktopów Linux. Nie należy go instalować na serwerze.
Istnieją dwa porządne źródła Docker Engine:
- Repozytorium pakietów samego Dockera (
download.docker.com). Zawsze najnowsza wersja, łącznie z wtyczkądocker compose, której użyją Państwo w lekcji 9.3. Tę metodę opisuje dokumentacja Dockera i z niej korzysta ten kurs. - Pakiet
docker.ioz Debiana lub Ubuntu. Starszy, ale aktualizowany przez dystrybucję w ramach zwykłych aktualizacji bezpieczeństwa (lekcja 4.2). Dobry wybór, jeśli wolą Państwo nie mieć niczego spoza dystrybucji; proszę jednak sprawdzić, czy dostępne jestdocker compose(ze spacją).
Prosimy wybrać jedno z nich. Instalowanie obu naraz powoduje konflikty; dlatego dokumentacja Dockera zaleca najpierw usunąć nieoficjalne pakiety, takie jak docker.io, docker-compose i podman-docker.
Instalacja z repozytorium pakietów Dockera
Oto kroki z dokumentacji Dockera dla Debiana, z osobnym kluczem i własnym Signed-By (lekcja 4.1). Jeśli Państwo chcą, proszę najpierw wykonać snapshot.
anna@web1:~$ sudo apt update
anna@web1:~$ sudo apt install ca-certificates curl
anna@web1:~$ sudo install -m 0755 -d /etc/apt/keyrings
anna@web1:~$ sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
anna@web1:~$ sudo chmod a+r /etc/apt/keyrings/docker.ascNastępnie plik źródła /etc/apt/sources.list.d/docker.sources (w formacie deb822):
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: trixie
Components: stable
Architectures: amd64
Signed-By: /etc/apt/keyrings/docker.ascW polu Suites wpisują Państwo nazwę kodową swojego wydania (cat /etc/os-release, lekcja 4.3), a w polu Architectures wynik polecenia dpkg --print-architecture. Na Ubuntu adres URL to https://download.docker.com/linux/ubuntu, a suite to na przykład noble.
Teraz instalacja:
anna@web1:~$ sudo apt update
anna@web1:~$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
anna@web1:~$ sudo docker run hello-world
...
Hello from Docker!
This message shows that your installation appears to be working correctly.Na Debianie i Ubuntu Docker uruchamia się automatycznie po instalacji, a także po każdym restarcie (systemctl status docker, lekcja 6.1).
Uwaga: unattended-upgrades (lekcja 4.2) domyślnie nie aktualizuje automatycznie pakietów z tego źródła. Prosimy uwzględnić sudo apt update && sudo apt upgrade dla Dockera w swoim harmonogramie konserwacji (lekcja 10.4) albo świadomie dodać to źródło do automatycznych aktualizacji.
Grupa docker to root
W całym internecie można przeczytać, że należy dodać siebie do grupy docker, aby nie trzeba było już wpisywać sudo:
anna@web1:~$ sudo usermod -aG docker annaProsimy robić to tylko wtedy, gdy rozumieją Państwo, co to oznacza. Dokumentacja Dockera mówi o tym jasno: grupa docker daje uprawnienia na poziomie roota. Kto może sterować usługą Dockera, może uruchomić kontener z podłączonym całym dyskiem hosta:
docker run -it -v /:/host debian chroot /hosti tym samym jest rootem na Państwa serwerze, bez hasła i bez wpisu w logu sudo. Dokumentacja Dockera ujmuje to tak: tylko zaufani użytkownicy powinni mieć możliwość sterowania usługą Dockera.
W przypadku serwera, którym administrują Państwo wyłącznie sami, to kwestia wyboru: wygoda kontra dodatkowa droga do roota. Bezpieczniej jest po prostu dalej wpisywać sudo docker ...; wtedy każde polecenie trafia do logu sudo (lekcja 3.2). W żadnym wypadku prosimy nie dodawać do tej grupy użytkownika, który nie powinien być rootem, na przykład użytkownika usługi dla strony internetowej.
Rootless mode
Docker może też działać bez roota: usługa i kontenery działają wtedy jako zwykły użytkownik, z własną przestrzenią nazw użytkowników (user namespace). Instalują go Państwo jako ten użytkownik za pomocą dockerd-rootless-setuptool.sh install (z pakietu docker-ce-rootless-extras; wcześniej potrzebny jest pakiet uidmap). Luka w kontenerze nie daje wtedy uprawnień roota na hoście. Istnieją jednak ograniczenia, a konfiguracja jest trudniejsza; w tym kursie korzystamy ze zwykłej instalacji i dbamy o bezpieczeństwo, stosując zasady z tego modułu.
Pierwszy prawdziwy kontener
Uruchamiamy serwer WWW nginx w kontenerze, dostępny tylko z samego serwera:
anna@web1:~$ sudo docker run -d --name proef -p 127.0.0.1:8080:80 nginx:stable
Unable to find image 'nginx:stable' locally
stable: Pulling from library/nginx
...
3f1c9e0d7a2b...Poszczególne elementy:
| Element | Znaczenie |
|---|---|
-d | Działanie w tle (detached) |
--name proef | Nazwa, dzięki której nie trzeba posługiwać się długimi identyfikatorami |
-p 127.0.0.1:8080:80 | Port 80 w kontenerze staje się portem 8080 na hoście, tylko na loopback |
nginx:stable | Oficjalny obraz nginx, tag stable |
Sprawdzenie:
anna@web1:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
3f1c9e0d7a2b nginx:stable "/docker-entrypoint.…" Up 5 seconds 127.0.0.1:8080->80/tcp proef
anna@web1:~$ curl -I http://127.0.0.1:8080
HTTP/1.1 200 OK
Server: nginx/1.28.0
anna@web1:~$ sudo ss -tlnp | grep 8080
LISTEN 0 4096 127.0.0.1:8080 0.0.0.0:* users:(("docker-proxy",pid=2211,fd=7))ss (lekcja 5.1) potwierdza: tylko na 127.0.0.1. Gdyby Państwo wpisali -p 8080:80, pojawiłoby się 0.0.0.0:8080 i [::]:8080, a kontener byłby dostępny z internetu, nawet jeśli ufw nie przepuszcza portu 8080 (lekcja 9.3). Wersja w nagłówku Server może się u Państwa różnić.
Rozglądanie się i interwencja
anna@web1:~$ sudo docker logs proef # co wypisał program (stdout i stderr)
anna@web1:~$ sudo docker logs -f --tail 20 proef # ostatnie 20 wierszy i dalsze śledzenie
anna@web1:~$ sudo docker exec -it proef sh # powłoka w działającym kontenerze
# cat /etc/os-release
# exit
anna@web1:~$ sudo docker stop proef
anna@web1:~$ sudo docker start proef
anna@web1:~$ sudo docker rm -f proef # zatrzymaj i usuńdocker logs to pierwsze miejsce, do którego warto zajrzeć, gdy kontener nie działa zgodnie z oczekiwaniami, podobnie jak journalctl w przypadku zwykłych usług (lekcja 6.2). Za pomocą docker exec mogą Państwo zajrzeć do środka, ale lepiej niczego tam nie zmieniać: zmiany w kontenerze znikają przy następnej aktualizacji (lekcja 9.1).
Sprzątanie
Obrazy i zatrzymane kontenery pozostają, dopóki ich Państwo nie usuną. Na VPS z małym dyskiem zajmowane miejsce rośnie niepostrzeżenie.
anna@web1:~$ sudo docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 7 3 1.9GB 1.2GB (63%)
Containers 3 3 12MB 0B (0%)
Local Volumes 2 2 180MB 0B (0%)
Build Cache 0 0 0B 0B
anna@web1:~$ sudo docker image prunedocker image prune usuwa obrazy bez nazwy, które nie są już z niczym powiązane; z opcją -a również wszystkie obrazy, których nie używa żaden kontener. Prosimy zachować ostrożność z docker system prune --volumes: usuwa ono także anonimowe wolumeny (bez nazwy), które w danej chwili nie należą do żadnego kontenera, a docker volume prune -a nawet wolumeny z nazwą. Mogą się w nich znajdować Państwa dane. Dlatego zawsze nadawajcie Państwo wolumenom nazwy lub używajcie bind mount (lekcja 9.1), a najpierw sprawdźcie stan za pomocą docker volume ls.
Logi kontenerów również mogą rosnąć. Docker domyślnie przechowuje je w plikach JSON bez limitu rozmiaru. Limit ustawiają Państwo w /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" }
}Następnie sudo systemctl restart docker; ustawienie dotyczy tylko nowo utworzonych kontenerów, istniejące kontenery trzeba utworzyć ponownie.
W praktyce
Docker na VPS w WebOké działa tak samo jak u każdego innego dostawcy: to oprogramowanie wewnątrz Państwa własnego serwera, które instalują i aktualizują Państwo samodzielnie. Na małym VPS prosimy regularnie sprawdzać wolne miejsce na dysku za pomocą docker system df i df -h (lekcja 1.4).
Podsumowanie
- Prosimy instalować Docker Engine z repozytorium pakietów Dockera (z własnym kluczem i
Signed-By) albodocker.ioz dystrybucji, nie oba naraz. - Grupa docker jest równoznaczna z rootem;
sudo dockerzostawia ślad w logu sudo. Rootless mode to bezpieczniejsza, ale bardziej ograniczona alternatywa. docker run -d --name ... -p 127.0.0.1:host:container image:taguruchamia kontener dostępny tylko lokalnie; sprawdzenie za pomocąss.docker ps,logs,exec,stop,rmto Państwa codzienne narzędzia.- Prosimy usuwać obrazy za pomocą
docker image prune, ograniczać logi kontenerów (domyślnie bez limitu) i oszczędnie używać--volumes.
Quiz
Zadanie
Zadanie O9.2: Państwa pierwszy kontener. Prosimy zainstalować Docker Engine na swoim serwerze zgodnie z lekcją (lub na maszynie testowej). Proszę uruchomić kontener nginx nasłuchujący tylko na 127.0.0.1:8080, sprawdzić go za pomocą docker ps, curl -I i ss -tlnp, przejrzeć logi, a następnie go usunąć. Prosimy odpowiedzieć na pytania: z jakiego źródła zainstalowali Państwo Dockera, co pokazało ss dla portu 8080 i czy dodali Państwo siebie do grupy docker (dlaczego tak lub dlaczego nie)?
Zadanie O9.2: Państwa pierwszy kontener
To zadanie wykonuje się samodzielnie, nikt go nie sprawdza. Prosimy zaznaczyć wykonane punkty i oznaczyć zadanie jako wykonane.
Gdy Docker pochodzi z repozytorium Dockera, unattended-upgrades domyślnie go nie aktualizuje; docker.io z dystrybucji już tak. ss powinien pokazać 127.0.0.1:8080, a nie 0.0.0.0:8080. Grupa docker daje uprawnienia roota; przy sudo docker każde polecenie zostaje zapisane w logu sudo.
Zaznaczenia i notatki pozostają tylko w tej przeglądarce; nie są nigdzie wysyłane. Po zalogowaniu w Moje kursy zapisywana jest jedynie informacja, że zadanie zostało wykonane.
Przeczytaj więcej
- Dokumentacja Dockera, Install Docker Engine on Debian: https://docs.docker.com/engine/install/debian/
- Dokumentacja Dockera, Install Docker Engine on Ubuntu: https://docs.docker.com/engine/install/ubuntu/
- Dokumentacja Dockera, Linux post-installation steps: https://docs.docker.com/engine/install/linux-postinstall/
- Dokumentacja Dockera, Docker security (Docker daemon attack surface): https://docs.docker.com/engine/security/
- Dokumentacja Dockera, Rootless mode: https://docs.docker.com/engine/security/rootless/
- Dokumentacja Dockera, JSON File logging driver: https://docs.docker.com/engine/logging/drivers/json-file/
