web-dev-qa-db-fra.com

Création d'un conteneur docker mysql avec un schéma de base de données préparé

Je veux créer une image docker au-dessus de celle de mysql qui contient déjà le schéma nécessaire pour mon application.

J'ai essayé d'ajouter des lignes au Dockerfile qui importera mon schéma en tant que fichier sql. Je l'ai fait en tant que tel (mon Dockerfile):

FROM mysql

ENV MYSQL_ROOT_PASSWORD="bagabu"
ENV MYSQL_DATABASE="imhere"

ADD imhere.sql /tmp/imhere.sql

RUN "mysql -u root --password="bagabu" imhere < /tmp/imhere.sql"

À ma connaissance, cela n'a pas fonctionné car l'image de docker mysql ne contient pas de client mysql (les meilleures pratiques indiquent "n'ajoutez pas les choses simplement parce qu'elles seront agréables à avoir") (ai-je tort à ce sujet?)

quelle pourrait être une bonne façon de procéder? J'ai pensé à plusieurs choses, mais elles semblent toutes être des solutions de contournement compliquées.

  1. installez le client mysql, faites ce que j'ai à faire avec lui, puis supprimez/purgez-le.
  2. copiez le binaire client mysql dans l'image, faites ce que j'ai à faire, puis supprimez-le.
  3. Créez le schéma dans un autre serveur SQL et copiez directement le fichier db (cela semble très compliqué et me semble être un pool de problèmes contaminé)

Aucune suggestion? Si tout va bien d'une manière qui sera facile à entretenir plus tard et peut-être également conforme aux meilleures pratiques?

17
Tom Klino

Vous devez placer votre script init dans un répertoire monté en tant que /docker-entrypoint-initdb.d - voir la section "Initialisation d'une nouvelle instance" dans la section MySQL Docker image docs .

14
Greg Dubicki

J'ai dû le faire à des fins de test.

Voici comment je l'ai fait en tirant parti des images MySQL/MariaDB réelles sur dockerhub et de la construction en plusieurs étapes:

FROM mariadb:latest as builder

# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only init
RUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"]

# needed for intialization
ENV MYSQL_ROOT_PASSWORD=root

COPY setup.sql /docker-entrypoint-initdb.d/

# Need to change the datadir to something else that /var/lib/mysql because the parent docker file defines it as a volume.
# https://docs.docker.com/engine/reference/builder/#volume :
#       Changing the volume from within the Dockerfile: If any build steps change the data within the volume after
#       it has been declared, those changes will be discarded.
RUN ["/usr/local/bin/docker-entrypoint.sh", "mysqld", "--datadir", "/initialized-db", "--aria-log-dir-path", "/initialized-db"]

FROM mariadb:latest

COPY --from=builder /initialized-db /var/lib/mysql

Exemple de travail complet ici: https://github.com/lindycoder/prepopulated-mysql-container-example

14
Martin Roy

Crédits à @Martin Roy

Modifications mineures apportées au fonctionnement de mysql ...

Contenu Dockerfile

FROM mysql:latest as builder

# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only init
RUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"]

# needed for intialization
ENV MYSQL_ROOT_PASSWORD=root

COPY setup.sql /docker-entrypoint-initdb.d/

# Need to change the datadir to something else that /var/lib/mysql because the parent docker file defines it as a volume.
# https://docs.docker.com/engine/reference/builder/#volume :
#       Changing the volume from within the Dockerfile: If any build steps change the data within the volume after
#       it has been declared, those changes will be discarded.
RUN ["/usr/local/bin/docker-entrypoint.sh", "mysqld", "--datadir", "/initialized-db"]

FROM mysql:latest

COPY --from=builder /initialized-db /var/lib/mysql

Content setup.sql

CREATE DATABASE myexample;

USE myexample;

CREATE TABLE mytable (myfield VARCHAR(20));

INSERT INTO mytable VALUES ('Hello'), ('Dolly');

Exemple de travail complet ici: https://github.com/iamdvr/prepopulated-mysql-container-example

2
Venkateswara Rao

Voici mon fichier docker qui fonctionne parfaitement./sql-scripts/contiendra votre fichier sql personnalisé (contenant votre db préparé) qui sera exécuté une fois le conteneur exécuté. Vous voudrez peut-être regarder le montage du volume.

FROM mysql:5.6
COPY ./sql-scripts/ /docker-entrypoint-initdb.d/
0
Rohit Salecha