oktatóvideó: sanfranciscoboljottem.com – Docker ismeretek; Kódbázis: Docker
Telepítés: docker.com/product/docker-desktop; egy program, amit írtunk, adott operációs rendszeren, adott futtatókörnyezetben lett megírva. Ha egy másik gépen akarjuk futtatni, akkor ugyanezt a szoftveres környezetet kell létrehozni azon a gépen. A docker egy elszeparált környezetben (ez a konténer) létrehozza a programot futtató környezetet és elraktározza a programot, majd felteszi ezt egy felhőbe. Ezt a konténert onnan letölthetem más gépre, s ott – a szoftveres környezet nélkül is – futtathatom a programot a konténerből.
A container az image (sablon) lepéldányosított változata. A container a hardverből (processzor, memória, merevlemez) kap egy szeletet és ott fut. Ha beírjuk a parancssorba: docker run hello-world, akkor a következő üzenetet kapjuk (parancssor > docker kliens > docker démon > docker hub)
- The Docker client contacted the Docker daemon.
- The Docker daemon pulled the „hello-world” image from the Docker Hub.
(beteszi a gépen lévő lokális cache-be) - The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading. - The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
parancs: docker ps [process status] kiírja az éppen futó konténereket; az utolsó oszlop, a name egy – a docker által adott random – vicces név; docker ps -a [all] a lefutott konténereket is megmutatja; konténer leállítása: docker rm <id> [rm=remove]; az összes konténer leállítása: docker container prune [prune = eltávolít]; a docker run hello-world parancs valójában két parancsot foglal magába: docker create hello-world létrehozza a konténert; a docker start -a <id> lefuttatja a konténert; az -a flag gondoskodik arról, hogy a parancssorba kiíródjon az, ami a konténerből kijön; id-ből elég csak az első pár karaktert beírni, csak annyit, amitől már unikális az id az összes éppen futó közül. Kontéren újrainítása: docker start <id>; a docker run <id> ugyanis a konténer egy újabb példányát hozza létre és futtatja le, míg a docker start <id> ugyanazt a konténert futtatja újra; docker logs <id> paranccsal tudom kiíratni a konténer által eddig kiadott összes outputot; konténer leállítása: docker stop <id>; ez max 10 másodpercig vár, hogy a konténer szabályosan álljon le; a docker kill <id> azonnal leállítja a konténert;
képfájl létrehozása: Dockerfile kiterjesztés nélkül; FROM – base image az alap fájlrendszer létrehozása; WORKDIR: /home/webserver – munkakönyvtár létrehozása a konténeren belül; COPY: ./ ./ – a gyökérkönyvtár fájljait másolja át a konténer gyökérkönyvtárába; ha WORKDIR-rel létrehoztunk egy munkakönyvtárat, akkor a COPY második ./ eleme automatikusan a munkakönyvtárra fog mutatni. RUN – azok a parancsok, amelyek még azelőtt lefutnak, mielőtt a kép elkészült és valaki lepéldányosítaná a konténert; CMD [„parameter”, „parameter”, „parameter”] – azután fut le, hogy valaki elindította a konténert, a parancsban összetartozó kifejezések is külön elemként vannak a tömbben.
A konténer fájlrendszerének kilistázása: docker exec -it <id> sh; exec: execute; -it tkp. két parancs egybeírva: -i -t; i: input – kösse rá a programra ezt a terminált, hogy itt lehessen kommunikálni vele; t: a kommunikáció legyen szépen formázott; a -i -t együtt is írható: -it; sh: shell; ez beléptet a shell-be;itt könyvtár kilistázása: dir; belépés adott könyvtárba cd <könyvtár>
Konténer létrehozása: parancssor: docker build <a Dockerfile elérési útja>; ha abban a mappában vagyok, ahol a Dockerfile is van, akkor a parancs végén egy pont (‘.’) jelzi ezt: docker build . ; a konténer futtatása: docker run <id>; dockerfile kiíratása: cat Dockerfile [cat=concatenate]; névadás a konténernek, hogy ne id-vel kelljen hivatkozni rá; (ehhez regisztrálni kell a docker hub-on): docker build -t felhasználónév/projektnév:verziószám . – a végén a pont!; [t = tagging, taggelés]; verziószám helyére írhatjuk azt is, hogy latest, ekkor a legfrissebbnek fogja tekinteni; indítás: docker run felhasználónév/projektnév:verziószám; a verziószám elhagyható, ekkor a latest-et fogja indítani;
Ha webszervert futtatunk, ami pl. a 3000 portot figyeli, akkor a localhost:3000-en nem jelenik meg semmi a böngészőben, mert az adott port a konténeren belül fut, így azt össze kell kötni a saját számítógépünk 3000-es portjával: docker run -p 3000:3000 felhasználónév/projektnév:verziószám; p: port; -p op. rendszer portja : konténer portja;
Egy Dockerfile egy vs code kódszerkesztővel írt programhoz (a package.json-ba: „scripts”:{ „start”: „node ./src/index.js”}, az index.js-re mutató relatív útnak abból a mappából kell kiindulnia, ahol a package.json van.
FROM node:12 WORKDIR /home/webserver COPY ./ ./ RUN npm install CMD ["npm","start"]
Amikor a Dockerfile lefut, akkor soronként jön létre a képfájl egy-egy rétege, amelyek rétegesen épülnek egymásra. Ha változtatunk valamit a Dockerfájlban, akkor a változatlan képeket a cache-ből tölti be, csak a megváltozott rétegeket hozza újra létre. Ez a réteges felépítés arra is jó, hogy ha egy másik képfájlban is szerepel a FROM node:12 utasítás, akkor a docker nem hozza létre újra ezt a réteget, hanem a már meglévőt veszi elő a cache-ből.
Oktatóvideó: A docker konténerizáció
A windowsra letöltött docker program egy linuxos virtuális gépet hoz létre, a ezen az emulált linuxos környezetben futnak a konténerek. A docker info parancs a docker rendszerinformációit mutatja meg. Amikor a konténer fut, akkor container, amiből viszont létrejött, az az image. Az image-k a hub.docker.com-on; docker run <név>: ha nincs meg lokálisan a gépen a kép, akkor felmegy a hub.docker.com felhőjébe és onnan lelölti, majd futtatja; docker pull <név>: csak letölti, ha nincs meg lokálisan; docker images: kilistázza, hogy milyen docker képek vannak a gépemen; konténer futtatása: docker run <név>: a konténer a háttérben fog futni; docker run -it <név>: kapcsolat lesz a futó konténer és az adott parancssor között; pl. ls parancs kilistázza a konténer fájlrendszerét (kis l + s); docker ps: kilistázza a futó konténereket; docker logs <név>: megmutatja a konténer naplófájlját; docker rm: konténer törlése; docker rmi: image törlése [remove]; docker build . :konténer építése image-ből, abban a mappában nyissuk meg a parancssort, amiben a Dockerfile van; docker push <az image neve>; előtte bejelentkezni: docker login;
Ha a program több konténert is futtat, akkor az indító parancs, ami egyszerre kezeli az összes konténert: docker-compose up; ekkor egy docker.compose.yml fájlra van szükség; yml kiterjesztés: egy YAML nyelven írt file; YAML: Yet Another Markup Language (‘egy másik jelölőnyelv’ – ekkoriban szaporodtak el a jelölőnyelvek, pl. HTML); ember által olvasható, adat-szerializálásra való, leginkább konfigurációs fájlt létrehozására szolgáló nyelv.
Példa egy docker-compose.yml fájlra:
version: "3" services: nodejs_tutorial: build: context: ./server dockerfile: Dockerfile volumes: - "./server/src:/usr/src/app" environment: - PORT=3000 ports: - "3000:3000" networks: - tutorial_net mysql_host: build: context: ./db dockerfile: Dockerfile restart: always environment: MYSQL_DATABASE: 'test_db' MYSQL_USER: 'user' MYSQL_PASSWORD: 'password' MYSQL_ROOT_PASSWORD: 'password' ports: - '3308:3306' networks: - tutorial_net expose: - '3308' phpmyadmin: image: phpmyadmin/phpmyadmin links: - mysql_host environment: PMA_ARBITRARY: 1 PMA_HOST: mysql PMA_PORT: 3306 restart: always ports: - 8181:80 networks: - tutorial_net volumes: - /sessions networks: tutorial_net: driver: bridge
ports: – „3000:3000” – a gazdagép portját rákötöm a konténer portjára; ha bekötök a konténerbe a volume-t, akkor a gazdagépből ráerősítek a konténerre egy mappát és engedem, hogy a konténer ebből a fájlból olvasson és ide írjon, azaz ha történik adat átírása / hozzáadása a program futása során, akkor az megőrződik a gazdagépben lévő mappában a konténer törlése után is; enviroment: megadhatok környezeti változókat; networks: network beállítása, amin keresztül az egyes konténerek kommunikálnak egymással;