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.
Aucune suggestion? Si tout va bien d'une manière qui sera facile à entretenir plus tard et peut-être également conforme aux meilleures pratiques?
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 .
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
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
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/