Estoy tratando de configurar un Dockerfile para mi proyecto LAMP, pero tengo 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 la importación de volcados durante una compilación de Dockerfile?
RUN
comando se ejecuta en un contenedor diferente. Está bien explicado aquí: stackoverflow.com/questions/17891669/…RUN
línea.RUN
con varios pasos. Puede encontrar un ejemplo con una instalación de varios pasos de un software aquí: stackoverflow.com/questions/25899912/install-nvm-in-docker/…Respuestas:
Cada
RUN
instrucción en aDockerfile
se ejecuta en una capa diferente (como se explica en la documentación deRUN
).En tu
Dockerfile
, tienes tresRUN
instrucciones. El problema es que el servidor MySQL solo se inicia en el primero. En los demás, no se está ejecutando MySQL, es por eso que obtiene su error de conexión con elmysql
cliente.Para resolver este problema tienes 2 soluciones.
Solución 1: use una línea
RUN
Solución 2: use un script
Crea un script ejecutable
init_db.sh
:Agregue estas líneas a su
Dockerfile
:fuente
docker run
ejecuciones, debe montar volúmenes. Si solo desea tener un contenedor con su volcado, pero no desea continuar con las modificaciones adicionales, puede deshacerse de lasVOLUME
instrucciones en suDockerfile
.ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
cuando intento la Solución 1. Siguiendo los registrosmysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
ymysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
mysql_init_db
y cargue en la estructura de su base de datos. Esto permite la flexibilidad de restablecer automáticamente la base de datos durante la prueba, pero si desea que persista o pruebe diferentes conjuntos de datos, simplemente monte un volumen en / var / lib / mysql usandodocker run -v ...
.La última versión de la imagen oficial de MySQL Docker le permite importar datos al inicio. Aquí está mi docker-compose.yml
Aquí, tengo mi data-dump.sql en
docker/data
relación con 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 agregado este bloque para permitir la importación de datos.Una nota adicional, si desea que los datos se conserven incluso después de que el contenedor mysql se detenga y se elimine, debe tener un contenedor de datos separado como se ve en docker-compose.yml. El contenido del contenedor de datos Dockerfile es muy simple.
El contenedor de datos ni siquiera tiene que estar en estado de inicio para persistencia.
fuente
- ./docker/data:/docker-entrypoint-initdb.d
eliminó el.
directorio frente al contenedor.Lo que hice fue descargar mi volcado de sql en una carpeta "db-dump" y montarlo:
Cuando ejecuto
docker-compose up
por primera vez, el volcado se restaura en la base de datos.fuente
mysql
Parece que lo último no carga el archivo sql volcado, e incluso usando 5.6 tengo un problema con los motores de almacenamiento InnoDb.Usé el enfoque docker-entrypoint-initdb.d (Gracias a @Kuhess) Pero en mi caso quiero crear mi base de datos basada en algunos parámetros que definí en el archivo .env, así que hice estos
1) Primero defino el archivo .env como este en mi directorio de proyectos raíz de Docker
2) Luego defino mi archivo docker-compose.yml. Entonces utilicé la directiva args para definir mis variables de entorno y las configuré desde el archivo .env
3) Luego defino una carpeta mysql que incluye un Dockerfile. Entonces el Dockerfile es este
4) Ahora uso mysqldump para volcar mi base de datos y poner data.sql dentro de la carpeta mysql
El archivo es solo un archivo de volcado sql normal pero agrego 2 líneas al principio para que el archivo se vea así
Entonces, ¿qué sucede? Utilicé el comando "EJECUTAR sed -i / MYSQL_DATABASE / '$ MYSQL_DATABASE' / g '/etc/mysql/data.sql" para reemplazar el
MYSQL_DATABASE
marcador de posición con el nombre de mi DB en el que lo configuré archivo .env.Ahora está listo para construir y ejecutar su contenedor
fuente
.env
archivo. Sin embargo, de acuerdo con esto , la.env
función de archivo solo funciona cuando usa eldocker-compose up
comando y no funcionadocker stack deploy
. Por lo tanto, en caso de que desee utilizar el.env
archivo en producción, es posible que desee consultar los secretos de Docker que se introdujeron condocker 17.06
. Entonces puede usar su archivo .env en conjunción con secretos endocker compose up
lasdocker stack deploy
fases de desarrollo y producciónRUN sed -i '1s/^/CREATE DATABASE IF NOT EXISTS
$ MYSQL_DATABASE;\nUSE
$ MYSQL_DATABASE;\n/' data.sql
lugar delsed
comando que sugirió. De esta manera puede usar cualquier archivo de volcado que tenga, es útil si está trabajando con una gran cantidad de datos :)Aquí está utilizando una versión de trabajo
v3
dedocker-compose.yml
. La clave es la directiva de volúmenes :En el directorio que tengo
docker-compose.yml
, tengo undata
directorio que contiene.sql
archivos de volcado. Esto es bueno porque puede tener un.sql
archivo de volcado por tabla.Simplemente corro
docker-compose up
y estoy listo para ir. Los datos persisten automáticamente entre paradas. Si desea eliminar los datos y "absorber" los nuevos.sql
archivos ejecutados,docker-compose down
entoncesdocker-compose up
.Si alguien sabe cómo hacer que la
mysql
ventana acoplable vuelva a procesar los archivos/docker-entrypoint-initdb.d
sin eliminar el volumen, deje un comentario y actualizaré esta respuesta.fuente
docker-compose down
fue muy importante ya que no veía cambios a pesar de reiniciar docker-compose. MYSQL_DATABASE es una variable requerida en este caso