Докеризованное приложение django не может подключиться к серверу mysql на localhost

У меня есть Dockerized django приложение, которое я запускаю, и я пытаюсь подключить его к серверу mysql, который у меня есть, который перенаправляется через порт из другого контейнера docker. Я уже провел тест на разумность и подтвердил, что могу подключиться к моему серверу mysql с помощью mysql workbench на моем localhost.

У меня есть мое докеризованное приложение django, работающее на network_mode: host, поэтому я думал, что смогу просто подключиться. К сожалению, сейчас я выхожу из строя на docker-compose build с ошибкой django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on '127.0.0.1' (115)")

Принятое решение этой проблемы означает, что мое докеризованное приложение django сможет успешно подключиться к моему серверу mysql, работающему под управлением localhost:29998

SETTINGS.PY (приложение Django)

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mytestdb',
        'USER': 'userone',
        'PASSWORD': 'password',
        'HOST': '127.0.0.1',
        'PORT': '29998',
    }
}

DJANGO App compose file

version: '3.3'
services:
  mydjangoapp:
    container_name: mydjangoapp
    restart: always
    env_file: .env
    build: .
    volumes:
      - ./apps:/apps
      - ./core:/core
    network_mode: host

Django app dockerfile:

FROM python:3.9

COPY . .

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

COPY requirements.txt .
# install python dependencies
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt

# running migrations
RUN python manage.py migrate

# gunicorn
CMD ["gunicorn", "--config", "gunicorn-cfg.py", "core.wsgi"]

Докеризованный сервер mysql (порт перенаправлен на localhost)

version: '3.3'

services:
  mysql:
    image: mysql:latest
    container_name: mymysqlserver
    environment:
      - MYSQL_DATABASE=mytestdb
      - MYSQL_USER=userone
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_PASSWORD=password
    ports:
      - 29998:3306

Нужно ли мне создать какую-то сеть/мост docker для того, чтобы это работало? (никогда не пробовал этого раньше).

Я уже пробовал следующие решения: sol1 (network_mode=host), sol2,

Почему бы не поместить эти два сервиса в один файл docker compose и запустить его оттуда, например, так:

version: '3.3'
services:
  mydjangoapp:
    container_name: mydjangoapp
    restart: always
    env_file: .env
    build: .
    volumes:
      - ./apps:/apps
      - ./core:/core
    network_mode: host
    depends_on: mysql
mysql:
    image: mysql:latest
    container_name: mymysqlserver
    environment:
      - MYSQL_DATABASE=mytestdb
      - MYSQL_USER=userone
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_PASSWORD=password
    ports:
      - 29998:3306

А затем обновите настройки следующим образом:

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

Таким образом, связь между Django и MySQL будет осуществляться через сеть docker, а не через сеть хост-машины.

Ваше приложение django не работает, потому что:

  1. Вы запускаете контейнеры в отдельных файлах docker-compose, из-за этого контейнер django работает в другой сети, чем контейнер mysql.

  2. Вы пытаетесь подключиться к localhost (127.0.0.1) внутри контейнера django. Этот localhost отличается от 'localhost' вашего компьютера и отличается от 'localhost' контейнера mysql. Существует 3 различных сети. Если вы хотите соединить контейнер django с контейнером mysql, используйте одну и ту же сеть ( сеть докера или IP вашего компьютера, назначенный маршрутизатором, также подойдет).

  3. Вы пытаетесь подключиться к открытому порту 29998, но этот порт открыт из контейнера mysql на ваш компьютер. Если вы пытаетесь установить внутреннее соединение, вам следует использовать порт 3306. (Если вы используете внутреннее соединение, то вам не нужно открывать порт)

    .
Вернуться на верх