django无法在docker-compose中连接mysql [英] django cannot connect mysql in docker-compose
问题描述
我对Docker非常陌生,现在我想通过docker-compose在docker中使用mariadb运行django,但我总是会收到此错误:
I'm very new for docker, now I am trying to run django with mariadb in docker through docker-compose, but I always get this error:
我使用 Docker版本17.09.1-ce,内部版本19e2cf6
, docker-compose版本1.18.0,内部版本8dd22a9
django.db.utils.OperationalError:(2003,'无法连接到MySQL\'mariadb55 \'上的服务器(111连接被拒绝")')
django.db.utils.OperationalError: (2003, 'Can\'t connect to MySQL server on \'mariadb55\' (111 "Connection refused")')
在本地或远程运行 docker-compose up db
后,我可以正确连接数据库,甚至可以正确运行 python manage.py runserver 0.0.0.0:6001
通过设置 settings.py 文件的参数,在 anaconda虚拟环境中连接docker中的 db
服务:
I can connect db correctly after run docker-compose up db
in local or remote, and I even can run python manage.py runserver 0.0.0.0:6001
correctly in anaconda virtual environment to connect db
service in docker by setting parameters of settings.py file like below:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test',
'USER': 'belter',
# 'HOST': 'mariadb55',
'HOST': '127.0.0.1',
'PORT': '3302',
'PASSWORD': 'belter_2017',
'default-character-set': 'utf8',
'OPTIONS': {
'sql_mode': 'traditional',
}
}
}
这是我的 docker-compose.yml 文件
version: '3'
services:
db:
image: mariadb:5.5
restart: always
environment:
- MYSQL_HOST=localhost
- MYSQL_PORT=3306
- MYSQL_ROOT_HOST=%
- MYSQL_DATABASE=test
- MYSQL_USER=belter
- MYSQL_PASSWORD=belter_2017
- MYSQL_ROOT_PASSWORD=123456_abc
volumes:
- /home/belter/mdbdata/mdb55:/var/lib/mysql
ports:
- "3302:3306"
web:
image: onlybelter/django_py35
command: python3 manage.py runserver 0.0.0.0:6001
volumes:
- /mnt/data/www/mysite:/djcode
ports:
- "6001:6001"
depends_on:
- db
links:
- db:mariadb55
我几乎尝试了所有可以找到的东西,但仍然无法弄清楚,任何帮助都将很不错!
I almost tried everything I can find, but still cannot figure it out, any help would be nice!
我尝试过的事情:
使用docker-compose链接django和mysql容器
通过docker-compose Django与Postgres的连接
推荐答案
最后,我知道了!关键是,正如@SangminKim所说,我需要在 settings.py
中使用 3306
而不是 3302
,并使用 db
作为 HOST
而不是 127.0.0.1
.
Finally, I figured it out!
The key point is, just as @SangminKim said, I need to use 3306
not 3302
in settings.py
, and use db
as HOST
not 127.0.0.1
.
所以这是我的 docker-compose.yml 文件:
version: '3'
services:
db:
image: mariadb:5.5
restart: always
environment:
- MYSQL_HOST=localhost
- MYSQL_PORT=3306 # cannot change this port to other number
- MYSQL_ROOT_HOST=%
- MYSQL_DATABASE=test
- MYSQL_USER=belter
- MYSQL_PASSWORD=belter_2017
- MYSQL_ROOT_PASSWORD=123456_abc
volumes:
- /home/belter/mdbdata/mdb55:/var/lib/mysql
ports:
- "3302:3306"
web:
image: onlybelter/django_py35
command: python3 manage.py runserver 0.0.0.0:6001
volumes:
- .:/djcode
ports:
- "6001:6001"
depends_on:
- db
所以现在我们可以通过 mysql -h 127.0.0.1 -P 3302 -u root -p
直接在shell中连接此 docker-mysql ,但是我们必须使用Django settings.py
文件中的 db
和 3306
:
So now we can connect this docker-mysql by mysql -h 127.0.0.1 -P 3302 -u root -p
in shell directly, but we have to use db
and 3306
in django settings.py
file:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test',
'USER': 'belter',
# 'HOST': 'mariadb55',
'HOST': 'db', #<---
'PORT': '3306', #<---
'PASSWORD': 'belter_2017',
'default-character-set': 'utf8',
'OPTIONS': {
'sql_mode': 'traditional',
}
}
}
我们仍然可以通过在 docker-compose.yml
文件中运行额外的命令来检查此端口是否打开:
And we can still check if this port is open, by running extra command in docker-compose.yml
file:
...
web:
image: onlybelter/django_py35
command: /bin/sh -c "python check_db.py --service-name mysql --ip db --port 3306"
volumes:
- .:/djcode
...
这是 check_db.py 文件:
# check_db.py
import socket
import time
import argparse
""" Check if port is open, avoid docker-compose race condition """
parser = argparse.ArgumentParser(description='Check if port is open, avoid\
docker-compose race condition')
parser.add_argument('--service-name', required=True)
parser.add_argument('--ip', required=True)
parser.add_argument('--port', required=True)
args = parser.parse_args()
# Get arguments
service_name = str(args.service_name)
port = int(args.port)
ip = str(args.ip)
# Infinite loop
while True:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((ip, port))
if result == 0:
print("{0} port is open! Bye!".format(service_name))
break
else:
print("{0} port is not open! I'll check it soon!".format(service_name))
time.sleep(3)
顺便说一下,这是我用于构建 django-py35
的 Dockerfile :
By the way, this is my Dockerfile for build django-py35
:
FROM python:3.5-alpine
MAINTAINER Xin Xiong "xiongxin20008@126.com"
ENV PYTHONUNBUFFERED 1
RUN set -e; \
apk add --no-cache --virtual .build-deps \
gcc \
libc-dev \
linux-headers \
mariadb-dev \
python3-dev \
postgresql-dev \
freetype-dev \
libpng-dev \
g++ \
;
RUN mkdir /djcode
WORKDIR /djcode
ENV REFRESHED_AT 2017-12-25
ADD requirements.txt /djcode/
RUN pip install --no-cache-dir -r /djcode/requirements.txt
RUN pip install uwsgi
ADD . /djcode/ # copy . to /djcode/
EXPOSE 6001
从此处查看更多详细信息: https://github.com/OnlyBelter/django-compose
See more details from here: https://github.com/OnlyBelter/django-compose
这篇关于django无法在docker-compose中连接mysql的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!