Django cannot connect to mysql

走远了吗. 提交于 2021-02-20 02:57:09

问题


So i put my django app and mysql inside docker container. Here is what i do

Docker file

FROM python:3
ENV PYTHONUNBUFFERED 1
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
COPY . /app

and here is my docker-compose-yml

version: '3'
services:
  db:
    container_name: database
    image: mysql:8
    ports:
      - "3306:3306"
    command: --default-authentication-plugin=mysql_native_password

    environment:
      - MYSQL_DATABASE=django_example
      - MYSQL_USER=root
      - MYSQL_PASSWORD=123456
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_ROOT_HOST=%
    volumes:
      - "./db:/var/lib/mysql"
  web:
    container_name: app
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    ports:
      - "8000:8000"
    volumes:
      - .:/app
      - /tmp/app/mysqld:/run/mysqld
    depends_on: 
      - db

Then i run it with docker-compose up

I get this error

MySQLdb._exceptions.OperationalError: (2002, "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)")

Here is my database setting

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_example',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

My docker ps --all

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                               NAMES
c61ac60bc037        mysql:latest        "docker-entrypoint.s…"   2 minutes ago       Up 34 seconds               0.0.0.0:3306->3306/tcp, 33060/tcp   py_rest_api_db_1
f00857755a46        py_rest_api_web     "python manage.py ru…"   5 minutes ago       Up 34 seconds               0.0.0.0:8000->8000/tcp              py_rest_api_web_1

So how can i fix it ? did i miss something?

Full Log

Starting database ... done
Starting app      ... done
Attaching to database, app
database | 2020-10-23 06:03:42+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.22-1debian10 started.
database | 2020-10-23 06:03:42+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
database | 2020-10-23 06:03:42+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.22-1debian10 started.
database | 2020-10-23T06:03:43.191491Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.22) starting as process 1
database | 2020-10-23T06:03:43.199528Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
database | 2020-10-23T06:03:43.214677Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
app    | Watching for file changes with StatReloader
app    | Performing system checks...
app    | 
app    | System check identified no issues (0 silenced).
app    | Exception in thread django-main-thread:
app    | Traceback (most recent call last):
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
app    |     self.connect()
app    |   File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
app    |     return func(*args, **kwargs)
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
app    |     self.connection = self.get_new_connection(conn_params)
app    |   File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
app    |     return func(*args, **kwargs)
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/backends/mysql/base.py", line 234, in get_new_connection
app    |     return Database.connect(**conn_params)
app    |   File "/usr/local/lib/python3.9/site-packages/MySQLdb/__init__.py", line 130, in Connect
app    |     return Connection(*args, **kwargs)
app    |   File "/usr/local/lib/python3.9/site-packages/MySQLdb/connections.py", line 185, in __init__
app    |     super().__init__(*args, **kwargs2)
app    | MySQLdb._exceptions.OperationalError: (2002, "Can't connect to MySQL server on 'db' (115)")
app    |
app    | The above exception was the direct cause of the following exception:
app    |
app    | Traceback (most recent call last):
app    |   File "/usr/local/lib/python3.9/threading.py", line 950, in _bootstrap_inner
app    |     self.run()
app    |   File "/usr/local/lib/python3.9/threading.py", line 888, in run
app    |     self._target(*self._args, **self._kwargs)
app    |   File "/usr/local/lib/python3.9/site-packages/django/utils/autoreload.py", line 53, in wrapper
app    |     fn(*args, **kwargs)
app    |   File "/usr/local/lib/python3.9/site-packages/django/core/management/commands/runserver.py", line 121, in inner_run
app    |     self.check_migrations()
app    |   File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 459, in check_migrations
app    |     executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/migrations/executor.py", line 18, in __init__
app    |     self.loader = MigrationLoader(self.connection)
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 53, in __init__
app    |     self.build_graph()
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 216, in build_graph
app    |     self.applied_migrations = recorder.applied_migrations()
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 77, in applied_migrations
app    |     if self.has_table():
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 55, in has_table
app    |     with self.connection.cursor() as cursor:
app    |   File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
app    |     return func(*args, **kwargs)
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 259, in cursor
app    |     return self._cursor()
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 235, in _cursor
app    |     self.ensure_connection()
app    |   File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
app    |     return func(*args, **kwargs)
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
app    |     self.connect()
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/utils.py", line 90, in __exit__
app    |     raise dj_exc_value.with_traceback(traceback) from exc_value
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
app    |     self.connect()
app    |   File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
app    |     return func(*args, **kwargs)
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
app    |     self.connection = self.get_new_connection(conn_params)
app    |   File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
app    |     return func(*args, **kwargs)
app    |   File "/usr/local/lib/python3.9/site-packages/django/db/backends/mysql/base.py", line 234, in get_new_connection
app    |     return Database.connect(**conn_params)
app    |   File "/usr/local/lib/python3.9/site-packages/MySQLdb/__init__.py", line 130, in Connect
app    |     return Connection(*args, **kwargs)
app    |   File "/usr/local/lib/python3.9/site-packages/MySQLdb/connections.py", line 185, in __init__
app    |     super().__init__(*args, **kwargs2)
app    | django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on 'db' (115)")
database | 2020-10-23T06:03:45.429683Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
database | 2020-10-23T06:03:45.557475Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
database | 2020-10-23T06:03:45.635937Z 0 [System] [MY-010229] [Server] Starting XA crash recovery...
database | 2020-10-23T06:03:45.639397Z 0 [System] [MY-010232] [Server] XA crash recovery finished.
database | 2020-10-23T06:03:45.805023Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
database | 2020-10-23T06:03:45.805494Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
database | 2020-10-23T06:03:45.818355Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
database | 2020-10-23T06:03:45.855862Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.22'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.

回答1:


Your Database settings has HOST set to localhost. when your django service spins up in container, service will look for mysql on the same container (django) instead of connecting to actual mysql container.

  • Change the HOST value to db (db container name).
  • Add a depends_on to web in docker compose, to make sure web container waits for db to be up and running.
  • You may also need to set MYSQL_ROOT_HOST=% environment variable in mysql container to allow mysql to accept remote connections.

Edit

You can try using below options to wait for db container to be up.

  • use wait-for-sh as suggested in docker official docs
  • or try the approach here


来源:https://stackoverflow.com/questions/64487009/django-cannot-connect-to-mysql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!