2016-07-20 5 views
2

Я пытаюсь настроить среду разработки Django с помощью docker. Хотя я могу подключиться к mysql на главной машине. Но веб-контейнер не удалось подключиться к тузд контейнер с следующей ошибкой:Контейнер docker Django не смог подключиться к контейнеру mysql с ошибкой «Не удается подключиться к серверу MySQL на« db »(111)»)

django.db.utils.OperationalError: (2003, "Can't connect to MySQL server on 'db' (111)") 

Ниже приведены Докер конфигурации и Джанго конфигурации:

--------- докер-compose.yml-- -------

version: '2' 
services: 
    web: 
    build: . 
    volumes: 
    - ".:/code/current" 
    ports: 
    - "8000:8000" 
    depends_on: 
    - db 
    - redis 
    links: 
    - db 
    - redis 
    command: ./manage.py runserver 0.0.0.0:8000 

db: 
    image: mysql:5.7 
    volumes: 
    - "./.data/db:/var/lib/mysql" 
    environment: 
    - MYSQL_ROOT_PASSWORD=root 
    - MYSQL_DATABASE=goat_db 
    restart: always 
    ports: 
    - "3306:3306" 

Redis: рестарт: всегда изображения: Redis: последние порты: - "6379: 6379"

-------------- Dockerfile для веб-изображения ----------------------

FROM ubuntu:14.04 
MAINTAINER Alice 
RUN apt-get update 
RUN apt-get install -y tar git curl wget emacs build-essential python python-dev python-distribute python-pip libpcre3 libpcre3-dev libmysqlclient-dev python-m2crypto openssl libssl-dev swig freetds-dev python-pymssql nginx subversion 
RUN mkdir -p var/www/goat.garenanow.com/current/log 
WORKDIR /var/www/goat.garenanow.com/current 
ADD requirements.txt /var/www/goat.garenanow.com/current 
RUN pip install -r requirements.txt 
ADD . /var/www/goat.garenanow.com/current 
EXPOSE 8000 

- ----- Конфигурация базы данных django ---

DATABASES = { 
'default': { 
    'ENGINE': 'django.db.backends.mysql', 
    'NAME': 'goat_db', 
    'USER': 'root', 
    'PASSWORD': 'root', 
    'HOST': 'db', 
    'PORT': '3306', 
}, 

ответ

0

Каков ваш файл my.cnf для службы db?

Проверьте значение bind-address, а также убедитесь, что разрешения на доступ правильно подключены к веб-контейнеру.

Чтобы проверить, вы можете docker exec ... в веб-контейнер и попытаться соединиться с db хостом оттуда.

+0

После выхода из контейнера до запуска для одного всю ночь. Это просто работает. (Что случилось, хотя ????) – sinsin

+0

Dunno - в любом случае был конфликт портов, а некоторые другие службы остановились? Или машина перезапустилась? – ldg

+0

Да, получилось, что докер-составление перезапуска решает проблему ... – sinsin

0

Если Джанго пытается подключиться к базе данных и MySql не готов, то вы, вероятно, увидите эту ошибку:

django.db.utils.OperationalError: (2003, "Can't connect to MySQL server on 'db' (111)") 

Решение для этого случая является ждать, пока сервер БД, чтобы быть готовым перед запуском веб-сервера.

Как мы можем это сделать?

Вместо того, чтобы напрямую работать с веб-сервером, мы создаем и запускаем скрипт, который будет ждать готовности сервера db. После этого скрипт запустит веб-сервер.


докер-compose.yml файл (Соответствующая часть, когда мы перезаписать сеть: command директиву и мы запускаем скрипт, вместо того, чтобы немедленно запустить веб-сервер).

version: '3' 
services:  
    db: 
    restart: always 
    image: mysql:5.7 
    container_name: my_db 
    env_file: env_db 
    ports: 
     - "3306:3306" 

    web: 
    restart: always 
    build: ./web 
    env_file: env_web 
    command: ./wait_for_db_and_start_server.sh 
    ports: 
     - "8000:8000" 
    depends_on: 
     - db 

Теперь env_web файл (Соответствующая часть START_CMD переменная).

# Add Environment Variables 
DB_NAME=docker 
DB_USER=docker_user 
DB_PASS=docker_password 
DB_SERVICE=db 
DB_HOST=db 
DB_PORT=3306 
START_CMD=python manage.py runserver 0.0.0.0:8000 

Теперь, наш веб-Dockerfile (Соответствующая часть, когда мы добавим wait_for_db_and_start_server.sh).

FROM python:2.7 

ADD wait_for_db_and_start_server.sh . 

ADD requirements.txt . 
RUN pip install -r requirements.txt 

ADD . . 

Теперь wait_for_db_and_start_server.sh файла. (В принципе, пока мы не можем подключиться к нашему серверу db по указанному $DB_HOST: $DB_PORT, указанному в нашем файле env_web, мы ожидаем 3 секунды и повторим попытку за M_LOOPS раз. Если мы сможем подключиться к серверу, тогда мы запускаем $START_CMD, который был определяется в нашем файле env_web.)

#!/bin/sh 
# Wait for database to get available 

M_LOOPS="10" 

#wait for mysql 
i=0 
# http://stackoverflow.com/a/19956266/4848859 
while ! curl $DB_HOST:$DB_PORT >/dev/null 2>&1 < /dev/null; do 
    i=`expr $i + 1` 

    if [ $i -ge $M_LOOPS ]; then 
    echo "$(date) - ${DB_HOST}:${DB_PORT} still not reachable, giving up" 
    exit 1 
    fi 

    echo "$(date) - waiting for ${DB_HOST}:${DB_PORT}..." 
    sleep 3 
done 

echo "$(date) - ${DB_HOST}:${DB_PORT} Reachable ! - Starting Daemon" 
#start the daemon 
exec $START_CMD 
+0

вы командуете почти работает. Я могу ping db контейнер из веб-контейнера или сервиса, но он многократно печатает '..! - Запуск Daemon ", и он не смог продолжить работу. –

0

Если вы пытаетесь сохранить ваш веб-контейнер «тонкий», вы не можете добавлять пакеты MySQL или Postgres клиента, просто чтобы проверить, если ваш дб готов. Некоторые из популярных сценариев ожидания имеют клиентские зависимости.

Я просто создал простой скрипт Python, который делает собственные вызовы, чтобы увидеть, функциональна ли БД. В этом случае я не добавляю действительные учетные данные и просто ищу сообщение об ошибке аутентификации. Пример здесь для Postgres, но должен быть легко адаптирован для MySQL.

wait_for_db.py

import psycopg2.extras 
from time import sleep 

connect_str = "dbname='postgres' user='nobody' host='db' " + \ 
       "password='foobar'" 

while True: 
    try: 
     conn = psycopg2.connect(connect_str) 
    except psycopg2.OperationalError as e: 
     if "authentication failed" in e.args[0]: 
      print("Postgres is ready. Launching site.") 
      break 
     else: 
      print("Waiting for postgres...", e.args[0]) 
      sleep(1) 

Затем установите веб-контейнер в вашем DEV среде Докер-compose.yml так, что у вас есть что-то вроде

command: bash -c "python wait-for-postgres.py; python manage.py runserver 0.0.0.0:8000" 
Смежные вопросы