skip to Main Content

I have a Dockerized django application I am running and I am trying to connect it to a mysql server I have that is port forwarded from another docker container. I have done a sanity test already and confirmed that I can connect to my mysql server using mysql workbench on my localhost.

I have my dockerized django application running on network_mode: host so I thought I would be able to simply connect. Sadly I currently error out on docker-compose build with the error django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on '127.0.0.1' (115)")

An accepted resolution to this issue means that my dockerized django application would be able to connect successfully to my mysql server running localhost:29998

SETTINGS.PY (Django Application)

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"]

Dockerized mysql server (port forwarded to 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

Do I need to create some sort of docker network / bridge for this to work? (never tried that before).

I have already attempted the following solutions: sol1 (network_mode=host), sol2,

2

Answers


  1. Why not put the two services in same docker compose file and run it from there, like this:

    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
    

    And then update the settings like this:

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

    In that way, the communication between Django and MySQL will be done through docker network, rather than accessing the host machine network.

    Apart from that, you need to change the Dockerfile, so that the migration runs after the MySQL server is running. To ensure that, you can add the migration command in the CMD part:

    CMD ["sh", "-c", "python manage.py migrate;gunicorn --config gunicorn-cfg.py core.wsgi"]
    
    Login or Signup to reply.
  2. You django app is not working because:

    1. You are running the containers in separated docker-compose files, this causes django container runs in different network than mysql container.

    2. You are trying to connect to localhost (127.0.0.1) inside the django container. This localhost is different to ‘localhost’ of your computer and is different to the ‘localhost’ of mysql container. There are 3 different networks. If you want to connect django container with mysql container use the same network (docker network or your computer IP assigned by a router also will works).

    3. You are trying to connect to the exposed port 29998, but this port is exposed from mysql container to your computer. If you are trying to make an internal connection you should use 3306. (If you are using an internal connection, then you don’t need to expose the port)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search