django无法在docker-compose中连接mysql

我对docker非常陌生,现在我想通过docker-compose在Docker中运行django,但是我总是得到这个错误:

我使用Docker version 17.09.1-ce, build 19e2cf6Docker version 17.09.1-ce, build 19e2cf6 docker-compose version 1.18.0, build 8dd22a9

django.db.utils.OperationalError:(2003,'无法连接到'mariadb55'(111“连接被拒绝)”)上的MySQL服务器

运行后,我可以正确地连接数据库docker-compose up db在本地或远程docker-compose up db ,我甚至可以在anaconda虚拟环境中正确运行python manage.py runserver 0.0.0.0:6001 ,通过设置参数settings.py在docker中连接db服务文件如下:

 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 

我几乎试过了我能find的所有东西,但仍然无法弄清楚,任何帮助都会很好!

我曾经尝试过:

Docker撰写mysql连接失败

使用docker-compose链接django和mysql容器

由docker-compose连接到postgres的Django连接

您应该在settings.py文件中使用容器名称而不是localhost(或127.0.0.1)。 尝试使用container_name属性docker-compose.yml文件中的db服务提供容器名称,并使用container_name的值replacesettings.py的主机名。 (请确保它们位于Docker组合为您创build的同一networking中。)

最后,我明白了! 关键是,就像@SangminKi​​m所说的,我需要在settings.py使用3306而不是3302 ,并使用db作为HOST而不是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连接这个docker-mysql ,但是我们必须在django settings.py文件中使用db3306

 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文件中运行额外的命令来检查这个端口是否打开:

 ... 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) 

顺便说一句,这是我的Dockerfile构builddjango-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