Creazione di un contenitore mysql docker con uno schema di database preparato


17

Voglio creare un'immagine docker in cima a quella mysql che contiene già lo schema necessario per la mia app.

Ho provato ad aggiungere linee al Dockerfile che importerà il mio schema come file sql. L'ho fatto come tale (il mio 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"

A quanto ho capito, ciò non ha funzionato perché l'immagine della finestra mobile mysql non contiene un client mysql (le best practice dichiarano "non aggiungere cose solo perché saranno belle da avere") (sbaglio?)

quale potrebbe essere un buon modo per farlo? Ho avuto in mente alcune cose, ma sembrano tutte soluzioni alternative disordinate.

  1. installa il client mysql, fai quello che ho a che fare con esso, quindi rimuovilo / eliminalo.
  2. copia il file binario del client mysql sull'immagine, fai quello che devo fare, quindi rimuovilo.
  3. Crea lo schema in un altro server sql e copia direttamente il file db (questo sembra molto disordinato e mi sembra un pool di problemi contaminato)

Eventuali suggerimenti? Eventualmente in un modo che sarà facile da mantenere in seguito e forse anche conforme alle migliori pratiche?


Risposte:


14

Dovresti mettere il tuo script init in una directory montata come /docker-entrypoint-initdb.d- vedi la sezione "Inizializzazione di una nuova istanza" nei documenti di immagine di MySQL Docker .


2
Funziona per far apparire un nuovo contenitore e caricarlo con il mio schema. Qual è un bel modo per aggirarlo, ma cosa succede se sto cercando un modo per creare la mia immagine docker che abbia già lo schema preinstallato?
Tom Klino,

In realtà, non importa :-) Ho pensato che /docker-entrypoint-initdb.dfosse nell'host ma in realtà è nel contenitore. Ho cambiato il ADDcomando per copiare in quella directory e rimosso il RUNcomando. Docker ha creato l'immagine con successo e l'ho testata e funziona.
Tom Klino,

14

Ho dovuto farlo a scopo di test.

Ecco come ho fatto sfruttando le immagini MySQL / MariaDB effettive su dockerhub e la build multi-stage:

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

Esempio di lavoro completo qui: https://github.com/lindycoder/prepopulated-mysql-container-example


2
la migliore risposta che ho trovato su Internet, la mia era per Postgres, quindi è stato un po 'più difficile, ma alla fine ha funzionato. E funziona perfettamente!
snowe2010,

Le versioni precedenti di mysql (5.7.9) non hanno /usr/local/bin/docker-entrypoint.sh collegato a /entrypoint.sh, invece hanno solo entrypoint.sh in /. La modifica di /usr/local/bin/docker-entrypoint.sh in /entrypoint.sh funziona e dovrebbe presumibilmente funzionare anche per le versioni "moderne".
Marvin,

2

Crediti a @Martin Roy

Apportate piccole modifiche per funzionare con mysql ...

File Docker contenuto

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');

Esempio di lavoro completo qui: https://github.com/iamdvr/prepopulated-mysql-container-example


-1

Software di gestione come Ansible possono aiutarti ad automatizzare facilmente un'importazione mysql senza bisogno di installare e reinstallare un client. Ansible ha ottime funzionalità integrate per gestire immagini e container docker e database mysql.


È interessante - ho usato Ansible ma non l'ho usato per le immagini Docker. Puoi estendere la tua risposta con alcuni esempi, Patrick?
Greg Dubicki,

Ansible ha un'ottima pagina di documenti, puoi trovare il modulo Ansible su questo url: docs.ansible.com/ansible/docker_module.html Su ciascuna pagina del capitolo del modulo di questa guida sono riportati alcuni esempi.
Patrick,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.