Configuración de MySQL e importación de volcado dentro de Dockerfile


Estoy tratando de configurar un Dockerfile para mi proyecto LAMP, pero estoy teniendo algunos problemas al iniciar MySQL. Tengo las siguientes líneas en mi Dockerfile:

VOLUME ["/etc/mysql", "/var/lib/mysql"]
ADD dump.sql /tmp/dump.sql
RUN /usr/bin/mysqld_safe & sleep 5s
RUN mysql -u root -e "CREATE DATABASE mydb"
RUN mysql -u root mydb < /tmp/dump.sql

Pero sigo recibiendo este error:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)

¿Alguna idea sobre cómo configurar la creación de bases de datos y volcar la importación durante una compilación de Dockerfile?

Author: Vini.g.fer, 2014-09-18

5 answers

Cada instrucción RUN en un Dockerfile se ejecuta en una capa diferente (como se explica en la documentación de RUN).

En tu Dockerfile, tienes tres RUN instrucciones. El problema es que MySQL Server solo se inicia en el primero. En los otros, no se está ejecutando MySQL, es por eso que obtiene su error de conexión con el cliente mysql.

Para resolver este problema tienes 2 soluciones.

Solución 1: utilice una línea RUN

RUN /bin/bash -c "/usr/bin/mysqld_safe --skip-grant-tables &" && \
  sleep 5 && \
  mysql -u root -e "CREATE DATABASE mydb" && \
  mysql -u root mydb < /tmp/dump.sql

Solución 2: utilizar a script

Crea un script ejecutable init_db.sh:

#!/bin/bash
/usr/bin/mysqld_safe --skip-grant-tables &
sleep 5
mysql -u root -e "CREATE DATABASE mydb"
mysql -u root mydb < /tmp/dump.sql

Añade estas líneas a tu Dockerfile:

ADD init_db.sh /tmp/init_db.sh
RUN /tmp/init_db.sh
 96
Author: Kuhess,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-28 08:23:33

La última versión de la imagen oficial de mysql docker le permite importar datos al iniciar. Aquí está mi docker-compose.yml

data:
  build: docker/data/.
mysql:
  image: mysql
  ports:
    - "3307:3306"
  environment:
    MYSQL_ROOT_PASSWORD: 1234
  volumes:
    - ./docker/data:/docker-entrypoint-initdb.d
  volumes_from:
    - data

Aquí, tengo mi volcado de datos.sql bajo docker/data que es relativo a la carpeta desde la que se ejecuta docker-compose. Estoy montando ese archivo sql en este directorio /docker-entrypoint-initdb.d en el contenedor.

