Fórumok
Üdv,
Egy image buildelésekor szeretnék létrehozni egy mariadb adatbázist (van is rá egy dbscript.sh scriptem). Hogyan érdemes ezt a Dockerfile-be beírni?
Valahogy el kellene indítani a mariadbd-t, hogy a script lefuttatható legyen.
# Dockerfile
# ....
RUN mariadb-install-db
RUN /usr/sbin/mariadbd -u root # <-- előtérben fut, nem megy tovább a következő lépésre
RUN /tmp/dbscript.sh mydbname username password
# ...
ENTRYPOINT /usr/bin/supervisord -c /etc/supervisord.conf
Háttérben kellene indítani a mariadbd-t, mert addig nem megy tovább. Az elegáns, helyes megoldást keresem.
Van ötletetek?
Hozzászólások
Image buildkor nem elegáns db-t létrehozni, sőt a db imaget csak használni kell, nem kell rebuildelni. Hozza létre az app, az induláskor, ha még nem létezik.
Én a command parancsba szoktam tenni az applikációt futtató konténerbe (a példában mysql és docker-compose.yml van).
Nem mondom hogy ez a legjobb megoldás. A mysql jelszót berakhatod egy mysql.ini fájlba is az /etc alatt és akkor nem figyelmeztet.
Így persze fel kell telepítened az application image-be a "mariadb-client"-et, de minden indulás során lefut és a DB imaged maradhat official.
FONTOS, hogy az SQL-ben mindent IF-elj mindenhol, hogy csak akkor csinálja meg a műveleteket ha még nem léteznek.
sry ha hülyeség, kezdő dockeres vagyok, de nem erre van a /docker-entrypoint-initdb.d/?
Ezt néztem, de mintha ebbe csak SQL scriptek futnak le automatikusan, nem?
A .sh is végehajtódik?
(Most nem vagyok a gép előtt.)
Az official postgres imageben futnak a shell scriptek is, szóval ha a MySQL nem akar nagyon szar lenni, akkor mennie kellene ott is.
Ez akkor image függő.
Nem official mariadb image-bol készitem.
Ha nem az official dbt használod, akkor lesd el onnan az entrypoint scriptet, valszeg ez az: https://github.com/MariaDB/mariadb-docker/blob/master/docker-entrypoint…
(vagy ha nem akarsz GPL liszenszinget, akkor írj egy saját entrypoint scriptet, ami felnyalja startupkor a volumeodból a shell scriptedet)
Ne keverd össze a konténert a VM-mel/chroot-tal hasonlókkal - ugyanis nagyon más. A konténer _csak_ a DB-szerver funkciót valósítsa meg, a DB-t (mint perzisztens tartalmat) ne a konténer építése, hanem az azt használó alkalmazás indulása hozza létre, ha még nem létezik.
Plusz nem hülyeség a perzisztens mappákat volume-ként alácsatolni a futó containernek.
Lehet a végére kiderül, hogy mégiscsak az official image-et érné meg használni: https://hub.docker.com/_/mariadb
Miért hoznál létre db-t? Az egy másik konténer, csatolt erőforrás.
Teszt környezet.
De ehhez egy másik konténer való. Van egy konténered, az alkalmazás, ami használja a db-t, és egy másik konténered, ami maga a db.
Szépen elkülöníted a felelősségi köröket, nem keverednek a konténerek között.
Használd például a hivatalos mariadb konténert.
https://hub.docker.com/_/mariadb/
Azaz van egy maradb konténered, a neki megfelelő init scripttel a /docker-entrypoint-initdb.d mappa alatt. Ehhez persze a legcélszerűbb egy custom image, ami a mariadb image-ből ered, és ADD-dal vagy COPY-val hozzáadod az init scriptedet. Ezután lesz egy image-d, amit ha elindítasz üresen, létrehozza azt az adatbázist, amit szeretnél. Ezután már csatlakozhatsz az alkalmazásból hozzá.
Igen, lehet így is - de ez attól még erősen antipattern, hiszen a DB-szerver felhúzása az egy feladat, a DB-szerverben az adott alkalmazásnak a séma/user/adatszerkezet/ősfeltöltés meg egy másik - célszerűen az alkalmazásra bízva - a DB-szerveren maximum egy "create user pistikeapp..." legyen induláskor - a többit meg csinálja meg az alkalmazás (célszerűen flyway, liquibase vagy hasonló támogatással, ahogy illik)
A flyway/liquibase és hasonlók sok mindent nem tudnak, például nem tudnak DB konfigurációt változtatni, stb. Valamint valakinek létre is kell hoznia, és megfelelő jogokkal ellátnia azt a usert, aki az adatbázishoz hozzáfér. A mariadb környezeti változói által adott lehetőségek ehhez kevesek, a default konfig is sok esetben haszontalan. Konfigot meg nem tud változtatni egyik séma menedzser eszköz sem. Megvan mindkettőnek a helye: custom image a custom konfigurációhoz, a séma menedzser meg menedzselje a sémát, ahogy kell. Mindkettőnek más a feladatköre.
Ezért írtam, hogy a mariska :-) konténer létrehozásakor egy create user... fusson le, a többit meg intézze az alkalmazás telepítője a saját konténeréből.
Attól még nem kéne gányolni... Gondolom, a tesztkörnyezetben majd az alkalmazás "késznek" veszi a DB-t, aztán "úgy marad" az élesben is - yool begyógyítva ezt az antipattern megoldást. (Mivel a DB-install/startup az egyszer van, DB/séma kreálás meg lehet n+1-szer is, hiszen kvázi tetszőleges számú DB-t/sémát létre lehet MySQL-ben is hozni - miközben a konténert buildelni nem kell n+1-szer.
Ez szó szerint teszt környezet. Sehol nem lesz felhasználva. 🙂
Szóval játszós környezet. Akkor meg tessék rendesen/szépen játszani, ahogy azt ezekkel az eszközökkel kell. :-P
Buildkor nem szep megoldas DB-t letrehozni, azt runtime kell.
A gyari image tudja ezt, olvasd el a doksijat milyen kornyezeti valtozokat kezel:
https://hub.docker.com/_/mariadb
Jelen esetben neked erre van szukseged:
MARIADB_DATABASE
/MYSQL_DATABASE
This variable allows you to specify the name of a database to be created on image startup.
Én így oldottam meg, ez a docker-compose.yml:
Első indításkor betölti az /opt/appneve/conf/schema.sql fájlt az appneve adatbázisba, és azonnal használható lesz az appod.