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?
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
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.
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.
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
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.
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