run initdb imagen entrypoint custom create compose cnf mysql ruby-on-rails docker-compose dockerfile

initdb - imagen mysql docker



Docker, ¿cómo ejecutar un archivo.sql en una imagen? (1)

Es la primera vez que trabajo con Docker y no estoy seguro de si estoy haciendo las cosas bien.

Tengo una aplicación de rieles que depende de una base de datos Mysql , así que configuré el archivo docker-compose.yml esta manera:

db: image: library/mysql:5.6 environment: MYSQL_ALLOW_EMPTY_PASSWORD: "yes" expose: - "3306" ports: - "3306:3306" rails-app: build: . dockerfile: Dockerfile environment: RAILS_ENV: development links: - db volumes: - ".:/home/app" volumes_from: - bundle ... omitted lines ...

Entonces, si corro lo siguiente:

$ docker-compose run db mysql --host=$DOCKER_LOCALHOST --port=3306 --protocol=tcp -u root < shared/create_common_tables.sql

Me sale este error:

ERROR 2003 (HY000): Can''t connect to MySQL server on ''192.168.99.100'' (111)

Esto suena normal, porque sospecho que tengo que build antes de algún contenedor que se vincule a db .

Lo sé porque si ejecuto esto en este orden:

$ docker-compose build rails-app $ docker-compose run -e RAILS_ENV=development rails-app bundle $ docker-compose run -e RAILS_ENV=development rails-app bundle exec rake db:create $ docker-compose run db mysql --host=$DOCKER_LOCALHOST --port=3306 --protocol=tcp -u root < shared/create_common_tables.sql

Funciona bien.

Pero, ¿cómo puedo hacer para ejecutar este SQL antes de crear cualquier contenedor?


Puede cargar el archivo sql durante la fase de build de la imagen. Para hacer esto, crea un Dockerfile para el servicio db que se verá así:

FROM mysql:5.6 COPY setup.sh /mysql/setup.sh COPY setup.sql /mysql/setup.sql RUN /mysql/setup.sh

donde setup.sh ve algo como esto:

#!/bin/bash set -e service mysql start mysql < /mysql/setup.sql service mysql stop

Y en su docker-compose.yml cambiaría la image para build: ./db o la ruta donde colocó sus archivos.

Ahora esto funciona si tiene todos sus sql en un archivo .sql en bruto, pero no será así si está usando rieles o un marco similar donde el sql se almacena realmente en el código. Esto te deja con dos opciones.

  1. En lugar de usar FROM mysql:5.6 , puede usar FROM your_app_image_that_has_the_code_in_it y apt-get install mysql ... Esto te deja con una imagen más grande que contiene mysql y tu aplicación, lo que te permite ejecutar los comandos de ruby ​​anteriores. Reemplazaría mysql < /mysql/setup/sql con el rails-app bundle exec rake db:create lines. También deberías proporcionar una configuración de aplicación que llegue a una base de datos en localhost:3306 lugar de db:3306

  2. Mi opción preferida es crear un script que exporte el sql a un archivo .sql , que luego puede usar para construir su contenedor de base de datos. Esto es un poco más de trabajo, pero es mucho mejor. Esto significa que, en lugar de ejecutar rails-app bundle exec rake db:create , simplemente ejecutaría el script para cargar una db.

Tal guión se vería así:

#!/bin/bash set -e docker-compose build rails-app docker run -d --name mysql_empty mysql:5.6 docker run --link mysql_empty:db -v $PWD:/output project_rails-app export.sh

donde export.sh ve algo como esto:

#!/bin/bash set -e RAILS_ENV=development rails-app bundle exec rake db:create mysqldump > /output/setup.sql

También puede reemplazar el script de docker run la docker run con un segundo archivo de redacción si lo desea.