Estoy intentando crear un contenedor con una base de datos MySQL y añadir un esquema a esta base de datos.
Mi Dockerfile actual es:
FROM mysql
MAINTAINER (me) <email>
# Copy the database schema to the /data directory
COPY files/epcis_schema.sql /data/epcis_schema.sql
# Change the working directory
WORKDIR data
CMD mysql -u $MYSQL_USER -p $MYSQL_PASSWORD $MYSQL_DATABASE < epcis_schema.sql
Para crear el contenedor estoy siguiendo la documentación proporcionada en Docker y ejecutando este comando:
docker run --name ${CONTAINER_NAME} -e MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD} -e MYSQL_USER=${DB_USER} -e MYSQL_PASSWORD=${DB_USER_PASSWORD} -e MYSQL_DATABASE=${DB_NAME} -d mvpgomes/epcisdb
Pero cuando ejecuto este comando el Contenedor no se crea y en el estado del Contenedor se puede ver que el CMD no se ha ejecutado correctamente, de hecho solo se ejecuta el comando mysql
.
De todas formas, ¿hay alguna forma de inicializar la base de datos con el esquema o tengo que realizar estas operaciones manualmente?
Lo siento por esta respuesta super larga, pero, tienes un poco de camino por recorrer para llegar a donde quieres. Voy a decir que normalmente wouldn't poner el almacenamiento de la base de datos en el mismo contenedor que la base de datos en sí, que o bien montar un volumen de acogida para que los datos persiste en el host docker, o, tal vez un contenedor podría ser utilizado para mantener los datos (/var/lib/mysql). Además, soy nuevo en mysql, por lo que, esto podría no ser super eficiente. Dicho esto...
Creo que puede haber algunos problemas aquí. El Dockerfile se utiliza para crear una imagen. Es necesario ejecutar el paso de construcción. Como mínimo, desde el directorio que contiene el Dockerfile deberías hacer algo como:
docker build .
El Dockerfile describe la imagen a crear. Yo no sé mucho acerca de mysql (soy un fanboy de postgres), pero, hice una búsqueda alrededor de las interwebs para '¿cómo puedo inicializar un contenedor mysql docker'. Primero he creado un nuevo directorio para trabajar, lo he llamado mdir, luego he creado un directorio files en el que he depositado un archivo epcis_schema.sql que crea una base de datos y una única 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 files:
#!/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 root@'%' 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 fue tomada de aquí: https://gist.github.com/pda/9697520)
Aquí está el script files/run_db que he creado:
# 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
Por último, el Dockerfile para enlazarlos todos:
FROM mysql
MAINTAINER (me) <email>
# 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"
Así que, me cd'ed a mi directorio mdir (que tiene el Dockerfile junto con el directorio de archivos). A continuación, ejecuto el comando
docker build --no-cache .
Usted debe ver la salida como esta:
Sending build context to Docker daemon 7.168 kB
Sending build context to Docker daemon
Step 0 : FROM mysql
---> 461d07d927e6
Step 1 : MAINTAINER (me) <email>
---> 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 se inicia, veo una cadena de instancia:
4b377ac7397ff5880bc9218abe6d7eadd49505d50efb5063d6fab796ee157bd3
Podría entonces 'detener', y reiniciarlo.
docker stop 4b377
docker start 4b377
Si miras los logs, 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 fue descomprimida 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 arriba. Observe que init_db y run_db son scripts con el bit execute activado:
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
He intentado Greg's respuesta con cero éxito, debo haber hecho algo mal ya que mi base de datos no tenía datos después de todos los pasos: Yo estaba usando MariaDB's última imagen, por si acaso.
Entonces decidí leer el punto de entrada para la [imagen MariaDB] oficial (https://github.com/docker-library/mariadb/blob/c64262339972ac2a8dadaf8141e012aa8ddb8c23/10.1/docker-entrypoint.sh), y usé eso para generar un simple archivo docker-compose:
lenguaje: yaml -->
database:
image: mariadb
ports:
- 3306:3306
expose:
- 3306
volumes:
- ./docker/mariadb/data:/var/lib/mysql:rw
- ./database/schema.sql:/docker-entrypoint-initdb.d/schema.sql:ro
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
Ahora puedo persistir mis datos y generar una base de datos con mi propio esquema.
La solución más sencilla es utilizar tutum/mysql
docker pull tutum/mysql:5.5
docker run -d -p 3306:3306 -v /tmp:/tmp -e STARTUP_SQL="/tmp/to_be_imported.mysql" tutum/mysql:5.5
Obtenga el CONTAINER_ID anterior y luego ejecute el comando docker logs
para ver la información de la contraseña generada.
docker logs #<CONTAINER_ID>