J'essaye de configurer un Dockerfile pour mon projet LAMP, mais j'ai quelques problèmes lors du démarrage de MySQL. J'ai les lignes suivantes sur mon 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 à recevoir 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 vidage lors d'une construction Dockerfile?
RUN
commande est exécutée dans un conteneur différent. C'est bien expliqué ici: stackoverflow.com/questions/17891669/…RUN
ligne.RUN
avec plusieurs étapes. Vous pouvez trouver un exemple d'installation en plusieurs étapes d'un logiciel ici: stackoverflow.com/questions/25899912/install-nvm-in-dockerRéponses:
Chaque
RUN
instruction de aDockerfile
est exécutée dans une couche différente (comme expliqué dans la documentation deRUN
).Dans votre
Dockerfile
, vous avez troisRUN
instructions. Le problème est que le serveur MySQL ne démarre 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 lemysql
client.Pour résoudre ce problème, vous avez 2 solutions.
Solution 1: utilisez une ligne
RUN
Solution 2: utilisez un script
Créez un script exécutable
init_db.sh
:Ajoutez ces lignes à votre
Dockerfile
:la source
docker run
exécutions, vous devez monter des volumes. Si vous voulez juste avoir un conteneur avec votre vidage, mais que vous ne voulez pas persister d'autres modifications, vous pouvez vous débarrasser de l'VOLUME
instruction dans votre fichierDockerfile
.ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
en essayant la solution 1. Suivre les journauxmysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
etmysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
mysql_init_db
et chargez dans la structure de votre base de données. Cela permet la flexibilité de réinitialiser automatiquement la base de données lors du test, mais si vous voulez qu'elle persiste ou teste différents ensembles de données, il vous suffit de monter un volume dans / var / lib / mysql en utilisantdocker run -v ...
.La dernière version de l' image officielle du docker mysql vous permet d'importer des données au démarrage. Voici mon docker-compose.yml
Ici, j'ai mon data-dump.sql sous
docker/data
lequel est relatif au dossier à partir duquel docker-compose s'exécute. Je monte ce fichier sql dans ce répertoire/docker-entrypoint-initdb.d
sur le conteneur.Si vous souhaitez voir comment cela fonctionne, jetez un œil à leur
docker-entrypoint.sh
dans GitHub. Ils ont ajouté ce bloc pour permettre l'importation de donnéesUne note supplémentaire, si vous voulez que les données soient persistantes même après l'arrêt et la suppression du conteneur mysql, vous devez avoir un conteneur de données séparé comme vous le voyez dans le fichier docker-compose.yml. Le contenu du conteneur de données Dockerfile est très simple.
Le conteneur de données n'a même pas besoin d'être à l'état de démarrage pour la persistance.
la source
- ./docker/data:/docker-entrypoint-initdb.d
suppression du répertoire.
devant le conteneur.Ce que j'ai fait a été de télécharger mon dump sql dans un dossier "db-dump" et de le monter:
Lorsque je lance
docker-compose up
pour la première fois, le vidage est restauré dans la base de données.la source
mysql
semble ne pas charger le fichier sql vidé, et même en utilisant 5.6 j'ai un problème avec les moteurs de stockage InnoDb.J'ai utilisé l'approche docker-entrypoint-initdb.d (Merci à @Kuhess) Mais dans mon cas, je veux créer ma base de données en fonction de certains paramètres que j'ai définis dans le fichier .env, alors je l'ai fait
1) Tout d'abord, je définis le fichier .env quelque chose comme ça dans mon répertoire de projet racine docker
2) Ensuite, je définis mon fichier docker-compose.yml. J'ai donc utilisé la directive args pour définir mes variables d'environnement et je les ai définies à partir du fichier .env
3) Ensuite, je définis un dossier mysql qui comprend un Dockerfile. Donc le Dockerfile est ceci
4) Maintenant, j'utilise mysqldump pour vider ma base de données et mettre le data.sql dans le dossier mysql
Le fichier est juste un fichier de vidage sql normal mais j'ajoute 2 lignes au début pour que le fichier ressemble à ceci
Donc, ce qui se passe, c'est que j'ai utilisé la commande "RUN sed -i 's / MYSQL_DATABASE /' $ MYSQL_DATABASE '/ g' /etc/mysql/data.sql" pour remplacer l'
MYSQL_DATABASE
espace réservé par le nom de ma base de données dans laquelle je l'ai défini fichier .env.Vous êtes maintenant prêt à créer et exécuter votre conteneur
la source
.env
fichier. Cependant, selon cela , la.env
fonctionnalité de fichier ne fonctionne que lorsque vous utilisez ladocker-compose up
commande et ne fonctionne pas avecdocker stack deploy
. Ainsi, si vous souhaitez utiliser le.env
fichier en production, vous voudrez peut-être consulter les secrets de docker introduits avecdocker 17.06
. Ensuite, vous pouvez utiliser votre fichier .env en conjonction avec des secrets dans les phases de développementdocker compose up
et de productiondocker stack deploy
RUN sed -i '1s/^/CREATE DATABASE IF NOT EXISTS
$ MYSQL_DATABASE;\nUSE
$ MYSQL_DATABASE;\n/' data.sql
au lieu de lased
commande que vous avez suggérée. De cette façon, vous pouvez utiliser n'importe quel fichier de vidage que vous avez - c'est utile si vous travaillez avec une grande quantité de données :)Voici une version fonctionnelle utilisant
v3
dedocker-compose.yml
. La clé est la directive volumes :Dans le répertoire que j'ai,
docker-compose.yml
j'ai un répertoiredata
contenant.sql
des fichiers de vidage. C'est bien car vous pouvez avoir un.sql
fichier de vidage par table.Je cours simplement
docker-compose up
et je suis prêt à partir. Les données persistent automatiquement entre les arrêts. Si vous voulez supprimer les données et « aspirer » les nouveaux.sql
fichiers exécutentdocker-compose down
ensuitedocker-compose up
.Si quelqu'un sait comment faire en sorte que le
mysql
docker retravaille les fichiers/docker-entrypoint-initdb.d
sans supprimer le volume, veuillez laisser un commentaire et je mettrai à jour cette réponse.la source
docker-compose down
était très importante car je ne voyais aucun changement malgré le redémarrage de docker-compose. MYSQL_DATABASE est une variable obligatoire dans ce casJe n'aime pas vraiment la réponse acceptée par
sleep 5
Kuhess car cela me semble un peu hackish car il suppose que le démon mysql db s'est correctement chargé dans ce laps de temps. C'est une hypothèse, aucune garantie. De plus, si vous utilisez une image docker mysql fournie, l'image elle-même s'occupe déjà du démarrage du serveur; Je n'interférerais pas avec cela avec une coutume/usr/bin/mysqld_safe
.J'ai suivi les autres réponses ici et copié les scripts bash et sql dans le dossier
/docker-entrypoint-initdb.d/
du conteneur docker car c'est clairement la manière prévue par le fournisseur d'images mysql. Tout ce qui se trouve dans ce dossier est exécuté une fois que le démon db est prêt, vous devriez donc pouvoir vous y fier.En complément des autres - car aucune autre réponse ne le mentionne explicitement: outre les scripts SQL, vous pouvez également copier des scripts bash dans ce dossier ce qui pourrait vous donner plus de contrôle.
C'est ce dont j'avais besoin par exemple car j'avais également besoin d'importer un vidage, mais le vidage seul n'était pas suffisant car il ne fournissait pas la base de données dans laquelle il devait importer. Donc, dans mon cas, j'ai un script nommé
db_custom_init.sh
avec ce contenu:et ce Dockerfile copiant ce script:
edit: Notez que cela n'importera le vidage SQL qu'au moment de la création du conteneur, pas au moment de la construction de l'image!
la source