Configuration de MySQL et importation de dump dans Dockerfile
j'essaye de configurer un fichier Dockerfile pour mon projet de lampe, mais j'ai quelques problèmes quand je démarre MySQL. J'ai les lignes suivantes sur mon fichier 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
mais je continue à avoir cette erreur:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)
des idées sur la façon de configurer la création de base de données et l'importation de dump pendant une construction Dockerfile?
5 réponses
chaque instruction RUN
dans une instruction Dockerfile
est exécutée dans une couche différente (comme expliqué dans la documentation de RUN
).
dans votre Dockerfile
, vous avez trois instructions RUN
. Le problème est que MySQL server n'est démarré que dans le premier. Dans les autres, Aucun MySQL n'est en cours d'exécution, c'est pourquoi vous obtenez votre erreur de connexion avec le client mysql
.
Pour résoudre ce problème, vous avez 2 solutions.
Solution 1: utiliser une ligne 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
Solution 2: Utiliser un script
créer un script exécutable 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
ajoutez ces lignes à votre Dockerfile
:
ADD init_db.sh /tmp/init_db.sh
RUN /tmp/init_db.sh
la dernière version de l'officiel mysql image du docker vous permet d'importer des données au démarrage. Voici mon menu fixe-composer.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
ici, j'ai mes données-dump.sql sous docker/data
qui est relatif au dossier de l'docker-composer est en cours d'exécution. Je monte ce fichier sql dans ce répertoire /docker-entrypoint-initdb.d
sur le conteneur.
Si vous êtes intéressé à voir comment cela fonctionne, jetez un oeil à leur docker-entrypoint.sh
sur GitHub. Ils ont ajouté ce bloc pour permettre l'importation de données
echo
for f in /docker-entrypoint-initdb.d/*; do
case "$f" in
*.sh) echo ""151910920": running $f"; . "$f" ;;
*.sql) echo ""151910920": running $f"; "${mysql[@]}" < "$f" && echo ;;
*) echo ""151910920": ignoring $f" ;;
esac
echo
done
une note supplémentaire, si vous voulez que les données persistent même après que le conteneur mysql est arrêté et enlevé, vous devez avoir un conteneur de données séparé comme vous voyez dans le docker-composer.yml. Le contenu du conteneur de données Dockerfile est très simple.
FROM n3ziniuka5/ubuntu-oracle-jdk:14.04-JDK8
VOLUME /var/lib/mysql
CMD ["true"]
le conteneur de données n'a même pas besoin d'être dans start état de la persistance.
ce que j'ai fait était de télécharger mon SQL dump dans un dossier" db-dump", et je l'ai monté:
mysql:
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: pass
ports:
- 3306:3306
volumes:
- ./db-dump:/docker-entrypoint-initdb.d
quand j'exécute docker-compose up
pour la première fois, le dump est restauré dans le db.
j'ai utilisé docker-entrypoint-initdb.d approche (grâce à @Kuhess) Mais dans mon cas, je veux créer ma base de données sur la base de certains paramètres que j'ai définis .j'ai donc fait ces
1) je commence par définir .fichier env quelque chose comme ça dans mon menu fixe racine du répertoire du projet
MYSQL_DATABASE=my_db_name
MYSQL_USER=user_test
MYSQL_PASSWORD=test
MYSQL_ROOT_PASSWORD=test
MYSQL_PORT=3306
2) puis je définirai ma composition de docker.fichier yml. J'ai donc utilisé la directive args pour définir mes variables d'environnement et je les ai pris .fichier env
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) puis je définis un dossier mysql qui inclut un fichier Dockerfile. Donc le fichier Dockerfile est ce
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) maintenant j'utilise mysqldump pour vider ma base de données et mettre les données.sql à l'intérieur de mysql dossier
mysqldump -h <server name> -u<user> -p <db name> > data.sql
le fichier est juste un fichier de dump sql normal mais j'ajoute 2 lignes au début pour que le fichier ressemble à ceci
--
-- 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 ...;
...
...
...
donc ce qui se passe est que j'ai utilisé" RUN sed-i 's/MYSQL_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/data.sql "commande pour remplacer le placeholder MYSQL_DATABASE
avec le nom de mon DB dans lequel je l'ai placé .fichier env.
|- docker-compose.yml
|- .env
|- mysql
|- Dockerfile
|- data.sql
Maintenant, vous êtes prêt à construire et exécuter votre conteneur
Voici une version de travail utilisant v3
de docker-compose.yml
. La clé est la volumes directive:
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
dans le répertoire que j'ai mon docker-compose.yml
j'ai un data
dir qui contient .sql
dump files. C'est sympa parce que vous pouvez avoir un fichier .sql
dump par table.
j'ai simplement exécuter docker-compose up
et je suis bon pour aller. Les données persistent automatiquement entre les arrêts. Si vous vous voulez supprimer les données et "aspirer" nouveau .sql
les fichiers courent docker-compose down
puis docker-compose up
.
si quelqu'un sait comment obtenir le mysql
docker pour re-traiter les fichiers dans /docker-entrypoint-initdb.d
sans supprimer le volume, s'il vous plaît laisser un commentaire et je vais mettre à jour cette réponse.