Saltar al contenido

¿Cómo puedo inicializar una base de datos MySQL con esquema en un contenedor Docker?

Después de de esta larga recopilación de datos solucionamos esta pregunta que pueden tener ciertos de nuestros usuarios. Te ofrecemos la solución y deseamos resultarte de mucha ayuda.

Solución:

Tuve este mismo problema en el que quería inicializar el esquema de mi instancia de MySQL Docker, pero tuve dificultades para hacer que esto funcionara después de buscar en Google y seguir los ejemplos de otros. Así es como lo resolví.

1) Vierta su esquema MySQL en un archivo.

mysqldump -h  -u  -p --no-data  > schema.sql

2) Utilice el comando ADD para agregar su archivo de esquema al /docker-entrypoint-initdb.d directorio en el contenedor de Docker. los docker-entrypoint.sh archivo ejecutará cualquier archivo en este directorio que termine con ".sql" contra la base de datos MySQL.

Dockerfile:

FROM mysql:5.7.15

MAINTAINER me

ENV MYSQL_DATABASE= 
    MYSQL_ROOT_PASSWORD=

ADD schema.sql /docker-entrypoint-initdb.d

EXPOSE 3306

3) Inicie la instancia de Docker MySQL.

docker-compose build
docker-compose up

Gracias a la configuración de MySQL y la importación de volcado dentro de Dockerfile por darme pistas sobre el docker-entrypoint.sh y el hecho de que ejecuta tanto SQL como scripts de shell.

Lamento esta respuesta tan larga, pero tienes un pequeño camino por recorrer para llegar a donde quieres. Diré que normalmente no colocaría el almacenamiento de la base de datos en el mismo contenedor que la propia base de datos, sino que montaría un volumen de host para que los datos persistan en el host de la ventana acoplable, o tal vez se podría usar un contenedor para mantenga los datos (/ var / lib / mysql). Además, soy nuevo en mysql, por lo que esto podría no ser muy eficiente. Dicho eso …

Creo que puede haber algunos problemas aquí. El Dockerfile se utiliza para crear una imagen. Necesita ejecutar el paso de compilación. Como mínimo, desde el directorio que contiene el Dockerfile, haría algo como:

docker build .

El Dockerfile describe la imagen a crear. No sé mucho sobre mysql (soy un fanboy de postgres), pero hice una búsqueda en las interwebs para ‘cómo inicializo un contenedor de mysql docker’. Primero creé un nuevo directorio para trabajar, lo llamé mdir, luego creé un directorio de archivos en el que deposité un archivo epcis_schema.sql que crea una base de datos y una sola tabla:

create database test;
use test;

CREATE TABLE testtab
(
id INTEGER AUTO_INCREMENT,
name TEXT,
PRIMARY KEY (id)
) COMMENT='this is my test table';

Luego creé un script llamado init_db en el directorio de archivos:

#!/bin/bash

# Initialize MySQL database.
# ADD this file into the container via Dockerfile.
# Assuming you specify a VOLUME ["/var/lib/mysql"] or `-v /var/lib/mysql` on the `docker run` command…
# Once built, do e.g. `docker run your_image /path/to/docker-mysql-initialize.sh`
# Again, make sure MySQL is persisting data outside the container for this to have any effect.

set -e
set -x

mysql_install_db

# Start the MySQL daemon in the background.
/usr/sbin/mysqld &
mysql_pid=$!

until mysqladmin ping >/dev/null 2>&1; do
  echo -n "."; sleep 0.2
done

# Permit root login without password from outside container.
mysql -e "GRANT ALL ON *.* TO [email protected]'%' IDENTIFIED BY '' WITH GRANT OPTION"

# create the default database from the ADDed file.
mysql < /tmp/epcis_schema.sql

# Tell the MySQL daemon to shutdown.
mysqladmin shutdown

# Wait for the MySQL daemon to exit.
wait $mysql_pid

# create a tar file with the database as it currently exists
tar czvf default_mysql.tar.gz /var/lib/mysql

# the tarfile contains the initialized state of the database.
# when the container is started, if the database is empty (/var/lib/mysql)
# then it is unpacked from default_mysql.tar.gz from
# the ENTRYPOINT /tmp/run_db script

