Docker: od instalace k vlastnímu image
Co je Docker Engine, proč na Linux VPS nepotřebujeme Docker Desktop a jak se image mění na běžící container.
Docker Desktop vs. Docker Engine
Windows
Linux VPS
Na VPS není potřeba Docker Desktop, protože Linuxové prostředí už je samotný hostitelský systém.
Docker stack
Runtime je vrstva, která skutečně realizuje běh containeru: připraví izolaci, filesystem, cgroups/namespaces a spustí proces.
Instalace Dockeru z oficiálního APT repozitáře
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
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin
TLS certifikáty chrání HTTPS spojení k repozitáři; GPG signing key zase umožňuje APT ověřit, že metadata/balíčky skutečně pocházejí od Dockeru a nebyly změněny.
Docker daemon jako systemd služba
systemctl status docker
Typický výstup ukáže:
Loaded: loaded (...; enabled)
Active: active (running)
Main PID: ... (dockerd)
CLI komunikuje s daemonem přes Unix socket:
/var/run/docker.sock
Oprávnění typicky:
srw-rw---- 1 root docker ... /var/run/docker.sock
Proto běžný uživatel bez členství ve skupině docker dostane
permission denied. Používali jsme tedy sudo docker ....
docker je prakticky root-equivalent oprávnění. Není to „nevinná“ skupina.
Image vs. container
Image
Neměnná šablona/layered artefakt. Vzniká buildem a může být základem mnoha containerů.
Container
Konkrétní běžící nebo zastavená instance image. Má svůj proces, síť a writable vrstvu.
sudo docker run hello-world
sudo docker images
sudo docker ps
sudo docker ps -a
docker run nejprve hledá image lokálně. Když není, stáhne ho z výchozího registry (Docker Hub),
vytvoří container a spustí jeho hlavní proces.
Port mapping
sudo docker run --name docker-nginx -p 8080:80 -d nginx
-p HOST_PORT:CONTAINER_PORT.
Výchozí publikace znamená typicky všechna rozhraní:
0.0.0.0:8080 → container:80
Pro backend za reverse proxy jsme port schovali jen na localhost:
sudo docker run --name docker-nginx \
-p 127.0.0.1:8080:80 \
-d nginx
Vlastní Dockerfile a build
FROM nginx:latest
COPY index.html /usr/share/nginx/html/index.html
sudo docker build -t docker-static:v1 .
Tečka je build context. Docker má při buildu k dispozici soubory z aktuálního adresáře.
Proto jsme přidali:
# .dockerignore
.git
.dockerignore říká Dockeru, co nemá posílat do build contextu.
Není to totéž co .gitignore.
Build image – pozor na poslední tečku
sudo docker build -t docker-tahak:v1 .
Příkaz se skládá z několika částí:
| Část | Význam |
|---|---|
sudo |
Docker socket zatím používáme s root oprávněním. |
docker build |
Sestav nový Docker image. |
-t docker-tahak:v1 |
Dej image jméno docker-tahak a tag v1. |
. |
Build context je aktuální adresář. |
. zapomeneme, Docker neví,
odkud má vzít Dockerfile a ostatní soubory.
Typická chyba:
docker buildx build requires 1 argument
Docker tím říká, že chybí PATH, URL nebo jiný build context.
Co přesně znamená build context?
Máme například:
docker-vps-tahak/
├── Dockerfile
├── README.md
└── site/
├── index.html
├── docker.html
└── assets/
└── style.css
A Dockerfile:
FROM nginx:latest
COPY site/ /usr/share/nginx/html/
Díky tečce na konci docker build ... . dostane Docker
přístup k adresáři site/ a může jej při buildu zkopírovat.
Spuštění containeru: jméno containeru není jméno image
sudo docker run \
--name docker-tahak \
--restart unless-stopped \
-p 127.0.0.1:8081:80 \
-d \
docker-tahak:v1
Tady jsou dvě různá jména, která se snadno pletou:
--name docker-tahak
↑
jméno nového CONTAINERU
docker-tahak:v1
↑
IMAGE, ze kterého container vytvoříme
Když omylem napíšeme:
sudo docker run --name docker-tahak ... nginx
vznikne sice container jménem docker-tahak,
ale bude vytvořen z image nginx:latest.
Náš vlastní web v něm nebude.
Port mapping
-p 127.0.0.1:8081:80
Čte se zleva doprava:
Port 8081 tedy není port nginxu uvnitř containeru.
Nginx v containeru pořád poslouchá na portu 80.
8081 je pouze port na hostitelském VPS,
který Docker překládá na port 80 containeru.
Proč nefunguje veřejná IP na portu 8081?
http://PUBLIC_VPS_IP:8081
Protože jsme port navázali pouze na:
127.0.0.1:8081
127.0.0.1 je loopback – spojení dostupné pouze
uvnitř samotného VPS.
To je záměr. Veřejnost má komunikovat se systémovým nginxem, nikoli přímo s backend containerem.
Docker Compose
Compose je deklarativní popis celého prostředí. Hodí se ve chvíli, kdy máme více služeb: například web + databázi + Redis.
services:
web:
image: moje-app
ports:
- "8080:8000"
db:
image: postgres
docker compose up -d
Dockerfile odpovídá hlavně na „jak sestavit image?“. Compose odpovídá na „jak mají spolu běžet jednotlivé služby?“.