Comment puis-je savoir quand mon menu fixe mysql conteneur est en place et mysql est prêt à prendre des requêtes?
Je suis le déploiement de quelques-uns des différents conteneurs docker, mysql être la première. Je veux exécuter des scripts dès que la base de données est en place et de procéder à la construction d'autres conteneurs. Le script a été défaillant parce qu'il était en train de s'exécuter lorsque le point d'entrée de script, qui permet de définir mysql (à partir de cette officiel de mysql conteneur), était toujours en cours d'exécution.
sudo docker run --name mysql -e MYSQL_ROOT_PASSWORD=MY_ROOT_PASS -p 3306:3306 -d mysql
[..] wait for mysql to be ready [..]
mysql -h 127.0.0.1 -P 3306 -u root --password=MY_ROOT_PASS < MY_SQL_SCRIPT.sql
Est-il un moyen d'attendre un signal de entrypoiny mysql script d'installation de finition à l'intérieur du conteneur docker? Bash le sommeil apparaît comme une solution sous-optimale.
EDIT: je suis Allé pour un script bash comme ça. Pas le plus élégant et un peu de force brute, mais fonctionne comme un charme. Peut-être que quelqu'un va trouver que utile.
OUTPUT="Can't connect"
while [[ $OUTPUT == *"Can't connect"* ]]
do
OUTPUT=$(mysql -h $APP_IP -P :$APP_PORT -u yyy --password=xxx < ./my_script.sql 2>&1)
done
- ajouter une boucle en bash pour vérifier mysql service de l'état ? Je pense que c'est aussi bon qu'il peut obtenir.
- Merci @fabrizioM. Je suis allé avec cette approche.
- cette question a été répondu ici.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez installer mysql-client package et utiliser la commande mysqladmin de ping serveur cible. Utile lorsque vous travaillez avec plusieurs conteneur docker. Combiner avec le sommeil, et de créer une simple attente de la boucle:
docker run --health-cmd='mysqladmin ping --silent' -d mysql
--health-cmd
est vraiment belle astuce! Merci 🙂while [ $(docker inspect --format "{{json .State.Health.Status }}" <container-name>) != "\"healthy\"" ]; do printf "."; sleep 1; done
mysqladmin ping
réussit avant je peux effectivement utiliser la base de données - je suppose que le conteneur est toujours en cours d'exécution est l'initialisation de la.sql
scripts.while ! wget mysql:3306; do sleep 1 done
Cette petite boucle en bash attend à mysql d'être ouvert, ne nécessite pas de paquets supplémentaires pour être installé:
mysqladmin ping
est la bonne réponse ici.Cela a été plus ou moins mentionné dans les commentaires pour les autres réponses, mais je pense qu'il mérite sa propre entrée.
Tout d'abord, vous pouvez exécuter votre conteneur de la manière suivante:
Il y a aussi un équivalent dans le Dockerfile.
De la commande de votre
docker ps
etdocker inspect
va vous montrer l'état de santé de votre conteneur. Pour mysql, en particulier, cette méthode a l'avantage demysqladmin
être disponible à l'intérieur du conteneur, de sorte que vous n'avez pas besoin de l'installer sur le panneau d'accueil.Alors vous pouvez simplement boucle dans un script bash pour attendre sur le statut de devenir sain. Le script bash suivant est créé par Dennis.
Maintenant, vous pouvez le faire dans votre script:
et votre script va attendre jusqu'à ce que le conteneur est en place et en cours d'exécution. Le script va quitter si le conteneur devient malsain, ce qui est possible, si par exemple le panneau d'accueil est de mémoire, de sorte que mysql ne peut pas allouer suffisamment de il pour lui-même.
mysqladmin ping
captures de la première rotation, ce qui est probablement ce que vous ne voulez pas. Dans mon cas, l'exécution d'un mannequin de requête avec le schéma que vous vous attendez à être, il y a le mieux fonctionné, c'est à dire changer de santé de la commande àmysql -u root -e "use your_schema;"
.Quelques fois le problème avec le port que le port peut être ouvrir, mais la base de données n'est pas encore prêt.
D'autres solutions requièrent que vous avez installé le mysql o un client mysql dans votre machine hôte, mais vraiment vous avez déjà à l'intérieur du conteneur Docker, donc je préfère utiliser quelque chose comme ceci:
mysql -u root -proot -e 'status' &> /dev/null
au lieu demysqladmin ping
J'ai trouvé que l'utilisation de la
mysqladmin ping
approche n'est pas toujours fiable, surtout si vous êtes de mettre en place un nouveau DB. Dans ce cas, même si vous êtes en mesure de faire un ping du serveur, vous pourriez être incapable de se connecter si l'utilisateur/privilège tables sont encore en cours d'initialisation. Au lieu de cela, je fais quelque chose comme ce qui suit:Jusqu'à présent, je n'ai pas rencontré de problèmes avec cette méthode. Je vois que quelque chose de similaire a été proposé par VinGarcia dans un commentaire à l'un des
mysqladmin ping
réponses.De la santé-vérifier fonctionne pour tous mes mysql conteneurs:
J'ai eu le même problème lors de mon Django conteneur essayé de vous connecter la base de données mysql contenant juste après qu'il a commencé. Je l'ai résolu en utilisant la vishnubob de wait-for.it.sh script. Ses un script shell qui attend une adresse IP et un hôte pour être prêt avant de continuer. Voici l'exemple que j'utilise pour mon applicaction.
Dans le script que je suis en demandant à la base de données mysql contenant attendre un maximum de 90 secondes (il sera exécuté normalement, lorsque vous êtes prêt) dans le port 3306 (par défaut le port mysql) et l'hôte asigned par docker pour mon MYSQL_CONTAINER_NAME. Le script ont plus variables, mais pour mw travaillé avec ces trois.
Donc je ne sais pas si quelqu'un a posté. Il ne ressemble pas à quelqu'un, alors... il y a une commande dans la commande mysqladmin qui dispose d'une attente, il gère test de la connexion, puis réessaie en interne et renvoie un succès à la fin.
La pièce principale est
mysqladmin ping -h 127.0.0.1 -u root --password=MY_ROOT_PASS --wait=30 -v
avec le--wait
être le drapeau à attendre jusqu'à ce que la connexion est réussie et que le nombre soit le montant de chaque tentative.L'idéal serait de exécuter cette commande à partir de l'intérieur du conteneur docker, mais je ne voulais pas modifier les affiches originales de commande trop.
Lorsque utilisé dans mon fichier de créer pour l'initialisation
J'ai développé une nouvelle solution de ce problème basée sur une nouvelle approche. Toutes les approches que j'ai trouvé compter sur un script qui tente de se connecter à la base de données, ou d'essayer d'établir une connexion TCP avec le conteneur. Tous les détails peuvent être trouvés sur le waitdb référentiel, mais, ma solution est de s'appuyer sur l'extrait du journal à partir du conteneur. Le script attend jusqu'à ce que les feux de bois le message prêt pour les connexions. Le script peut identifier si le conteneur de départ pour la première fois. Dans ce cas, le script attend jusqu'à ce que la base de données initiale script est exécuté et la base de données est redémarré, en attente de nouveau pour une nouvelle prêt pour les connexions message. J'ai testé cette solution sur MySQL 5.7 et MySQL 8.0.
Le script lui-même (wait_db.sh):
Le script peut être utilisé dans le Panneau composition ou dans le Panneau lui-même. J'espère que les exemples soufflet que l'usage clair:
Exemple 01: Utilisation avec menu fixe Composer
Exemple 02: Utilisation avec menu fixe
Exemple 3: Un exemple complet (le test)
Un exemple complet peut être trouvé sur le cas de test du référentiel. Ce test-cas de démarrage d'une nouvelle MySQL, créer un mannequin de base de données, attendre jusqu'à ce que tout est commencé et puis lance un sélectionnez pour vérifier si tout va bien. Après qu'il va redémarrer le conteneur et d'attendre d'être démarré et puis lance un nouveau sélectionnez pour vérifier si il est prêt pour la connexion.
https://github.com/docker-library/mysql/blob/master/5.7/docker-entrypoint.sh
docker-entrypoint.sh ne prend pas en charge la fusion personnalisés .sql encore.
Je pense que vous pouvez modifier docker-entrypoint.sh pour fusionner votre sql de sorte qu'il peut être exécutée une fois instance mysql est prêt.
Sur votre
ENTRYPOINT
script, vous devez vérifier si vous possédez une carte de connexion MySQL ou pas.Donc, dans cette solution, je vais vous montrer comment exécuter un script PHP pour vérifier si une base de données MySQL Contenant est en mesure de prendre de connexion. Si vous voulez savoir pourquoi je pense que c'est une meilleure approche de vérifier mon commentaire ici.
Fichier
entrypoint.sh
Par l'exécution de cette, vous êtes essentiellement en bloquant toute logique d'amorçage de votre récipient JUSQU'à ce que vous possédez une carte de Connexion MySQL.
Si le conteneur docker d'attente pour une base de données mysql contenant est basé sur un python de l'image (par exemple, pour une application Django), vous pouvez utiliser le code ci-dessous.
Avantages sont:
Code:
Utilisation:
wait-for-mysql-db.py
par exemple) à l'intérieur de votre application du code source.startup.py
par exemple) qui exécute le code ci-dessus, et après démarrage de votre application.command: ["python3", "startup.py"]
.Noter que cette solution est faite pour une base de données MySQL. Vous aurez besoin de l'adapter légèrement pour une autre base de données.
J'utilise le code suivant ;
exportation COMPOSE_PROJECT_NAME=web;
exportation IS_DATA_CONTAINER_EXISTS=$(docker volume ls | grep ${COMPOSE_PROJECT_NAME}_sqldata);