Docker

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)

  1. The Docker client contacted the Docker daemon.
  2. The Docker daemon pulled the “hello-world” image from the Docker Hub.
    (beteszi a gépen lévő lokális cache-be)
  3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
  4. 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;