![](/img/trans.png)
[英]Mariadb docker container Can't connect to MySQL server on host (111 Connection refused) with Python
[英]Django docker container failed to connect to mysql container with error “Can't connect to MySQL server on 'db' (111)”)
我正在嘗試使用docker建立一個Django開發環境。 雖然我可以連接到主機上的mysql。 但Web容器無法連接到mysql容器,並出現以下錯誤:
django.db.utils.OperationalError: (2003, "Can't connect to MySQL server on 'db' (111)")
以下是docker配置和django配置:
---------搬運工,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:restart:always image: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數據庫配置---
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'goat_db',
'USER': 'root',
'PASSWORD': 'root',
'HOST': 'db',
'PORT': '3306',
},
你的my.cnf文件對於db服務是什么樣的?
檢查bind-address
值,並確保從Web容器連接的授權權限正確。
要進行測試,您可以將docker exec ...
到Web容器中並嘗試從那里連接到db
主機。
如果Django嘗試連接到您的數據庫並且MySql尚未就緒,那么您可能會看到此錯誤:
django.db.utils.OperationalError: (2003, "Can't connect to MySQL server on 'db' (111)")
此案例的解決方案是在運行Web服務器之前等待數據庫服務器准備就緒。
我們怎么做到這一點?
我們不是直接運行Web服務器,而是創建並運行一個腳本,它將等待數據庫服務器准備就緒。 之后,腳本將運行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_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
現在,我們的Web 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
如果您試圖保持Web容器“瘦”,您可能不想添加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)
然后在您的開發環境docker-compose.yml中設置您的Web容器,以便您有類似的東西
command: bash -c "python wait-for-postgres.py; python manage.py runserver 0.0.0.0:8000"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.