Modul 7 — Virtualizace a kontejnery: Docker

29. Docker základy: images, containers, Dockerfile

Základní pojmy Dockeru — image, kontejner, Dockerfile — a první praktické spuštění a sestavení vlastního image.

Odhadovaná délka studia: 55 minut · Stav: nehotovo

Technologie: Docker

Úvod a kontext

Minulá lekce vysvětlila princip kontejnerizace obecně; tato lekce se
zaměřuje na konkrétní nástroj, který kontejnerizaci zpřístupnil širokým
masám vývojářů a DevOps inženýrů: Docker. Docker není jediný
kontejnerový engine (existují i containerd, Podman a další), ale je
zdaleka nejrozšířenější a jeho pojmy a formát Dockerfile se staly
fakticky odvětvovým standardem. Tato lekce projde tři základní pojmy —
image, kontejner, Dockerfile — a ukáže první praktické kroky.

Teorie

Image

Image (obraz) je neměnný (immutable) balíček obsahující vše, co
aplikace potřebuje ke spuštění: samotný program, jeho závislosti,
knihovny, konfigurační soubory a metadata o tom, jak se má spustit.
Image se skládá z vrstev (layers) — každý krok při jeho sestavování
přidá jednu vrstvu, a vrstvy se mezi různými images sdílejí, pokud jsou
identické (to šetří místo na disku i čas při stahování).

Image se identifikuje jménem a tagem, např. nginx:1.25-alpine
nginx je jméno image, 1.25-alpine je tag označující konkrétní verzi
a variantu (zde: Nginx verze 1.25 postavený na minimalistické distribuci
Alpine Linux).

Kontejner

Kontejner je běžící (nebo zastavená, ale existující) instance image.
Vztah image ku kontejneru je podobný vztahu třídy a objektu v
objektově orientovaném programování — z jednoho image lze spustit
libovolný počet nezávislých kontejnerů, každý se svým vlastním stavem
(běžícími procesy, dočasnými soubory), ale se stejným výchozím obsahem
zděděným z image.

Kontejner má svůj životní cyklus: vytvořen → běží → zastaven → odstraněn.
Na rozdíl od image, který je needitovatelný, kontejner může za běhu měnit
svůj souborový systém (ale tyto změny se ztratí při jeho odstranění,
pokud nejsou explicitně uložené do tzv. volume — viz pozdější lekce).

Dockerfile

Dockerfile je textový soubor s instrukcemi, jak image sestavit —
obdoba receptu. Docker ho čte řádek po řádku a z každé instrukce vytvoří
jednu vrstvu image:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]

Klíčové instrukce:

  • FROM — základní image, na kterém ten nový staví (téměř každý
    Dockerfile začíná touto instrukcí),
  • WORKDIR — nastaví pracovní adresář uvnitř kontejneru pro následující
    instrukce,
  • COPY — zkopíruje soubory z hostitele (kontextu buildu) do image,
  • RUN — spustí příkaz při sestavování image (např. instalace
    závislostí) — výsledek se uloží jako nová vrstva,
  • CMD — příkaz, který se spustí, když se z image vytvoří a spustí
    kontejner (na rozdíl od RUN se nevykoná při sestavování).

Registry

Registry je server, kam se images ukládají a odkud se stahují —
obdoba repozitáře pro Git, ale pro images. Veřejný a nejpoužívanější je
Docker Hub, firmy si často provozují i vlastní privátní registry
(podrobněji v pozdější lekci).

Praktický příklad

Stažení a spuštění existujícího image z Docker Hubu:

docker pull nginx:alpine
docker run -d --name muj-nginx -p 8080:80 nginx:alpine
  • -d — spustí kontejner na pozadí (detached),
  • --name — pojmenuje kontejner pro snazší odkazování,
  • -p 8080:80 — namapuje port 80 uvnitř kontejneru na port 8080
    hostitele; nyní je server dostupný na http://localhost:8080.

Základní příkazy pro práci s běžícími kontejnery:

docker ps                  # seznam běžících kontejnerů
docker ps -a                # seznam všech kontejnerů (i zastavených)
docker logs muj-nginx        # výstup (logy) kontejneru
docker exec -it muj-nginx sh # interaktivní shell uvnitř běžícího kontejneru
docker stop muj-nginx        # zastavení kontejneru
docker rm muj-nginx           # odstranění zastaveného kontejneru

Sestavení vlastního image z minimální Python aplikace. Adresářová
struktura:

moje-appka/
├── Dockerfile
├── requirements.txt
└── app.py

app.py:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Ahoj z kontejneru!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

requirements.txt:

flask==3.0.0

Dockerfile (stejný jako výše v teoretické části). Sestavení a spuštění:

docker build -t moje-appka:1.0 .
docker run -d --name moje-appka -p 5000:5000 moje-appka:1.0
curl http://localhost:5000

docker build -t moje-appka:1.0 . sestaví image s tagem moje-appka:1.0
z Dockerfile v aktuálním adresáři (. je tzv. build context — adresář,
jehož obsah je dostupný instrukcím COPY/ADD).

Prohlédnutí seznamu images uložených lokálně a jejich odstranění:

docker images
docker rmi moje-appka:1.0

Shrnutí

Image je needitovatelný balíček aplikace složený z vrstev, kontejner je
jeho běžící instance a Dockerfile je recept, podle kterého Docker image
sestaví. Klíčové instrukce Dockerfile jsou FROM (základ), COPY
(kopírování souborů), RUN (příkaz při sestavování) a CMD (příkaz při
spuštění kontejneru). Základní pracovní cyklus je docker build
docker rundocker ps/docker logs pro kontrolu → docker stop/
docker rm pro úklid.

Kontrolní otázky

  1. Jaký je rozdíl mezi image a kontejnerem? Použijte analogii z
    objektově orientovaného programování.
  2. V čem se liší instrukce RUN a CMD v Dockerfile?
  3. K čemu slouží přepínač -p 8080:80 u příkazu docker run?
  4. Napište minimální Dockerfile pro jednoduchou Node.js aplikaci, která
    se spouští příkazem node server.js a poslouchá na portu 3000.

Lekce na sebe nejsou zamčené — libovolnou lekci můžete otevřít i označit jako hotovou v jakémkoliv pořadí.