Ü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?
- 285 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.xz
and.sql.zst
that are found in/docker-entrypoint-initdb.d
. Files will be executed in alphabetical order..sh
files without file execute permission are sourced rather than executed. You can easily populate yourmariadb
services 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_DATABASE
variable.
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