(la mayor parte de este script se extrajo de aquí: https://gist.github.com/pda/9697520)

Aquí está el script files / run_db que creé:

# start db

set -e
set -x

# first, if the /var/lib/mysql directory is empty, unpack it from our predefined db
[ "$(ls -A /var/lib/mysql)" ] && echo "Running with existing database in /var/lib/mysql" || ( echo 'Populate initial db'; tar xpzvf default_mysql.tar.gz )

/usr/sbin/mysqld

Finalmente, el Dockerfile para vincularlos a todos:

FROM mysql
MAINTAINER  (me) 

# Copy the database schema to the /data directory
ADD files/run_db files/init_db files/epcis_schema.sql /tmp/

# init_db will create the default
# database from epcis_schema.sql, then
# stop mysqld, and finally copy the /var/lib/mysql directory
# to default_mysql_db.tar.gz
RUN /tmp/init_db

# run_db starts mysqld, but first it checks
# to see if the /var/lib/mysql directory is empty, if
# it is it is seeded with default_mysql_db.tar.gz before
# the mysql is fired up

ENTRYPOINT "/tmp/run_db"

Entonces, ingresé a mi directorio mdir (que tiene el Dockerfile junto con el directorio de archivos). Luego ejecuto el comando:

docker build --no-cache .

Debería ver un resultado como este:

Sending build context to Docker daemon 7.168 kB
Sending build context to Docker daemon 
Step 0 : FROM mysql
 ---> 461d07d927e6
Step 1 : MAINTAINER (me) 
 ---> Running in 963e8de55299
 ---> 2fd67c825c34
Removing intermediate container 963e8de55299
Step 2 : ADD files/run_db files/init_db files/epcis_schema.sql /tmp/
 ---> 81871189374b
Removing intermediate container 3221afd8695a
Step 3 : RUN /tmp/init_db
 ---> Running in 8dbdf74b2a79
+ mysql_install_db
2015-03-19 16:40:39 12 [Note] InnoDB: Using atomics to ref count buffer pool pages
...
/var/lib/mysql/ib_logfile0
 ---> 885ec2f1a7d5
Removing intermediate container 8dbdf74b2a79
Step 4 : ENTRYPOINT "/tmp/run_db"
 ---> Running in 717ed52ba665
 ---> 7f6d5215fe8d
Removing intermediate container 717ed52ba665
Successfully built 7f6d5215fe8d

Ahora tiene una imagen '7f6d5215fe8d'. Podría ejecutar esta imagen:

docker run -d 7f6d5215fe8d

y la imagen comienza, veo una instancia string:

4b377ac7397ff5880bc9218abe6d7eadd49505d50efb5063d6fab796ee157bd3

Entonces podría 'detenerlo' y reiniciarlo.

docker stop 4b377
docker start 4b377

Si observa los registros, la primera línea contendrá:

docker logs 4b377

Populate initial db
var/lib/mysql/
...

Luego, al final de los registros:

Running with existing database in /var/lib/mysql

Estos son los mensajes del script / tmp / run_db, el primero indica que la base de datos se descomprimió de la versión guardada (inicial), el segundo indica que la base de datos ya estaba allí, por lo que se utilizó la copia existente.

Aquí hay un ls -lR de la estructura de directorios que describo anteriormente. Tenga en cuenta que init_db y run_db son scripts con el bit de ejecución establecido:

gregs-air:~ gfausak$ ls -Rl mdir
total 8
-rw-r--r--  1 gfausak  wheel  534 Mar 19 11:13 Dockerfile
drwxr-xr-x  5 gfausak  staff  170 Mar 19 11:24 files

mdir/files:
total 24
-rw-r--r--  1 gfausak  staff   126 Mar 19 11:14 epcis_schema.sql
-rwxr-xr-x  1 gfausak  staff  1226 Mar 19 11:16 init_db
-rwxr-xr-x  1 gfausak  staff   284 Mar 19 11:23 run_db

Otra forma basada en una combinación de varias respuestas aquí antes:

archivo docker-compose:

version: "3"
services:
    db:
      container_name: db
      image: mysql
      ports:
       - "3306:3306"  
      environment:
         - MYSQL_ROOT_PASSWORD=mysql
         - MYSQL_DATABASE=db

      volumes:
         - /home/user/db/mysql/data:/var/lib/mysql
         - /home/user/db/mysql/init:/docker-entrypoint-initdb.d/:ro

dónde /home/user.. es una carpeta compartida en el host

Y en el /home/user/db/mysql/init carpeta .. simplemente suelte un archivo sql, con cualquier nombre, por ejemplo init.sql que contiene:

CREATE DATABASE mydb;
GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'%' IDENTIFIED BY 'mysql';
GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'localhost' IDENTIFIED BY 'mysql';
USE mydb
CREATE TABLE CONTACTS (
    [ ... ]
);
INSERT INTO CONTACTS VALUES ...
[ ... ]

De acuerdo con la documentación oficial de mysql, puede poner más de un archivo sql en el docker-entrypoint-initdb.d, se ejecutan en orden alfabético

valoraciones y comentarios

Si entiendes que te ha sido útil este artículo, nos gustaría que lo compartas con más entusiastas de la programación de este modo contrubuyes a difundir esta información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *