01 - Konténerizáció¶
Cél¶
A labor célja megismerni a Docker konténerek használatának alapjait és a leggyakrabban használt Docker CLI parancsokat.
Előkövetelmények¶
- A házi leírásban Windows platformot használunk, azonban a feladatok Linuxon és Mac-en is megoldhatóak (a könyvtár elérési útvonalakat megfelelően átírva).
- Docker Hub login
-
Docker Desktop
Warning
Más kiépítések, telepítési formák is elérhetőek (pl. Docker Engine), de a Docker Desktop tartalmaz minden eszközt, amire szükségünk lehet. Például
docker init
csak a Docker Desktop-ban van. -
Az opcionális feladathoz .NET 8 SDK. Ha van fent friss Visual Studio, akkor általában nem kell külön feltenni. Tesztelheted így
- Microsoft Visual Studio Code
- Javasolt: Docker extension
- Alap Linux parancsok ismerete. Érdemes átnézni pl.:
Előkészület¶
A feladatok megoldása során ne felejtsd el követni a feladat beadás folyamatát GitHub.
Git repository létrehozása és letöltése¶
- Moodle-ben keresd meg a laborhoz tartozó meghívó URL-jét és annak segítségével hozd létre a saját repository-dat.
- Várd meg, míg elkészül a repository, majd checkout-old ki.
- Hozz létre egy új ágat
megoldas
néven, és ezen az ágon dolgozz. - A
neptun.txt
fájlba írd bele a Neptun kódodat. A fájlban semmi más ne szerepeljen, csak egyetlen sorban a Neptun kód 6 karaktere.
NEPTUN
A példákban a neptun
helyett a saját neptunkódunkat helyettesítsük be. Ha neptun-ként látod, akkor kisbetűvel írd; ha NEPTUN-ként, akkor nagybetűvel
0. Feladat¶
Docker hello world¶
Teszteljük a Docker telepítésünket a hello-world
image futtatásával.
Nyissunk egy konzolt, és adjuk ki a következő parancsokat. Ezzel ellenőrizhetjük, hogy a docker CLI elérhető-e.
docker --version
Futtassunk egy egyszerű előre elkészített konténert, ami kiír egy példa szöveget a konzolra. Fontos, hogy a telepített Docker Desktop fusson a háttérben!
docker run hello-world
- hello-word az image neve: https://hub.docker.com/_/hello-world
- Image letöltődik, elindul, lefut a benne leírt program.
Konténer futtatása interaktív módon¶
-
Futtassunk egy natúr
ubuntu
konténert interaktív módon (-it
kapcsolóval), így a futó konténerben egy shell-en keresztül tudunk tetszőleges parancsokat futtatni.docker run -it ubuntu
-
Nézzük meg a fájlrendszert:
ls
-
Lépjünk ki az interaktív shell-ből:
exit
Konténer terminált, mert a bash folyamat megállt az
exit
hatására. Konténer addig fut, amíg a benne levő alkalmazás (folyamat) fut. Leállt konténer nem törlődik automatikusan, tartalma nem veszik el. -
Listázzuk ki a konténereinket:
docker ps -a
Nézzük meg a parancs eredményét. Keressük meg a konténerek id-ját.
-
Távolítsuk el a két konténert, amit mi indítottunk:
docker rm <id1|name> <id2|name>
Tip
ID helyett a konténer nevét is megadhatjuk. Az automatikusan generált nevek helyett pedig a
run
parancs--name
kapcsolójával adhatunk nevet a konténernek.
Gyakoribb Docker parancsok
- Adjuk ki a
docker
parancsot a help-hez. - Adminisztratív parancsok: mivel mit, pl.
docker image ls
- Kezelő parancsok: parancs argumentumok, pl.
docker rmi <id>
- Gyakran használtak:
- Konténerek kezelése
docker container ls [-all]
vagydocker ps [-a]
docker run [opciók] <image>
docker stop <id>
docker rm <id>
- Image-ek kezelése
docker pull <image>
docker image ls
vagydocker images
docker rmi <image>
docker tag <id> <tag>
- Konkrét parancshoz segítség:
docker <parancs> --help
- Minden konténer (futók is!) eltávolítása:
docker rm -f $(docker ps -aq)
GUI vs CLI
A Dockerhez már nagyon sok hasznos GUI-val rendelkező eszköz létezik, amik nagyban megkönnyítik a fejlesztők életét. A labor viszont elsősorban konzolos használatra fókuszál, mert az a leguniverzálisabb és a GUI-s eszközök is valójában az itt elérhető funkciókra építenek. A labor elvégzése során ha kényelmesebb nyugodtan használd a számodra kényelmesebb eszközt.
- Docker Desktop felülete
- VS Code Docker extension
- Visual Studio Container Tools ablak
1. Feladat¶
1.1 Volume csatolása (bind mount)¶
Gyakran szeretnénk a host gépről elérni a konténerben lévő fájlokat, vagy éppen a konténerben lévő fájlokat szeretnénk a host gépen tárolni. Erre megoldás a volume csatolás, amikor a host gép egy könyvtárát csatoljuk a konténerbe.
-
Hozzunk létre egy munkakönyvtárat tetszőleges helyen a neptun kódunkkal, például
c:\work\neptun
(windows)~/work/neptun
(linux) -
Indítsunk el egy konténert úgy, hogy ezt a könyvtárat felcsatoljuk a
-v
kapcsolóval:Windowsdocker run -it --rm -v c:\work\neptun:/neptun ubuntu
Linuxdocker run -it --rm -v ~/work/neptun:/neptun ubuntu
Szintaktika: helyi teljes elérési útvonal kettőspont konténeren belüli teljes elérési útvonal
-
Konténeren belül listázzuk ki a könyvtárat:
ls
Látjuk a
/neptun
könyvtárat -
Írjunk bele:
echo "hello NEPTUN" > /neptun/hello.txt
-
írjuk ki a tartalmát:
cat /neptun/hello.txt
-
Lépjünk ki a konténerből:
exit
-
Nézzük meg a munkakönyvtárunkat.
--rm
A docker run
--rm
opciója törli a konténert leállás után; pl. teszteléshez hasznos, mint most.
BEADANDÓ
Készíts egy képernyőképet (f1.1.png) és commitold azt be a házi feladat repó gyökerébe, amin a fenti Volume csatolás feladatok parancsainak eredményei láthatóak.
1.2 Port mappelés¶
Docker konténerek esetében gyakran webalkalmazásokat futtatunk, amiket a host gépről szeretnénk elérni. Ezt a port mappeléssel érhetjük el, ahol a host gép egy portját mappeljük a konténer egy portjára.
-
Indítsunk el egy nginx webszervert tartalmazó konténert:
docker run -d -p 8085:80 nginx
-d
(detach): háttérben fut, a konzolt "visszakapjuk", amint elindult a konténer, és kiírja az image id-t-p
(port): helyi port kettőspont konténeren belüli port
-
Nyissuk meg böngészőben a címet a neptun kódunkkal: http://localhost:8085/index.html?student=NEPTUN
-
Nézzük meg a konténer logjait:
docker logs <id|name>
-
Állítsuk le a konténert:
docker stop <id|name>
BEADANDÓ
Készíts egy képernyőképet (f1.2.png) és commitold azt be a házi feladat repó gyökerébe, amin a fenti webcím megnyitásának a logjai látszódnak. Emeld ki a képen a releváns logbejegyzést (pl.: karikázd be vagy sárga kiemelevőlvel színezd.)
1.3 Műveletvégzés futó konténerben¶
Gyakran már egy futó konténerben szeretnénk műveleteket végezni, pl. fájlokat nézni, módosítani, stb.
Ehhez a docker exec
és docker cp
parancsot használjuk most.
-
Indítsunk el egy nginx webszervert:
docker run -d -p 8085:80 nginx
Jegyezzük meg a kiírt konténer id-t, alább használni fogjuk. (A kiírt karakterlánc első 12 karaktere jelöli az ID-t.)
-
Futtassunk le egy parancsot a konténerben:
docker exec <id|name> ls /
A parancs kilistázta a konténer fájlrendszerének gyökerét.
-
Kérhetünk egy shell-t is a konténerbe ily módon:
docker exec -it <id|name> /bin/bash
- Az
-it
opció az interaktivitásra utal, azaz a konzolunkat "hozzáköti" a konténerben futó shellhez. - Tipikusan vagy
/bin/bash
vagy/bin/sh
a Linux konténerekben a shell. Utóbbi az alpine alapú konténerekben gyakori. - Ebben az interaktív shell-ben bármit csinálhatunk, beléphetünk könyvtárakba, megnézhetünk fájlokat, stb. Arra viszont ügyeljünk, hogy az így végzett módosításaink elvesznek, amikor a konténer törlésre kerül!
- Az
-
Például nézzük meg az nginx konfigurációját:
cat /etc/nginx/conf.d/default.conf
-
Módosítsuk az
index.html
-t a következő módon:echo "hello NEPTUN from nginx" > /usr/share/nginx/html/index.html
-
Nyissuk meg böngészőben ezt a címet: http://localhost:8085/index.html és ellenőrizzük, hogy a módosított tartalom látszik-e.
-
Lépjünk ki az
exit
utasítással. Ez csak a "második" shellt állítja le, a konténer még fut, mert az eredeti indítási pont is még fut. -
Ha szükségünk van egy fájlra, akkor azt kimásolhatjuk a futó konténerből:
Windowsdocker cp <id|name>:/etc/nginx/conf.d/default.conf c:\work\neptun\nginx.conf
Linuxdocker cp <id|name>:/etc/nginx/conf.d/default.conf ~/work/neptun/nginx.conf
- Szintaktikája:
docker cp <id|name>:</full/path> <cél/hely>
- A másolás az ellenkező irányba is működik, helyi gépről a konténerbe.
- Szintaktikája:
-
Állítsuk le és töröljük a konténert.
docker stop <id|name> docker rm <id|name>
BEADANDÓ
Készíts egy képernyőképet (f1.3.png) és commitold azt be a házi feladat repó gyökerébe, amin a fenti weboldal látszik a böngészőben.
2. Feladat¶
2.1 Image készítése parancssorból¶
Docker registry
Korábban használt parancs: docker run ubuntu
Az ubuntu az image neve. Ez egy ún. registry-ből jön, analóg más csomagkezelőkhöz pl.: NPM, NuGet stb.
Az alapértelmezett registry a https://hub.docker.com, ahol tipikusan open-source szoftverek image-ei és az általunk is használt alap image-ek találhatóak.
Léteznek természetesen továbbiak is (Azure, Google, stb.).
Az image neve valójában nem ubuntu
, hanem index.docker.io/ubuntu:latest
index.docker.io
registry szerver elérési útvonalaubuntu
image neve (lehet többszintű is):latest
tag neve
Jogosultság szempontból két fajta registry létezhet: publikus (pl. Docker Hub) és privát. Privát registry esetén docker login <url>
és docker logout <url>
szükséges az authentikációhoz.
Letöltés a registry-ből: docker pull mcr.microsoft.com/dotnet/aspnet:8.0
Ugyan a run parancs is letölti, de csak akkor, ha még nem létezik. Nem ellenőrzi viszont, hogy nincs-e újabb image verzió publikálva. A pull mindig frisset szed le.
Készítünk egy saját image-et, ami egy módosított nginx
image-et fog tartalmazni a saját tartalmunkkal.
Ehhez az előző feladatban lévő lépéseket kell ismét elvégezned, de most ne lépj ki a konténerből, hanem a konténer állapotát mentsd egy új image-be, ami az nginx-re épít, és egy új image layer-t tartalmaz a saját tartalmunkkal.
-
Az előző feladat alapján futtass egy nginx konténert, amiben módosítod az
index.html
tartalmát. -
Készíts egy pillanatmentést a konténer jelenlegi állapotáról:
docker commit <id|name>
-
Állítsd le a háttérben futó konténert:
docker stop <id|name>
-
Az előbbi parancs készített egy image-et, aminek kiírta a hash-ét. Ellenőrizd, hogy tényleg létezik-e ez az image:
docker images
-
Taggeld meg az image-et:
docker tag <imageid> nginx-neptun
Warning
Itt már az image id-ja kell az images listából!
-
Indíts el egy új konténert az előbb létrehozott saját image-ből:
docker run -it --rm -p 8086:80 nginx-neptun
Warning
A portszám szándékosan más, hogy biztosan legyünk benne, nem a korábban futóhoz csatlakozunk - ha mégsem állítottuk volna azt le.
-
Nyisd meg böngészőből a http://localhost:8086 címet. Látható, hogy ez a módosított tartalmat jeleníti meg. Tehát
nginx-neptun
néven létrehoztunk egy saját image-et.
BEADANDÓ
Készíts egy képernyőképet (f2.1.png) és commitold azt be a házi feladat repó gyökerébe, amin a fenti weboldal látszik a böngészőben és a konténert futtató parancs a terminálban és annak a logjai.
Takarítás
Fejlesztés közben sok ideiglenes image keletkezik, és konténereket hagyunk hátra. Add ki a következő parancsot a nem futó konténerek törléséhez és az ideiglenes (címke nélküli) image-ek törléséhez:
docker system prune
2.2 Dockerfile¶
Az előző feladatban az image készítését manuálisan végeztük el, ami nem jól verziózható, és reprodukálhatósági problémákat okozhat.
Készítsünk egy egyszerű webalkalmazás Pythonban a Flask nevű keretrendszerrel, ami egy REST végpontot definiál és szolgál ki. Az adatokat (egy számláló) Redis adatbázisból olvassa és írja, és egy üdvözlő üzenetet ad vissza környezeti változó alapján.
-
Nyisd meg a házi repositorydat Visual Studio Code-ban.
-
Készíts a repository mappájába egy almappát
pythonweb
néven. A továbbiakban ennek a kontextusában dolgozz. -
Készíts egy
app.py
fájlt az alábbi tartalommal.from flask import Flask from redis import Redis, RedisError import os import socket # Connect to Redis redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2) app = Flask(__name__) # root endpoint # inrements and returns the number of visits from Redis # and says hello to the user from the NAME environment variable @app.route("/") def hello(): try: visits = redis.incr("counter") except RedisError: visits = "<i>cannot connect to Redis, counter disabled</i>" html = "<h3>Hello {name}!</h3><b>Visits:</b> {visits}" return html.format(name=os.getenv("NAME", "world"), visits=visits) if __name__ == "__main__": app.run(host='0.0.0.0', port=80)
-
Készíts egy
requirements.txt
fájlt az alábbi tartalommal, ami a Python alkalmazásunk függőségeit tartalmazza.Flask Redis
-
Készíts egy
Dockerfile
nevű fájt (kiterjesztés nélkül!) az alábbi tartalommal. A Dockerfile egy szöveges fájl, ami tartalmazza az image létrehozásának lépéseit, mint egy recept.FROM python:3.12-slim WORKDIR /app COPY . /app RUN pip install --trusted-host pypi.python.org -r requirements.txt EXPOSE 80 # Ide a saját Neptun kódodat írd ENV NAME=NEPTUN CMD ["python", "app.py"]
-
Készítsd el a fenti fájlokból az image-et. Konzolból a munkakönyvtárban add ki a következő parancsot:
docker build -t python-neptun:v1 .
Ez a parancs létrehoz egy image-et a Dockerfile alapján. A végén egy pont van, az is a parancs része, ami a build kontextust jelenti.
A Dockerfile lépései:
FROM
: az alap image, amire építjük a sajátunkat. Mi most a Python 3.12-slim image-et használjuk.WORKDIR
: a konténerben a munkakönyvtár, a további műveletek ebben a könyvtárban lesznek.COPY
: a host gépről a konténerbe másoljuk a fájlokat. A.
jelenti a build kontextus mappáját, esetünkben apythonweb
mappát.RUN
: a build/image készítés során lefuttatandó parancsok. Itt arequirements.txt
fájlban felsorolt Python csomagokat telepítjük a python csomagkezelővel (pip).EXPOSE
: a konténer által kiajánlott portokat jelzi. Mi most webalkalmazást készítünk, ezért a 80-as portot jelöljük ki.ENV
: környezeti változó beállítása. ANAME
környezeti változó értéke a saját Neptun kódod legyen.CMD
: a konténer indításakor lefuttatandó parancs és argumentumai. Ebben az esetben a Python alkalmazásunkat indítjuk el.
-
Ellenőrizd, hogy tényleg létrejött-e az image.
-
Indíts el egy új konténert ebből az image-ből:
docker run -it --rm -p 8085:80 python-neptun:v1
-
Nyisd meg böngészőben a http://localhost:8085 oldalt.
A weboldal ki kell írja a neptun kódodat, és egy hibaüzenetet a Redis-szel kapcsolatban.
BEADANDÓ
Készíts egy képernyőképet (f2.2.png) és commitold azt be a házi feladat repó gyökerébe, amin a fenti weboldal látszik a böngészőben és a konténer futtatás parancsa és logjai.
Kitekintés: Dockerignore és build kontextus
A Dockerfile
-ban hivatkoztunk az aktuális könyvtárra a .
-tal. Vizsgáljuk meg, hogy ez mit is jelent.
-
Készítsünk az aktuális könyvtárunkba, az
app.py
mellé egy nagy fájlt. Ehhez PowerShell-ben adjuk ki a következő parancsot.Windows - powershell$out = new-object byte[] 134217728; (new-object Random).NextBytes($out); [IO.File]::WriteAllBytes("$pwd\file.bin", $out)
Linux - bashdd if=/dev/urandom of=./file.bin bs=1M count=1024
-
Buildeljük le ismét a fenti image-et:
docker build -t python-neptun:v1 .
Menet közben látni fogjuk a következő sort a build logban: Sending build context to Docker daemon 111.4MB, és azt is tapasztalni fogjuk, hogy ez el tart egy kis ideig.
A
docker build
parancs végén a.
az aktuális könyvtár. Ezzel tudatjuk a Docker-rel, hogy a buildeléshez ezt a kontextust használja, azon fájlok legyenek elérhetőek a build során, amelyek ebben a kontextusban vannak. ADockerfile
-ban aCOPY
így relatív útvonallal hivatkozik a kontextusban levő fájlokra.Elérhető fájlok
Ennek következménye az is, hogy csak a build kontextusban levő fájlokra tudunk hivatkozni. Tehát nem lehet pl.
COPY ..\..\file
használatával tetszőleges fájlt felmásolni a build közben. -
Ha a build kontextusból szeretnénk kihagyni fájlokat, hogy a build ne tartson sokáig, akkor egy
.dockerignore
fájlra lesz szükségünk (a.gitignore
mintájára). Ide szokás például a build környezet saját könyvtárait (obj
,bin
,.vs
,node_modules
, stb.) is felvenni.Készítsünk egy
.dockerignore
-t az alábbi tartalommalfile.bin
-
Futtassuk ismét a buildet. Így már gyorsabb lesz.
3. Feladat¶
3.1 Docker-compose¶
Linux eltérés
Linuxon a compose nem egy külön parancs, hanem a docker parancs kiterjesztése. Emiatt docker-compose
helyett docker compose
-ként kell meghívnunk.
A fenti alkalmazás egy része még nem működik. A Python alkalmazás mellett egy Redis-re is szükségünk lenne. Futtassunk több konténert egyszerre a docker compose segítségével.
-
Dolgozzunk a repository gyökerébe (tehát ne az előzőleg használt almappába) és készítsünk ide egy
docker-compose.yaml
nevű fájlt az alábbi tartalommal.services: redis: image: redis:7.2-alpine networks: - homework_network web: build: pythonweb ports: - 5000:80 depends_on: - redis networks: - homework_network networks: homework_network: driver: bridge
A fájl tartalmának magyarázata:
services
: a szolgáltatások, amiket indítani szeretnénkredis
: egy Redis konténer, ami azalpine
verziót használjaweb
: a saját image-ből épített Python alkalmazás konténerebuild
: a build kontextusban lévő mappából építi az image-tports
: a konténer által kiajánlott portokat jelzi. Mi most webalkalmazást készítünk, ezért a konténer 80-as portját mappeljük a host 5000-es portjára.depends_on
: a konténer indításának sorrendjét jelzi. Aweb
konténer csak akkor indul, ha aredis
konténer már fut.
networks
: a konténerek közötti hálózatokat definiálja. Ahomework_network
nevű hálózatot használjuk bridge módban, ami a konténerek között adatkapcsolati réteg szintű összeköttetést jelent. Erre hivatkozunk a konténereknetworks
tulajdonságában is.
-
Nyiss egy konzolt ugyanebbe a mappába. Indítsd el az alkalmazásokat az alábbi paranccsal:
docker-compose up --build
Két lépésben a parancs:
docker-compose build
ésdocker-compose up
-
Nyisd meg böngészőben a http://localhost:5000 oldalt.
-
Egy új konzolban nézd meg a futó konténereket.
docker ps
BEADANDÓ
Készíts egy képernyőképet (f3.1.png) és commitold azt be a házi feladat repó gyökerébe, amin a fenti weboldal látszik a böngészőben és a futó konténerek listája a konzolban.
docker-compose üzemeltetéshez
A docker-compose alkalmas üzemeltetésre is. A docker-compose.yaml
fájl nem csak fejlesztői környezetet ír le, hanem üzemeltetéshez szükséges környezetet is. Ha a compose fájlt megfelelően írjuk meg (pl. használjuk a restart
direktívát is), az elindított szolgáltatások automatikusan újraindulnak a rendszer indulásakor.
Ugyanakkor a docker-compose nem helyettesíti a Kubernetes-t vagy más konténer orkesztrációs megoldásokat, mert azok sokkal komplexebb feladatokat is meg tudnak oldani (pl. skálázás, load balancing, stb.).
3.2 Több compose yaml fájl¶
A docker-compose parancsnak nem adtuk meg, hogy milyen yaml fájlból dolgozzon. Alapértelmezésként a docker-compose.yaml
kiterjesztésű fájlt és ezzel összefésülve a docker-compose.override.yaml
fájlt használja.
-
Készíts egy
docker-compose.override.yaml
fájlt a másik compose yaml mellé az alábbi tartalommal, amiben a redis konténer naplózását állítjuk át verbose szintre.services: redis: command: redis-server --loglevel verbose
-
Indítsd el a rendszert.
docker-compose up
A redis konténer részletesebben fog naplózni a
command
direktívában megadott utasítás szerint. Állítsd le a rendszert. -
Nevezd át az előbbi override fájlt
docker-compose.debug.yaml
-re. -
Készíts egy új
docker-compose.prod.yaml
fájlt a többi yaml mellé az alábbi tartalommalservices: redis: command: redis-server --loglevel warning
-
Indítsuk el a rendszert az alábbi paranccsal
docker-compose -f docker-compose.yaml -f docker-compose.debug.yaml up
A
-f
kapcsolóval tudjuk kérni a megadott yaml fájlok összefésülését.
Általában a docker-compose.yaml
-be kerülnek a közös konfigurációk, és a további fájlokba a környezet specifikus konfigurációk.
BEADANDÓ
Készíts egy képernyőképet (f3.2.png) és commitold azt be a házi feladat repó gyökerébe, amin a fenti weboldal látszik a böngészőben és a részletesebb redis naplóbejegyzések.
Opcionális: 4. Feladat¶
Docker init¶
A docker init
paranccsal egy megadott technológiához tartozó, docker alapú fejlesztéshez szükséges-hasznos fájlokat generáltathatjuk. A fájlok az adott technológiához illeszkedően készülnek, például ASP .NET Core esetén a megfelelő .NET alap lemezképekre hivatkozik a generált Dockerfile.
.NET
Ehhez a feladathoz telepítened kell a .NET SDK-t (lásd fentebb az Előkövetelmények részt), mely a dotnet
parancsot adja.
-
Készíts a repository mappájába egy almappát
aspnetweb
néven. A továbbiakban ennek az új mappának a kontextusában dolgozz. -
Generálj egy ASP.NET Core alapú kiinduló projektet
dotnet new webapp
-
Generáld az ASP.NET Core-hoz tartozó docker fájlokat
Ez a lépés létrehoz egydocker init
Dockerfile
-t a projektben, ami ráadásul multi-stage build megoldást tartalmaz, ami a fordítási, publikálási és futtatási fázisokat különválasztja (többFROM
utasítás amik egymásra hivatkoznak). Ezáltal biztosítható, hogy a .NET alkalmazásunk fordítása is reprodukálható legyen egy szeparált .NET SDK-t tartalmazó konténerben. A publikálás pedig egy kisebb méretű image-be történik, ami már csak a .NET futtatókörnyezetet tartalmazza.Ezen felül létrejön még .dockerignore fájl is, valamint egy egy service-t hivatkozó Docker compose is.
-
Futtassuk a docker compose configurációt (
docker-compose up
- Windows vagydocker compose up
- Linux). Az alapértelmezetten felkínált lehetőségek általában megfelelőek, csak végig kell Enter -ezni. Böngészőben nyissuk meg a localhost címen a docker init-nek megadott portot pl. http://localhost:8080. -
Listázzuk ki a futó konténereket egy külön konzolablakban:
docker ps
BEADANDÓ
Készíts egy képernyőképet (f4.1.png) és commitold azt be a házi feladat repó gyökerébe, amin a fenti weboldal látszik a böngészőben és a futó konténerek listája.
Kitekintés¶
Image-ek használata¶
Konténer alapú fejlesztésnél tehát két féle image-et használunk:
- amit magunk készítünk egy adott alap image-re épülve,
- illetve kész image-eket, amiket csak futtatunk (és esetleg konfigurálunk).
Alap image-ek, amikre tipikusan saját alkalmazást építünk:
- Linux disztribúciók
- Futtató platformok
- scratch: üres image, speciális esetek, pl. go, vagy distro készítéshez
A kész image-ek, amiket pedig felhasználunk:
- SDK-k multi stage buildhez
- .NET SDK pl.
mcr.microsoft.com/dotnet/sdk:8.0
- .NET SDK pl.
- Adatbázis szerverek, webszerverek, gyakran használt szolgáltatások
- MSSQL, redis, mongodb, mysql, nginx, ...
- Termérdek elérhető image: https://hub.docker.com
Verziózás fontos
Az image-ek verziózását minden esetben meg kell érteni! Minden image más-más megközelítést alkalmaz.
Kész image testreszabása¶
Az előbb a Redis memória alapú adatbázist minden konfiguráció nélkül felhasználtuk. Gyakran az ilyen image-ek "majdnem" jók közvetlen felhasználásra, de azért szükség van egy kevés testreszabásra. Ilyen esetben a következő lehetőségeink vannak:
-
Saját image-et készítünk kiindulva a számunkra megfelelő alap image-ből. A saját image-ben módosíthatunk a konfigurációs fájlokat, avagy további fájlokat adhatunk az image-be. Ezt a megoldást alkalmazhatjuk például tipikusan weboldal kiszolgálásánál, ahol is a kiinduló image a webszerver, viszont a kiszolgálandó fájlokat még mellé kell tennünk.
-
Környezeti változókon (esetleg argumentumokon) keresztül konfiguráljuk a futtatandó szolgáltatást. Az alap image-ek általában elég jó konfigurációval rendelkeznek, csak keveset kell rajta módosítanunk. Erre tökéletesen alkalmas egy-egy környezeti változó. A jól felépített Docker image-ek előre meghatározott környezeti változókon keresztül testreszabhatóak.
Erre egy jó példa a Microsoft SQL Server Docker változata. Az alábbi parancsban a
-e
argumentumokban adunk át környezeti változókat, de lehetőség van compose fájlban is megadni ezeket.docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=yourStrong(!)Password' -p 1433:1433 mcr.microsoft.com/mssql/server:2017-CU8-ubuntu
-
Becsatolhatjuk a saját konfigurációs fájljainkat a konténerbe. Korábban láttuk, hogy lehetőségünk van egy mappát a host gépről a konténerbe csatolni. Ha elkészítjük a testreszabott konfigurációs fájlt, akkor a
docker-compose.yaml
leírásban a következő módon tudjuk ezt a fájlt becsatolni a konténer indulásakor.services: redis: image: redis:7.2-alpine volumes: - my-redis.conf:/usr/local/etc/redis/redis.conf
Ezen megoldás előnye, hogy nincs szükség saját image-et készíteni, tárolni, kezelni. Amikor a környezeti változó már nem elegendő a testreszabáshoz, ez a javasolt megoldás.
További olvasnivaló¶
- Dockerfile szintaktika: https://docs.docker.com/reference/dockerfile/
- .dockerignore fájl szintaktika: https://docs.docker.com/reference/dockerfile/#dockerignore-file
- Dockerfile best practice-ek: https://docs.docker.com/build/building/best-practices/
- compose fájl szintaktika: https://docs.docker.com/compose/compose-file/
- Több compose fájl használata: https://docs.docker.com/compose/multiple-compose-files/extends/#multiple-compose-files
- Multistage build-ek: https://docs.docker.com/build/building/multi-stage/