A mi entender, eso no funcionó porque la imagen de la ventana acoplable de mysql no contiene un cliente mysql (las mejores prácticas indican "no agregue cosas solo porque será bueno tenerlas") (¿me equivoco en esto?)
¿cuál podría ser una buena manera de hacer esto? He tenido algunas cosas en mente, pero todas parecen soluciones desordenadas.
instale el cliente mysql, haga lo que tenga que hacer con él, luego elimínelo/purgue.
copie el binario del cliente mysql en la imagen, haga lo que tenga que hacer y luego elimínelo.
Cree el esquema en otro servidor sql y copie el archivo db ellos mismos directamente (esto parece muy desordenado y me suena como un grupo de problemas contaminados)
Alguna sugerencia? Con suerte, de una manera que sea fácil de mantener más adelante y tal vez también se ajuste a las mejores prácticas.
Así es como lo hice aprovechando las imágenes reales de MySQL / MariaDB en dockerhub y la compilación de varias etapas:
FROM mariadb:latest as builder# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only initRUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"]# needed for intializationENV MYSQL_ROOT_PASSWORD=rootCOPY 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:latestCOPY --from=builder /initialized-db /var/lib/mysql
Debe colocar su script de inicio en un directorio montado como /docker-entrypoint-initdb.d - consulte la sección "Inicialización de una instancia nueva" en el Documentos de imagen de MySQL Docker.
Se han realizado cambios menores para que funcionen en mysql...
Dockerfile de Contenido
FROM mysql:latest as builder# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only initRUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"]# needed for intializationENV MYSQL_ROOT_PASSWORD=rootCOPY 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:latestCOPY --from=builder /initialized-db /var/lib/mysql
Esto funciona y sigue la interfaz con el script de punto de entrada de mariadb. Los archivos con configuraciones, tablas, datos y usuarios se copian en carpetas. Cuando se inicia el contenedor, el script de punto de entrada encuentra los archivos y crea una nueva base de datos.
FROM mariadb:10.5.5ENV MYSQL_ROOT_PASSWORD=blablablablablablaCOPY settings/my.cnf /etc/mysql/conf.d# comment out !includedir /etc/mysql/conf.d/ to stop recursionRUN sed -i 's/!includedir \/etc\/mysql\/conf\.d\//#!includedir \/etc\/mysql\/conf\.d\//' /etc/mysql/conf.d/my.cnfCOPY db_scripts/db_setup.sql /docker-entrypoint-initdb.d/COPY db_scripts/db_data.sql.template /docker-entrypoint-initdb.d/db_template.sqlCOPY db_scripts/db_users.sql /docker-entrypoint-initdb.d/# Note the port 3306 can be exposed
La respuesta de @Venkateswara Rao y @Martin Roy funciona muy bien si no le importa si los cambios en la base de datos acoplable aún se colocan en un volumen. En mi caso, quería una imagen de Docker prepoblada con datos, pero en un proyecto en el que tenemos migraciones frecuentes de bases de datos. Por lo tanto, de vez en cuando quería hacer un contenedor de base de datos, ejecutar migraciones y luego, de alguna manera, hacer una copia de seguridad de esos cambios para que el próximo usuario que use la imagen de base de datos ya tenga migraciones aplicadas. Dado que los archivos de base de datos viven en un volumen, no se enrollan en una imagen con docker commmit my-migrated-db-container my-new-db-image.
Mi solución fue usar el oficial MySQL (5.6 en mi. caso) Dockerfile (y archivo de punto de entrada) para recrear su trabajo después de quitar el VOLUME /var/lib/mysql alinear. A partir de la imagen resultante, utilicé los archivos de Venkateswara para crear una imagen de base de datos precargada donde incluso todos los datos de base de datos futuros se almacenan en el contenedor en sí (no en un volumen).
NOTA: El archivo Dockerfile vinculado es antiguo y se refiere a servidores de claves GPG obsoletos (es decir , keys.openpgp.org). Puede reemplazar estos nombres de servidor con, por ejemplo, keyserver.ubuntu.com.
Aquí está mi archivo docker que funciona absolutamente bien./sql-scripts / contendrá su archivo sql personalizado (que contiene su base de datos preparada) que se ejecuta una vez que se ejecuta el contenedor. Sin embargo, es posible que desee ver el montaje por volumen.
FROM mysql:5.6COPY ./sql-scripts/ /docker-entrypoint-initdb.d/
El software de administración como Ansible puede ayudarlo a automatizar una importación de mysql fácilmente sin la necesidad de instalar y reinstalar un cliente.Ansible tiene excelentes funciones integradas para administrar imágenes y contenedores de docker y bases de datos mysql.