Django的docker容器无法连接到MySQL容器,错误“无法连接到'db'(111)上的MySQL服务器”)

我正在尝试使用docker设置Django开发环境。 虽然我可以连接到主机上的MySQL。 但是Web容器无法连接到具有以下错误的mysql容器:

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

以下是dockerconfiguration和djangoconfiguration:

———搬运工,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”

————– Web图像的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数据库configuration—

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

什么是你的my.cnf文件看起来像数据库服务?

检查bind-address值,并确保从Web容器连接的授予权限是正确的。

要testing,您可以将docker exec ...放入Web容器,然后尝试从那里连接到db主机。

如果Django试图连接到你的数据库并且MySql没有准备好,那么你可能会看到这个错误:

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

这种情况下的解决scheme是在运行Web服务器之前等待数据库服务器准备就绪。

我们如何做到这一点?

我们不是直接运行Web服务器,而是创build并运行一个脚本,等待数据库服务器准备就绪。 之后,脚本将运行Web服务器。


docker-compose.yml文件(相关部分是当我们覆盖web: command指令时,我们运行脚本而不是立即运行web服务器)。

 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_CMDvariables)。

 # 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文件。 (基本上,虽然我们无法在我们的env_web文件中定义的$DB_HOST$DB_PORT上连接到我们的数据库服务器,但是我们等待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