Ü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?
- 298 megtekintés
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.
- A hozzászóláshoz be kell jelentkezni
É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.
command: sh -c 'mysql -u root --password=${MYSQL_ROOT_PASSWORD} -h mysql < /app/initdb.sql && /app/start.sh'
Í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.
CREATE DATABASE IF NOT EXISTS ...
CREATE USER IF NOT EXISTS ...
FLUSH PRIVILEGES;- A hozzászóláshoz be kell jelentkezni
sry ha hülyeség, kezdő dockeres vagyok, de nem erre van a /docker-entrypoint-initdb.d/?
- A hozzászóláshoz be kell jelentkezni
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.)
- A hozzászóláshoz be kell jelentkezni
Az official postgres imageben futnak a shell scriptek is, szóval ha a MySQL nem akar nagyon szar lenni, akkor mennie kellene ott is.
- A hozzászóláshoz be kell jelentkezni
Ez akkor image függő.
Nem official mariadb image-bol készitem.
- A hozzászóláshoz be kell jelentkezni
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)
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
Miért hoznál létre db-t? Az egy másik konténer, csatolt erőforrás.
- A hozzászóláshoz be kell jelentkezni
Teszt környezet.
- A hozzászóláshoz be kell jelentkezni
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/
Initializing a fresh instance
When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions
.sh,.sql,.sql.gz,.sql.xzand.sql.zstthat are found in/docker-entrypoint-initdb.d. Files will be executed in alphabetical order..shfiles without file execute permission are sourced rather than executed. You can easily populate yourmariadbservices by mounting a SQL dump into that directory and provide custom images with contributed data. SQL files will be imported by default to the database specified by theMARIADB_DATABASE/MYSQL_DATABASEvariable.
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á.
- A hozzászóláshoz be kell jelentkezni
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 hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
Ez szó szerint teszt környezet. Sehol nem lesz felhasználva. ?
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
Én így oldottam meg, ez a docker-compose.yml:
version: "2"
volumes:
DB:
services:
appneve:
container_name: appneve
image: appneve:latest
volumes:
- /opt/appneve/www:/var/www
ports:
- 1099:80
restart: always
links:
- appneve_db
appneve_db:
container_name: appneve_db
image: mariadb:10.6
volumes:
- DB:/var/lib/mysql
- /opt/appneve/conf/schema.sql:/docker-entrypoint-initdb.d/schema.sql:ro
restart: always
environment:
- MYSQL_ROOT_PASSWORD=rootjelszo
- MYSQL_DATABASE=appneve
- MYSQL_USER=appneve
- MYSQL_PASSWORD=appjelszava
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.
- A hozzászóláshoz be kell jelentkezni