【问题标题】:Django cannot connect to mysqlDjango 无法连接到 mysql
【发布时间】:2021-02-05 18:02:34
【问题描述】:

所以我把我的 django 应用程序和 mysql 放在 docker 容器中。这就是我的工作

Docker 文件

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

这是我的 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

然后我用docker-compose up运行它

我收到此错误

MySQLdb._exceptions.OperationalError: (2002, "Can't connect to local MySQL 服务器通过 socket '/var/run/mysqld/mysqld.sock' (2)")

这是我的数据库设置

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

我的 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

那么我该如何解决呢?我错过了什么吗?

完整日志

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.

【问题讨论】:

    标签: mysql django docker


    【解决方案1】:

    您的数据库设置已将HOST 设置为localhost。当您的 django 服务在容器中启动时,服务将在同一容器 (django) 上查找 mysql,而不是连接到实际的 mysql 容器。

    • HOST 值更改为db(数据库容器名称)。
    • 在 docker compose 中将 depends_on 添加到 web,以确保 web 容器等待 db 启动并运行。
    • 您可能还需要在 mysql 容器中设置 MYSQL_ROOT_HOST=% 环境变量以允许 mysql 接受远程连接。

    编辑

    您可以尝试使用以下选项等待数据库容器启动。

    【讨论】:

    • 您好,感谢您的回答。当我更改主机时,错误消息是这样的django.db.utils.OperationalError: (1130, "Host '172.26.0.3' is not allowed to connect to this MySQL server")
    • 你需要允许mysql服务器允许远程连接,更新了上面的步骤。这应该适用于 5.7.x 版本。
    • 嗨,它正在工作,我如何等待数据库先启动然后运行我的 django 应用程序?
    • 您将不得不等待 db 容器启动,我已编辑答案以添加一些可用选项。
    猜你喜欢
    • 2019-05-22
    • 2018-06-10
    • 2019-04-11
    • 1970-01-01
    • 2015-11-24
    • 1970-01-01
    • 2014-04-09
    相关资源
    最近更新 更多