Kötetek kezelése¶
A Docker kötetei lehetővé teszik a konténerekben előállított adatok tárolását vagy megosztását az egyes konténerek között. A Docker több, különböző típusú kötet kezelésére képes, amelyek függetlenek is lehetnek a konténerek életciklusától is. A fő cél a konténer adatainak megőrzése abban az esetben is, ha a konténert újraindítják vagy törlik. A kötetek használata különösen fontos adatbázisok, konfigurációs fájlok és egyéb perzisztens adatok kezelésekor. Ebben a fejezetben megismerkedünk a Docker kötetek létrehozásának, csatolásának és kezelésének módjaival, valamint alkalmazzuk azt a módszert, mellyel a konténer és a host rendszer közös adatkönyvtárakat használhat. A fejezet tartalma:
Docker kötetek fogalma, létrehozásuk és törlésük.
Kötetek csatolása konténerekhez.
Kötetek használata az az adatok megőrzésére.
Egy kötet jellemzőinek lekérdezése.
Nevesített és névtelen kötetek.
Megosztott mappák.
Gyakorlati példák és jógyakorlatok megismerése.
Szükséges eszközök: |
Windows, MacOS vagy Linux operációs rendszerű számítógép, telepített Docker szoftverrel. |
Feldolgozási idő: |
kb. 2 óra, a gyakorlati feladatok megoldására további 2 óra. |
Az eddig látott példákban talán nem hangsúlyoztuk ki eléggé, hogy a konténer példányok egy „felépített egészet” alkotnak, azaz minden tartalmi változás, amely a működésük során a belső fájlrendszerükben történik, az a host rendszerben nem látható, és a konténer példány törlésével (és újraépítésével is) elvész. Többek közt ezért szokás egy már felépített konténert annak újraépítése helyett a docker start paranccsal újra használni, nem pedig egy újabb példányt építeni a docker run-nal.
Ez a működési mód egyaránt lehet előny és hátrány is. Kifejezetten hasznos pl. akkor, ha a konténer egy komponense, pl. a benne futó webszerver valamilyen sérülékenységben érintett. Egy ilyen esetben a sikeres támadás után a helyreállításhoz elég a konténert újraépíteni, és abban minden újra egy sikeres támadás előtti (igaz, továbbra is sérülékeny) állapotában lesz, így el lehet végezni a sérülékenység elhárítását úgy, hogy a konténert a sérülékenységet már nem tartalmazó, javított változattal építjük újra. Hangsúlyozom: a sérülékenység megszüntetése a konténer újraépítésével történik, amely annak belső fájlrendszerére is vonatkozik, a folyamat során az is újraépül, így az abban esetleg tárolt adatokat nem fogja tartalmazni.
Ez a működési mód viszont súlyos adatvesztés forrása is lehet: ha pl. egy konténerben egy olyan webalkalmazás fut, amelybe a felhasználók fájlokat töltenek fel, abban adatokat rögzítenek, azok az adott konténer példány fájlrendszerében vannak, így annak újraépítése után elvesznek. A Docker e probléma megoldására a köteteket és a megosztott mappákat kínálja, ezeket viszont a konténer indítás során specifikálni kell.
A kötetek (pontosabban az ún. névvel ellátott kötetek) a Docker saját kezelésű, egy erre szolgáló könyvtárban elhelyezett fájljai, melyekre azok logikai nevével lehet hivatkozni. Működésük leginkább a virtualizáció során megismert virtuális merevlemezhez hasonlít.
Egy másik megoldás a megosztott mappa használata. Ez a konténer példány és az azt futtató operációs rendszer által közösen használt könyvtárat jelent – a működésük szinte teljes egészében megegyezik a virtualizáció során használt megosztott mappákéval. Ezek a mappák közvetlenül elérhetők a konténer és a host operációs rendszere számára is, ezért velük jelentősen egyszerűsíthető a konténerre alapozott fejlesztés és az adatcsere folyamata is.
A kötetek¶
A kötetek a gyakorlatban tehát olyan speciális fájlok, amelyeket a konténer belső fájlrendszerének egy könyvtárába csatolunk fel. A kötet tehát a konténer meghatározott belső könyvtárához kapcsolódik, azon keresztül, abba belépve érhető el. A csatolási pontként megadott könyvtár tartalma (fájlok, könyvtárak stb.) már a kötetben kerül tárolásra. A mechanizmus szinte pontosan úgy működik, ahogyan azt a Unix mount mechanizmusánál már láttuk.
Az alábbi példában egy konténerben futó alkalmazás az adatait a /data könyvtárban tárolja. A bal oldali szerkezetben ezek az adatok a konténer saját, belső fájlrendszerében helyezkednek el, így a konténer „eldobásakor” az abban tárolt tartalom is elvész. A jobb oldali felépítésben a dataVolume nevű, külső, statikus kötetet a /data könyvtárhoz csatoltuk, eltakarva ezzel a könyvtár eredeti tartalmát. Ezzel minden, a /data könyvtárban végzett fájlművelet ebben a külső kötetben történik. Maga a konténer ezzel eldobhatóvá válik, hiszen annak adattartalmát a kötet őrzi, ha pedig azt újra kell építeni, a konténer a kötet tartalmát ugyanúgy el tudja majd érni.
Kötet csatolása a konténerhez¶
Megjegyzés
Egy konténer-edukált :-) fejlesztőnek tehát gondolnia kell arra, hogy az alkalmazásában keletkező adatokat lehetőleg egy könyvtárból kiindulva strukturálja. Ha az alkalmazás az adatait szétszórva, más-más könyvtárban tárolja, a „konténeresítése” nehézkes lesz, mert a megőrzésükhöz megannyi kötetre lesz szükség. Ha azonban a fenti példában látható könyvtárrendszert tovább gondoljuk, és a tárolandó adatokat a /data könyvtáron belül, esetleg további könyvtárakba szervezve tároljuk, akkor egyetlen külső kötet elég lesz az alkalmazás működtetéséhez.
Hogyan működik ez a gyakorlatban? A kötetetek kezelésére néhány egyszerű parancs szolgál, melyek szintaxisa jól illeszkedik az eddig látott logikához.
Egy kötet létrehozása a docker volume create paranccsal történik, amelynek paraméterként meg kell adni a létrehozandó kötet nevét (ez példánkban dataVolume). A kötetek listázását a docker volume ls parancs végzi, amely kimenetében nem csak a rendszerben levő kötetek nevei, hanem a DRIVER oszlopban az azokat kezelő driverek is láthatók (ez példáinkban mindig local lesz).
root@columbo.uni-eszterhazy.hu:~# docker volume create dataVolume
data
root@columbo.uni-eszterhazy.hu:~# docker volume ls
DRIVER VOLUME NAME
local dataVolume
Egy kötet konténerhez rendelését a konténer indításakor lehet elvégezni, amelyhez egy további paramétert kell megadni. A -v (volume) kapcsolót követően kettősponttal elválasztva kell megadni a kötet nevét és a konténer belsejében levő csatolási könyvtárat. Amennyiben a célkönyvtár nem létezne a konténerben, a csatoláskor azt a Docker automatikusan létrehozza.
Az alábbi példában egy ubuntu:16.04 image-t töltünk le, és interaktív terminál módban készítünk belőle egy konténer példányt. A létrejövő konténer neve ubuntu-16.04 lesz, ennek indulását követően a /bin/bash programname kell elindulnia. A konténer /data könyvtárához hozzákapcsoljuk az imént létrehozott dataVolume kötetet. (Egy alap Ubuntu Linuxban ugyan nincs /data könyvtár, de ahogyan már említettem, a Docker automatikusan létrehozza azt.)
Az indítást követően a konténerben levő shell indul el, és a parancsaink a konténeren belül hajtódnak végre. Amikor az mkdir paranccsal létrehozunk egy hello nevű könyvtárat a /data könyvtárban, az már nem a konténerben, hanem az ahhoz csatolt dataVolume kötetben helyezkedik el.
root@columbo.uni-eszterhazy.hu:~# docker run -it --name ubuntu-16.04 -v dataVolume:/data ubuntu:16.04 /bin/bash
root@7a464f5947ba:/# ls /data
root@7a464f5947ba:/# mkdir /data/hello
root@7a464f5947ba:/# ls -l /data
total 4
drwxr-xr-x 2 root root 4096 Jan 26 07:12 hello
root@7a464f5947ba:/# exit
exit
Az eredményről meggyőződhetünk, ha a konténer leállítása és eldobása után ugyanezzel a paranccsal létrehozunk egy új, másik példányt, majd ellenőrizzük a /data könyvtár tartalmát: abban ott szerepel majd a hello könyvtár.
Egy kötettel kapcsolatos további információk a docker volume inspect paranccsal kérdezhetők le, amelynek kötelező paramétere a vizsgálandó kötet neve. A parancs kimenetében többek közt leolvasható a kötet létrehozásának dátuma és ideje, valamint a kötetfájl pontos helye (ez Linuxon általában a /var/lib/docker/volumes). Utóbbi értékes információ lehet akkor, amikor a rendszerben tárolt kötetetek biztonsági mentését szeretnénk elvégezni – ugyanakkor érdemes tudni, hogy túl azon, hogy a Docker dokumentációja nem garantálja az ilyen típusú mentések teljességét, nem mellesleg egy ilyen mentés konzisztenciája erősen megkérdőjelezhető, ha a mentést egy működő rendszer során végzik.
root@columbo.uni-eszterhazy.hu:~# docker volume inspect dataVolume
[
{
"CreatedAt": "2024-01-26T07:02:25Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/dataVolume/_data",
"Name": "dataVolume",
"Options": null,
"Scope": "local"
}
]
Végül, egy szükségtelenné vált kötetet törölni a docker volume rm paranccsal lehet, amelynek szintén kötelező paramétere a törlendő kötet neve.
root@columbo.uni-eszterhazy.hu:~# docker volume rm dataVolume
dataVolume
root@columbo.uni-eszterhazy.hu:~# docker volume ls
DRIVER VOLUME NAME
Megjegyzés
A teljesség kedvéért érdemes megemlíteni a fizikai partíciók csatolhatóságát is, ehhez a -v eszközfile:csatolási_pont formát kell alkalmazni pl. így: -v /dev/sdc1:/data. Fizikai partíciók csatolása azonban a konténerek gyakorlatában nem igazán jellemző.
Névtelen kötetek¶
A konténerek működésének biztosítására egy másik kötet típus, az ún. névtelen kötetek is alkalmazhatók. Ha egy kötet létrehozásakor name adjuk meg a használni kívánt kötet fájl nevét pl. így: docker run -v /mnt ubuntu, azaz csak a belső csatolási pontot határozzuk meg, akkor a Docker automatikusan létrehoz egy új kötetet, de annak neve ismeretlen marad. A docker volume ls parancs szerencsére ezeket is felsorolja, a docker volume prune pedig törli azokat, amelyeket nem használ egyetlen konténer sem. Az alábbi folyamat egy névtelen kötet alkalmazására mutat példát:
root@columbo.uni-eszterhazy.hu:~# docker run --name ubnt -v /mnt ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
29202e855b20: Pull complete
Digest: sha256:e6173d4dc55e76b87c4af8db8821b1feae4146dd47341e4d431118c7dd060a74
Status: Downloaded newer image for ubuntu:latest
root@columbo.uni-eszterhazy.hu:~# docker volume ls
DRIVER VOLUME NAME
local afd316ee6cfec4a726373731e825bdf21a1126bb074724cac79482cb9e310e70
root@columbo.uni-eszterhazy.hu:~# docker rm ubnt
ubnt
root@columbo.uni-eszterhazy.hu:~# docker volume prune
WARNING! This will remove anonymous local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
afd316ee6cfec4a726373731e825bdf21a1126bb074724cac79482cb9e310e70
A névtelen kötetek azonosítása nehézkes, a használhatóságuk korlátozott, emellett nem túl sok olyan esetet sorolhatnánk fel, amikor a névvel hivatkozható köteteteket célszerű lenne ezzel helyettesíteni.
Megosztott mappák¶
Egy megosztott mappa csatolása a kötetekkel ellentétben egy olyan mappa csatolását jelenti, amely a host fájlrendszerében helyezkedik el. Ez a Unixok esetében gyakran bind mount-nak is nevezik. Egy ilyen összerendelés során a meghatározott könyvtár tartalma tehát a konténeren kívül, a valódi fájlrendszerben helyezkedik el, annak tárolása a konténertől függetlenül történik, így az „túléli” a teljes újraépítés folyamatát is.
A megosztott mappák alkalmazása kifejezetten ideális a fejlesztési folyamat során, egy webalkalmazás fejlesztésekor a futtatási környezet (pl. az Apache-Php) a konténerbe zárva folyamatosan működik, míg a web forráskódja azon kívül található, és a megszokott fájlműveletekkel módosítható.
Egy megosztott mappa hozzárendelésekor szükséges parancs tulajdonképpen alig különbözik az eddig látottaktól, ugyanúgy a -v kapcsolót kell megadni, a különbség csupán annyi, hogy az összerendeléshez most a host és a konténer belsejében levő könyvtár párt kell meghatározni, pl. így: -v webroot:/var/www/html. Ebből következően nem lehet olyan könyvtárat bind mountolni, amellyel megegyező volume már létezik a rendszerben – ezt érdemes szem előtt tartani mind a könyvtár nevek, mint a kötet nevek megválasztásakor.
A megosztott mappák alkalmazását két, a gyakorlatban is jól hasznosítható példán keresztül nézzük meg. Az első egy olyan webszerver lesz, amit statikus weboldalak fejlesztési környezeteként használhatsz, a második pedig egy konténerben futó mySQL adatbáziskezelő rendszer.
Gyakorlat: webszerver¶
Feladat. Készítsünk egy olyan konténert, amely egy webszervert biztosít statikus website-ok készítéséhez!
Számos webszerver létezik, ebben a példában az egyik „kult” változatot, az nginx (ejtsd: endzsinex) fogjuk használni. (A szerver üzemeltetők közt nem ritkák az érzelmekkel tarkított kocsmai viták arról, hogy az Apache vagy az Nginx a jobb.) Első lépésben ismerkedjünk meg az nginx-szel, hozzunk létre egy konténer példányt belőle, majd második lépésben módosítsuk úgy, hogy az fejlesztési környezetként is használható legyen! A konténer indítását az alábbi módon végezzük:
macbook:~$ docker run --name webserver -p 5001:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
a5573528b1f0: Pull complete
8897d65c8417: Pull complete
fbc138d1d206: Pull complete
06f386eb9182: Pull complete
aeb2f3db77c3: Pull complete
64fb762834ec: Pull complete
e5a7e61f6ff4: Pull complete
Digest: sha256:4c0fdaa8b6341bfdeca5f18f7837462c80cff90527ee35ef185571e1c327beac
Status: Downloaded newer image for nginx:latest
.
.
.
2024/01/27 06:22:30 [notice] 1#1: start worker process 33
2024/01/27 06:22:30 [notice] 1#1: start worker process 34
2024/01/27 06:22:30 [notice] 1#1: start worker process 35
2024/01/27 06:22:30 [notice] 1#1: start worker process 36
A konténerben levő webszerver a 80-as belső tcp porton kommunikál, amit a gazdagép 5001-es, feltehetően még nem használt portjával kapcsolunk össze. Így a webszerverünk eléréséhez a böngésző címsorába a saját gépünk IP címét, vagy a localhost nevet és az 5001-es portot kell begépelni: http://localhost:5001. Ha mindent jól csináltunk, megjelenik az nginx alap weboldala.
Az Nginx alapoldala a konténerből¶
A webszerver telepítése ennyi munkát igényelt, de ez ebben a formájában nem felel meg az igényeinknek, mert a weboldalak „gyökérkönyvtára” most még a konténer belsejében, az /usr/share/nginx/html könyvtárban van, a webszerver minden esetben az itt található index.html fájl tartalmát jeleníti meg. (Hogy honnan tudtam ezt? A DockerHubon, a nginx leírásából derítettem ki itt: https://hub.docker.com/_/nginx), de ezt az nginx adminisztrátorai egyébként hamar megtanulják.
A konténer akkor lenne számunkra igazán hasznos, ha ezt a fejlesztői könyvtárunkkal tudnánk összekötni, amit egy megosztott mappa tehetne lehetővé. Ahhoz, hogy kipróbálhassuk, először állítsuk le ezt a konténer példányt a Ctrl-C megnyomásával, majd dobjuk el a docker rm webserver paranccsal.
macbook:~$ docker rm webserver
ae
Most hozzunk létre egy fejlesztési könyvtárat a web projektünk számára, majd kapcsoljuk össze azt a konténerünk /usr/share/nginx/html könyvtárával! Így a webszerver mindig az ott található webtartalmat jeleníti meg! Sajnos egy megkötéssel is szembesülnünk kell: itt mindig a könyvtárak abszolút elérési útját kell megadni, ami a gyakorlatban okoz némi kellemetlenséget, leginkább azért, mert a fejlesztéskor használt könyvtár helye minden bizonnyal eltér a végső, a szolgáltató szerverén levőétől. Vigaszul szolgáljon, hogy mivel kifejezetten szerencsétlen megoldás lenne a forrás könyvtár helyének abszolút megadása, segítségül hívhatjuk az operációs rendszer beépített változóit. Azt használjuk ki, hogy Unixok esetében az $PWD, Windowsban a %CD% nevű környezeti változók tartalmazzák az aktuális könyvtár elérési útját – a megadáshoz ezeket így fogjuk felhasználni:
macbook:~$ mkdir dev
macbook:~$ docker run --name webserver -p 5001:80 -v $PWD/dev:/usr/share/nginx/html nginx
Az eredmény ellenőrzéséhez a kedvenc text editorunkkal nyissuk meg a dev könyvtár tartalmát, és készítsünk ott egy rövid index.html fájlt:
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web project</title>
</head>
<body>
<h1>Lorem, ipsum.</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ducimus, debitis!</p>
</body>
</html>
A böngésző tartalmát az F5 billentyűvel frissítve meg is jelenik az új tartalom:
Statikus weboldal a konténerből.¶
Azt, hogy az oldalakat valóban a konténerünk szolgálja ki, a konténer ablakában megjelenő, az oldalak lekéréseit tartalmazó log üzenetek bizonyítják (a logokról még részletesen lesz szó az A konténerek üzeneteinek naplózása c. fejezetben). Az alábbi példában olvashatók a http kérés részletei:
172.17.0.1 - - [28/Jan/2024:07:05:48 +0000] "GET / HTTP/1.1" 200 375 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2.1 Safari/605.1.15" "-"
Mit is kínál ez az igazán egyszerű környezet? Az így kifejlesztett website-odat a munka végeztével becsomagolhatod a konténerbe (hogy miként, arról hamarosan, a Saját konténer készítése c. fejezetben lesz szó) és az futásképes lesz akár a nagy felhőszolgáltatók, akár egy kis konténerszolgáltató szerverén abban a formában, ahogyan azt összeraktad. Az így létrehozott csomag pedig a kiszolgáló operációs rendszerétől vagy beállításaitól függetlenül működik pontosan úgy, ahogyan azt a gépeden tette. A csomag elküldésekor csak annyit kell mondanod: „itt ez a konténer a webszerverrel és a weblapokkal, a 80-as belső porton fogadja a kéréseket, üzemeld be.”, és minden működni fog. A technológiát alkalmazva nincs szükség arra, hogy a fejlesztői gépen egy webszervert tarts, csupán projektenként, a fejlesztés idejére kell majd létrehoznod egyet-egyet, amit a munka befejeztével egyszerűen eldobhatsz.
Megjegyzés
Az elkészített webszerverünk nem php-képes, csak statikus html fájlokat tud kiszolgálni. A php-hoz a konténert módosítani kell, nem beszélve arról, hogy később valószínűleg valamilyen adatbáziskezelő-rendszerre is szükséged lesz. A végső fejlesztői környezetet, amely több konténer együtteséből áll majd, a Több konténer együttese c. fejezetben alakítjuk ki. Jelenlegi példáink olyan részfeladatok, amelyeket majd ott még használni fogunk.
Gyakorlat: adatbázis szerver¶
Feladat: Készítsük el egy mySQL szerver helyi gépen, konténerben futó változatát!
A megoldás gondolatmenete azonos lesz az nginx-nél már látottal, az adatbázis fájlokat itt sem a konténer belsejében, hanem attól függetlenül, a fizikai fájlrendszerben fogjuk tárolni. Ehhez tudnunk kell, hogy a mySQL esetében ez a /var/lib/mysql könyvtár lesz. A webszerverhez hasonlóan, ezt az információt vagy a mySQL dokumentációjából, vagy a DockerHubon, a mySql leírásából lehet megszerezni.
macbook:~$ docker run --name mydbserver -p 3306:3306 -v $PWD/mysqldata:/var/lib/mysql mysql
Unable to find image 'mysql:latest' locally
latest: Pulling from library/mysql
6988ac25ab22: Pull complete
...
2024-01-27 07:05:37+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
You need to specify one of the following as an environment variable:
- MYSQL_ROOT_PASSWORD
- MYSQL_ALLOW_EMPTY_PASSWORD
- MYSQL_RANDOM_ROOT_PASSWORD
Ha a konténert a szokásos módon indítjuk, sajnos hibaüzenetet kaptunk, ami (ha jobban belegondolunk) természetes, hiszen az új adatbáziskezelőnk számára valahogyan meg kellett volna határoznunk a kezelt adatbázis nevét és hozzáférési paramétereit is. Ezeket az operációs rendszer környezeti változóival lehet megtenni, a példában a szükséges változók neveit a hibaüzenet végén fel is sorolta a program. A paraméter átadás itt elvárt módszerét érdemes megjegyezni, mert ez általánosan alkalmazott megoldás a konténerek paraméterezéséhez.
Ezen a ponton két megoldás közül választhatunk. Az elsőben az adatbáziskezelőhöz tartozó root jelszót adjuk meg, amellyel bejelentkezve további felhasználók és adatbázisok hozhatók létre. A másikban, mivel a gyakorlatban általában egy konkrét adatbázisra van szükségünk, melynek eléréséhez egy felhasználó név és jelszó páros szükséges, konkrétan ezeket adjuk meg.
A környezeti változókat a -e paraméterrel lehet megadni az alábbi parancsban látható formában. Indítsunk most egy mySql konténert úgy, hogy az a szokásos 3306-os porton legyen elérhető, a root felhasználó jelszava pedig legyen nai7Iej7!
macbook:~$ docker run --name mydbserver -p 3306:3306 -v $PWD/mysqldata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD="nai7Iej7" mysql
(Hosszas kimenet)
Megjegyzés
A mySql indításakor használhatók lettek volna a MYSQL_ALLOW_EMPTY_PASSWORD és a MYSQL_RANDOM_ROOT_PASSWORD környezeti változók is. Az előbbi „yes” (igazából bármilyen nem üres) értéke esetén az adatbáziskezelő root felhasználójának üres jelszava van (ezt soha ne tegyük), utóbbi pedig a konténer indulásakor generál egy kellően biztonságos jelszót, amit egy alkalommal, az indításkor jelenít meg, ekkor lesz alkalmunk azt memorizálni.
Ehhez a mySql szerverhez már kapcsolódhatunk pl. a DBeaver vagy mySQL Workbench programmal pl. az alábbi ábrán látható beállításokkal:
Kapcsolódás a mySQL szerverhez¶
Lássuk azt a megoldást, amelyben rögtön létrehozunk egy fejlesztéshez szükséges adatbázist és beállítjuk a hozzáférését is! Először állítsuk le és dobjuk el a jelenlegi konténert:
macbook:~$ docker stop mydbserver
mydbserver
macbook:~$ docker rm mydbserver
mydbserver
Most állítsuk be a hozzáférési adatokat! Ha ezt az adatbázis létrehozásával felépítés során akarjuk megadni, további környezeti változóknak kell értéket adni. A MYSQL_DATABASE a létrehozandó új, üres adatbázis nevét, a MYSQL_USER az ehhez szükséges hozzáférés felhasználói nevét, a MYSQL_PASSWORD pedig a jelszót specifikálja. A root jelszavára most igazából nem lesz szükségünk, ezért azt véletlen értékre állítjuk be, így a MYSQL_RANDOM_ROOT_PASSWORD értéke "yes" lesz.
macbook:~$ docker run --name mydbserver -p 3306:3306 -v $PWD/mysqldata:/var/lib/mysql -e MYSQL_RANDOM_ROOT_PASSWORD="yes" -e MYSQL_DATABASE="webdb" -e MYSQL_USER="dbuser" -e MYSQL_PASSWORD="naih23thah" mysql
(Hosszas kimenet)
Mivel az adatbázis fájlok a konténeren kívül, a mysqldata könyvtárban jöttek létre, a konténert bármikor leállíthatjuk és eldobhatjuk, az adatbázis fájljaira ez már nincs hatással:
macbook:~$ ls mysqldata/
total 177128
-rw-r----- 1 koczka.ferenc staff 196608 Jan 27 18:36 #ib_16384_0.dblwr
-rw-r----- 1 koczka.ferenc staff 8585216 Jan 27 18:33 #ib_16384_1.dblwr
drwxr-x--- 34 koczka.ferenc staff 1088 Jan 27 18:34 #innodb_redo
drwxr-x--- 2 koczka.ferenc staff 64 Jan 27 18:57 #innodb_temp
-rw-r----- 1 koczka.ferenc staff 56 Jan 27 18:33 auto.cnf
-rw-r----- 1 koczka.ferenc staff 3040246 Jan 27 18:33 binlog.000001
-rw-r----- 1 koczka.ferenc staff 181 Jan 27 18:57 binlog.000002
-rw-r----- 1 koczka.ferenc staff 32 Jan 27 18:34 binlog.index
-rw------- 1 koczka.ferenc staff 1680 Jan 27 18:33 ca-key.pem
-rw-r--r-- 1 koczka.ferenc staff 1108 Jan 27 18:33 ca.pem
...
Összefoglalás¶
Ebben a fejezetben a konténerek kötetkezelését ismertük meg, – ezek olyan adatterületek, amelyeket a konténeren kívül, az azt futtató operációs rendszerben helyezkednek el. A kötetek elsődleges célja azoknak az adatoknak a megőrzése, amelyek a konténer működése során keletkeznek, és amelyeket a konténer eldobása és újraépítése után is meg kell őrizni. Tipikus példáink a webalkalmazásba feltöltött fájlokról, és egy adatbáziskezelő-rendszer nyers adatfájljainak elhelyezéséről szóltak. A Docker számos, különböző típusú kötet kezelésére képes, a két legfontosabb a közös használatú mappa és a névtelen kötetek voltak. Míg az utóbbi egy olyan speciális, felmountolt virtuális diszkként működő fájl, amit csak a Dockeren belül lehet egyszerűen kezelni, a megosztott mappák tartalma a konténeren kívül is elérhető, így alkalmazása egyszerűbb, és ezért a gyakorlatban talán könnyebben is kezelhető.
Feladatok¶
Készíts egy mySql konténert úgy, hogy az indulásakor létrehozott adatbázisban készítsen egy táblát és töltse fel azt néhány rekorddal! (Segítség: a mySql konténer az első indításakor automatikusan lefuttatja az konténer belsejében levő
/docker-entrypoint-initdb.d/init.sqlfájlt.)Készíts egy konténert, amely a ugyanezt a feladatot egy PostgreSql adatbáziskezelő-rendszerrel oldja meg!
Készíts egy konténert, melyben egy PHP webalkalmazás egy SQLite3 adatbázissal működik. Gondoskodj róla, hogy az adatbázis a konténer újraépítésekor is épségben megmaradjon!