Docker — Labor
Kestus: 4 tundi
Eeldused: Loeng antud (image ≠ konteiner, Dockerfile, build/run). Kui udu — tagasi loengusse. Siit edasi on ainult käed külge, teooriat ei korrata.
Keskkond: Docker seal kus töötad — kohalik (Docker Desktop / Engine), WSL, või server. Kood ja käsud VS Code'is. localhost = masin kus Docker jookseb.
Õpiväljundid
Selle labi lõpuks sa:
- Ehitad töötava image'i ja käivitad konteineri, ilma juhendisse piilumata
- Diagnoosid kolm tüüpilist Docker-viga nende veateate järgi (mitte pähe õpitult)
- Selgitad miks rebuild ei uuenda töötavat konteinerit — ja parandad selle
- Loed
docker ps/logsväljundit tõrkeotsinguks - Taastad puhta seisu pärast seda kui oled ise midagi katki teinud
Selle labi loogika: baas → katki → paranda → laienda → viga → taasta. Sa ei kopeeri valmis lahendust — sa ehitad, lõhud meelega, ja saad aru miks. Iga samm lisab ainult ühe tüki. Kui tahad tervet faili korraga kopeerida: see labi pole selleks.
Osa 1 · Baas — töötav image
Loo kaust ja mine sisse:
Loo fail Dockerfile (täpselt see nimi). See on ainus kord, kui näed tervet faili — edasi lisad ridu ühekaupa:
Ehita ja käivita:
Näed nginx tervituslehte. Baas töötab. Ära mine edasi enne kui see vastab.
Tip
Connection refused — kontrolli docker ps. Kui web1 pole seal, docker logs web1 ütleb miks.
Osa 2 · Katki — ja miks
Nüüd teed meelega vea, mille kõik teevad täpselt ühe korra. Lisa Dockerfile-i teine paketirida — aga jäta -y teadlikult ära:
Muuda keskmine rida selliseks (lisa curl install ilma -y-ta):
Ehita:
Vaata mis juhtub. Build peatub kohas, kus apt küsib Do you want to continue? [Y/n] — ja jääb toppama või katkeb, sest ehitamise ajal ei ole kedagi, kes vastaks.
Diagnoosi enne kui parandad
Miks töötab sama apt install nginx curl sinu enda terminalis, aga Docker build'is ripub? Mis vahe on interaktiivsel terminalil ja build-keskkonnal?
Paranda: pane -y tagasi. -y = "jah kõigele", sest build-keskkonnas pole inimest:
Läbib. See on reegel, mitte soovitus: Dockerfile'is apt install alati -y.
Osa 3 · Laienda — oma sisu image'isse
Baas serveerib nginx'i vaikimisi lehte. Paneme oma. Loo w05 kausta fail index.html:
Lisa Dockerfile-i üks uus rida, CMD ette (näita ainult uut rida, mitte tervet faili):
Ehita ja proovi vana konteineriga:
Ennusta enne vaatamist
Mida curl nüüd näitab — "Versioon 1", vana vaikimisi leht, või vea?
Näed ikka vana lehte. See pole viga — see on Osa 4.
Osa 4 · Rebuild ei uuenda konteinerit
Ehitasid uue image'i, aga curl näitab vana. Miks?
Diagnoosi:
docker ps näitab et web1 jookseb. docker images näitab et minu-nginx on äsja ehitatud (vaata CREATED). Kaks fakti, üks järeldus:
Miks?
web1 käivitati Osas 1, vanast image'ist. docker build tegi uue image'i, aga ei puutunud töötavat konteinerit. Konteiner on külmutatud hetk sellest image'ist, mis kehtis tema käivitamise ajal. Miks Docker seda ei uuenda automaatselt? (Vihje: kujuta et keegi ehitab katkise image'i reedel 16:55, ja kõik konteinerid tootmises uueneksid ise.)
Taasta õige seis:
Nüüd "Versioon 1". Jäta meelde see jada: stop → rm → run. Uus image ei jõua tootmisse ilma selleta.
Osa 5 · Port juba kinni
Proovi käivitada teine konteiner samast image'ist, sama pordiga:
Saad vea: port is already allocated.
Diagnoosi
web1 hoiab juba porti 8080. Kaks konteinerit ei saa jagada sama host-porti. Mis on lahendus, kui tahad mõlemat korraga jooksma? (Vihje: kumb number -p X:80-s on host-port?)
Paranda: anna web2-le teine host-port:
Nüüd jooksevad mõlemad — 8080 ja 8081, üks image, kaks konteinerit.
Osa 6 · Surnud konteiner
Muuda Dockerfile CMD rida selliseks (võta daemon off; ära):
Ehita ja käivita puhtalt:
web3 pole docker ps-is. Ta suri kohe.
Diagnoosi:
Miks?
Ilma daemon off; läheb nginx taustale ja põhiprotsess (PID 1) lõpeb kohe. Konteiner elab täpselt nii kaua kui elab tema põhiprotsess. Protsess lõppes → konteiner lõppes. Mis siis daemon off; teeb, et konteiner elus püsib?
Paranda: pane daemon off; tagasi, ehita, käivita. web3 jääb seekord püsti.
Osa 7 · Taasta puhas seis
Tegid sassi — kolm konteinerit, üks image. Koristame nagu päris elus:
Kontrolli et midagi ei jäänud rippuma, ja et image on alles:
Mõtle
Miks Docker nõuab enne konteineri kustutamist selle peatamist (stop enne rm)? Mis läheks valesti, kui rm tapaks jooksva konteineri kohe?
Tahad ka image'i minema:
Lõppkontroll — oskad ilma juhendita
- Ehitad töötava nginx image'i nullist, mälu järgi
- Selgitad miks
apt installvajab-yDockerfile'is (mitte lihtsalt "peab") - Kui rebuild "ei mõju", tead kohe et vaja stop → rm → run
-
port is already allocated— tead põhjust ja lahendust ilma googeldamata - Surnud konteiner —
docker logs+ PID 1 loogika -
docker ps -aon tühi kui pead selle tühjaks tegema
Lisaülesanded (kui jõuad ette)
docker exec: mine jooksvaweb1sisse (docker exec -it web1 bash), muuda/var/www/html/index.htmlkäsitsi.docker stop web1+docker start web1(mitte rm+run) — kas muudatus säilis?rm+run— kas säilis? Selgita vahet.--no-cache: ehitadocker build --no-cache -t minu-nginx .. Mis on aeglasem ja miks? Millal seda vaja?- Oma port konteineris: pane nginx kuulama porti 8000 konteineri sees (nõuab config-faili
COPY-t). Mis muutub-p-s?
Veaotsing
| Veateade | Põhjus | Lahendus |
|---|---|---|
Build ripub [Y/n] juures |
apt install ilma -y |
Lisa -y |
Connection refused |
-p puudub, või konteiner ei jookse |
docker ps, docker logs |
| Vana sisu pärast rebuild'i | Konteiner vanast image'ist | stop → rm → run |
port is already allocated |
Host-port kinni | Teine host-port -p vasakul |
| Konteiner sureb kohe | Põhiprotsess lõppes (nt daemon off; puudub) |
docker logs, paranda CMD |
image is being used |
Konteinerid veel olemas | Eemalda konteinerid enne rmi |
Tabel 5.1. Iga rida on viga, mille sa selles labis ise tekitasid ja parandasid.
Allikad
| Allikas | URL | Miks |
|---|---|---|
| Dockerfile reference | https://docs.docker.com/reference/dockerfile/ | Kõik käsud |
docker run |
https://docs.docker.com/reference/cli/docker/container/run/ | Lipud, pordid |
docker logs |
https://docs.docker.com/reference/cli/docker/container/logs/ | Tõrkeotsing |
| Play with Docker | https://labs.play-with-docker.com/ | Liivakast brauseris |