2017-09-18 3 views
-1

J'utilise le fichier docker-Compose suivantImpossible de se connecter à l'image mysql en liant dans le fichier Compose docker

version: '2' 
services: 
app_test: 
    build: 
    context: . 
    dockerfile: Dockerfile-jenkins-test 
    ports: 
    - "7200:7200" 
    volumes: 
    - .:/opt/project 
    environment: 
    - DJANGO_SETTINGS_MODULE=myapp.settings.test 
    - MYSQL_DATABASE=test_db 
    - DB_HOST=mysql_test_db 
    - MYSQL_ROOT_PASSWORD=my_pass 
    - DB_PORT=3306 
    links: 
    - mysql_test_db 
mysql_test_db: 
    image: mysql:latest 
    container_name: mysql_db_container 
    expose: 
    - "3306" 
    environment: 
    - MYSQL_ROOT_PASSWORD=mypass 
    - MYSQL_DATABASE=test_db 

lorsque vous essayez d'accéder au mysql en utilisant la DB_HOST mysql_test_db il sera donne une erreur disant

django.db.utils.OperationalError: (2005, "Unknown MySQL server host 'mysql_test_db' (0)")

Comment accéder à l'image MySQL db app_test?

Répondre

2

Vous n'avez pas besoin de "liens" de ce type, tous les services dans docker-composer peuvent se rejoindre et sont "liés" automatiquement en utilisant leur nom de service.

Il n'est également pas nécessaire d'exposer 3306, car dans le réseau docker interne pour cette pile docker-composer, le port peut être atteint par n'importe quel service à l'intérieur du réseau.

version: '2' 
services: 
app_test: 
    build: 
    context: . 
    dockerfile: Dockerfile-jenkins-test 
    ports: 
    - "7200:7200" 
    volumes: 
    - .:/opt/project 
    environment: 
    - DJANGO_SETTINGS_MODULE=myapp.settings.test 
    - MYSQL_DATABASE=test_db 
    - DB_HOST=mysql_test_db 
    - MYSQL_ROOT_PASSWORD=my_pass 
    - DB_PORT=3306 
mysql_test_db: 
    image: mysql:latest 
    container_name: mysql_db_container 
    environment: 
    - MYSQL_ROOT_PASSWORD=mypass 
    - MYSQL_DATABASE=test_db 

Mais ce à quoi vous avez probablement affaire, c'est que l'ordre de démarrage du service ne vous convient pas. Mysql aura besoin d'un moment avant que la base de données puisse être connectée et soit provisionnée avec les informations d'identification, tandis que votre application django démarre très rapidement et essaie de se connecter instantanément, avant que ces informations d'identification ne soient provisionnées.

Vous devez, dans votre point d'entrée de votre application django, utiliser quelque chose comme attendre https://github.com/vishnubob/wait-for-it et tester que le port 3306 est disponible. En termes MSQYL, cela pourrait même être faux, puisque la provision commence avec un démon mysqld_safe, ne permettant aucune connexion, mais le socket TCP est ouvert et trompera "wait it".

Donc ce que vous pouvez faire est d'utiliser une vraie connexion mysql-en utilisant vos informations d'identification pour bloquer l'application de démarrer jusqu'à ce que la connexion peut être établie:

#!/bin/bash 

RET=1 
echo "Waiting for database" 
while [[ RET -ne 0 ]]; do 
    sleep 1; 
    if [ -z "${db_password}" ]; then 
     mysql -h $db_host -u $db_user -e "select 1" > /dev/null 2>&1; RET=$? 
    else 
     mysql -h $db_host -u $db_user -p$db_password -e "select 1" > /dev/null 2>&1; RET=$? 
    fi 
done 
echo "DB reached, continuing" 

Alors cela se produit juste avant bootstrap réellement votre application django .

Cela devrait aider - et devrait également aider quel niveau de problèmes, plusieurs niveaux, peuvent être la cause ici.

+0

Malheureusement j'essaie avec un pipeline Jenkins et je ne peux pas utiliser une vraie connexion – Kalanamith

+0

Vous avez besoin d'un lien sinon il sera gênant dans les environnements pipeline multi-branche – Kalanamith

+0

Votre question n'a rien à voir avec les pipelines, faire avec des connexions réelles ou irréelles - définir le nom du projet sur le nom de la branche pour composer est la bonne façon de l'espace de noms, à côté il y a des espaces de noms quand même. Relier les services locaux avec le même nom que le service est un non-sens complet. Vous pouvez lier pour renommer les services locaux ou vous lier les externes –