Si está interesado en ver cómo funciona esto, eche un vistazo a su docker-entrypoint.sh en GitHub. Han añadido este bloque para permitir la importación datos

    echo
    for f in /docker-entrypoint-initdb.d/*; do
        case "$f" in
            *.sh)  echo "$0: running $f"; . "$f" ;;
            *.sql) echo "$0: running $f"; "${mysql[@]}" < "$f" && echo ;;
            *)     echo "$0: ignoring $f" ;;
        esac
        echo
    done

Una nota adicional, si desea que los datos se conserven incluso después de que el contenedor mysql se detenga y elimine, debe tener un contenedor de datos separado como se ve en docker-compose.yml. El contenido del archivo Dockerfile del contenedor de datos es muy simple.

FROM n3ziniuka5/ubuntu-oracle-jdk:14.04-JDK8

VOLUME /var/lib/mysql

CMD ["true"]

El contenedor de datos ni siquiera tiene que estar en estado de inicio para la persistencia.

 142
Author: Rajiv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-27 14:06:43

Lo que hice fue descargar mi volcado sql en una carpeta "db-dump" y montarlo:

mysql:
 image: mysql:5.6
 environment:
   MYSQL_ROOT_PASSWORD: pass
 ports:
   - 3306:3306
 volumes:
   - ./db-dump:/docker-entrypoint-initdb.d

Cuando corro docker-compose up por primera vez, el volcado se restaura en la base de datos.

 30
Author: Petru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-17 13:25:12

Usé docker-entrypoint-initdb.d enfoque (Gracias a @ Kuhess) Pero en mi caso quiero crear mi DB basado en algunos parámetros que definí en .env archivo así que hice estos

1) Primero defino .env file algo como esto en mi directorio raíz del proyecto docker

MYSQL_DATABASE=my_db_name
MYSQL_USER=user_test
MYSQL_PASSWORD=test
MYSQL_ROOT_PASSWORD=test
MYSQL_PORT=3306

2) Entonces defino mi docker-compose.archivo yml. Así que usé la directiva args para definir mis variables de entorno y las establecí desde .env file

version: '2'
services:
### MySQL Container
    mysql:
        build:
            context: ./mysql
            args:
                - MYSQL_DATABASE=${MYSQL_DATABASE}
                - MYSQL_USER=${MYSQL_USER}
                - MYSQL_PASSWORD=${MYSQL_PASSWORD}
                - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
        ports:
            - "${MYSQL_PORT}:3306"

3) Entonces defino una carpeta mysql que incluye un Dockerfile. Así que el Dockerfile es esto

FROM mysql:5.7
RUN chown -R mysql:root /var/lib/mysql/

ARG MYSQL_DATABASE
ARG MYSQL_USER
ARG MYSQL_PASSWORD
ARG MYSQL_ROOT_PASSWORD

ENV MYSQL_DATABASE=$MYSQL_DATABASE
ENV MYSQL_USER=$MYSQL_USER
ENV MYSQL_PASSWORD=$MYSQL_PASSWORD
ENV MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD

ADD data.sql /etc/mysql/data.sql
RUN sed -i 's/MYSQL_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/data.sql
RUN cp /etc/mysql/data.sql /docker-entrypoint-initdb.d

EXPOSE 3306

4) Ahora uso mysqldump para volcar mi base de datos y poner los datos.sql dentro de la carpeta mysql

mysqldump -h <server name> -u<user> -p <db name> > data.sql

El archivo es solo un archivo de volcado sql normal, pero agrego 2 líneas al principio para que el archivo se vea así

--
-- Create a database using `MYSQL_DATABASE` placeholder
--
CREATE DATABASE IF NOT EXISTS `MYSQL_DATABASE`;
USE `MYSQL_DATABASE`;

-- Rest of queries
DROP TABLE IF EXISTS `x`;
CREATE TABLE `x` (..)
LOCK TABLES `x` WRITE;
INSERT INTO `x` VALUES ...;
...
...
...

Entonces lo que sucede es que usé "RUN sed-i 's/MYSQL_DATABASE/'MYS MYSQL_DATABASE'/g' /etc/mysql/data.sql " para reemplazar el marcador de posición MYSQL_DATABASE con el nombre de mi base de datos que lo han puesto .archivo env.

|- docker-compose.yml
|- .env
|- mysql
     |- Dockerfile
     |- data.sql

Ahora está listo para construir y ejecutar su contenedor

 7
Author: Saman Shafigh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-04 00:57:58

Aquí hay una versión de trabajo usando v3 de docker-compose.yml. La clave es la directiva volumes :

mysql:
  image: mysql:5.6
  ports:
    - "3306:3306"
  environment:
    MYSQL_ROOT_PASSWORD: root
    MYSQL_USER: theusername
    MYSQL_PASSWORD: thepw
    MYSQL_DATABASE: mydb
  volumes:
    - ./data:/docker-entrypoint-initdb.d

En el directorio en el que tengo mi docker-compose.yml tengo un directorio data que contiene .sql archivos de volcado. Esto es bueno porque puede tener un archivo de volcado .sql por tabla.

Simplemente corro docker-compose up y estoy listo. Los datos persisten automáticamente entre paradas. Si desea eliminar los datos y" suck in " nuevos archivos .sql ejecutar docker-compose down entonces docker-compose up.

Si alguien sabe cómo obtener el mysql docker para volver a procesar los archivos en /docker-entrypoint-initdb.d sin eliminar el volumen, deje un comentario y actualizaré esta respuesta.

 0
Author: rynop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-29 19:30:14