Docker环境下Django无法连接MySQL的问题求助
Django+Docker容器化部署无法连接MySQL问题
我尝试用Docker容器化部署Django+MySQL项目,但一直无法连接MySQL,以下是错误信息、配置文件,求解决。
错误回溯
testcasebooks-backend-1 | Traceback (most recent call last): testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 289, in ensure_connection testcasebooks-backend-1 | self.connect() testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner testcasebooks-backend-1 | return func(*args, **kwargs) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 270, in connect testcasebooks-backend-1 | self.connection = self.get_new_connection(conn_params) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner testcasebooks-backend-1 | return func(*args, **kwargs) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 247, in get_new_connection testcasebooks-backend-1 | connection = Database.connect(**conn_params) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/MySQLdb/__init__.py", line 121, in Connect testcasebooks-backend-1 | return Connection(*args, **kwargs) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/MySQLdb/connections.py", line 193, in __init__ testcasebooks-backend-1 | super().__init__(*args, **kwargs2) testcasebooks-backend-1 | MySQLdb.OperationalError: (2002, "Can't connect to local MySQL server through socket '/run/mysqld/mysqld.sock' (2)") testcasebooks-backend-1 | testcasebooks-backend-1 | The above exception was the direct cause of the following exception: testcasebooks-backend-1 | testcasebooks-backend-1 | Traceback (most recent call last): testcasebooks-backend-1 | File "/service/./manage.py", line 22, in <module> testcasebooks-backend-1 | main() testcasebooks-backend-1 | File "/service/./manage.py", line 18, in main testcasebooks-backend-1 | execute_from_command_line(sys.argv) testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line testcasebooks-backend-1 | utility.execute() testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute testcasebooks-backend-1 | self.fetch_command(subcommand).run_from_argv(self.argv) testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 412, in run_from_argv testcasebooks-backend-1 | self.execute(*args, **cmd_options) testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 458, in execute testcasebooks-backend-1 | output = self.handle(*args, **options) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 106, in wrapper testcasebooks-backend-1 | res = handle_func(*args, **kwargs) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/core/management/commands/migrate.py", line 100, in handle testcasebooks-backend-1 | self.check(databases=[database]) testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 485, in check testcasebooks-backend-1 | all_issues = checks.run_checks( testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/core/checks/registry.py", line 88, in run_checks testcasebooks-backend-1 | new_errors = check(app_configs=app_configs, databases=databases) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/core/checks/database.py", line 13, in check_database_backends testcasebooks-backend-1 | issues.extend(conn.validation.check(**kwargs)) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/mysql/validation.py", line 9, in check testcasebooks-backend-1 | issues.extend(self._check_sql_mode(**kwargs)) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/mysql/validation.py", line 14, in _check_sql_mode testcasebooks-backend-1 | self.connection.sql_mode & {"STRICT_TRANS_TABLES", "STRICT_ALL_TABLES"} testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/utils/functional.py", line 57, in __get__ testcasebooks-backend-1 | res = instance.__dict__[self.name] = self.func(instance) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 443, in sql_mode testcasebooks-backend-1 | sql_mode = self.mysql_server_data["sql_mode"] testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/utils/functional.py", line 57, in __get__ testcasebooks-backend-1 | res = instance.__dict__[self.name] = self.func(instance) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 399, in mysql_server_data testcasebooks-backend-1 | with self.temporary_connection() as cursor: testcasebooks-backend-1 | File "/usr/local/lib/python3.11/contextlib.py", line 137, in __enter__ testcasebooks-backend-1 | return next(self.gen) testcasebooks-backend-1 | ^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 705, in temporary_connection testcasebooks-backend-1 | with self.cursor() as cursor: testcasebooks-backend-1 | ^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner testcasebooks-backend-1 | return func(*args, **kwargs) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 330, in cursor testcasebooks-backend-1 | return self._cursor() testcasebooks-backend-1 | ^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 306, in _cursor testcasebooks-backend-1 | self.ensure_connection() testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner testcasebooks-backend-1 | return func(*args, **kwargs) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 288, in ensure_connection testcasebooks-backend-1 | with self.wrap_database_errors: testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__ testcasebooks-backend-1 | raise dj_exc_value.with_traceback(traceback) from exc_value testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 289, in ensure_connection testcasebooks-backend-1 | self.connect() testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner testcasebooks-backend-1 | return func(*args, **kwargs) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 270, in connect testcasebooks-backend-1 | self.connection = self.get_new_connection(conn_params) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner testcasebooks-backend-1 | return func(*args, **kwargs) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 247, in get_new_connection testcasebooks-backend-1 | connection = Database.connect(**conn_params) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/MySQLdb/__init__.py", line 121, in Connect testcasebooks-backend-1 | return Connection(*args, **kwargs) testcasebooks-backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ testcasebooks-backend-1 | File "/usr/local/lib/python3.11/site-packages/MySQLdb/connections.py", line 193, in __init__ testcasebooks-backend-1 | super().__init__(*args, **kwargs2) testcasebooks-backend-1 | django.db.utils.OperationalError: (2002, "Can't connect to local MySQL server through socket '/run/mysqld/mysqld.sock' (2)") testcasebooks-backend-1 exited with code 1
配置文件
docker-compose.yml
services: # Backend Django backend: build: . command: bash -c "./manage.py collectstatic --noinput && ./manage.py migrate && ./manage.py runserver 0.0.0.0:8000" ports: - '8000:8000' depends_on: - db volumes: - .:/service env_file: - .env # MySQL db: image: mysql:8.2.0 env_file: - .env volumes: - ./data/mysql/db:/var/lib/mysql ports: - '3306:3306' # Redis redis: image: redis:7.0.5-alpine # Celery Worker celery: restart: always build: context: . entrypoint: celery command: -A celery_app.app worker --loglevel=info volumes: - .:/service container_name: celery depends_on: - db - redis - backend links: - redis env_file: - .env
.env
MYSQL_DATABASE=test_db MYSQL_USER=user MYSQL_PASSWORD=password MYSQL_ROOT_PASSWORD=password MYSQL_PORT=3306 MYSQL_HOST=localhost
Django数据库配置
DB_USER = os.environ.get('MYSQL_USER') DB_PASS = os.environ.get('MYSQL_PASSWORD') DB_NAME = os.environ.get('MYSQL_DATABASE') DB_PORT = os.environ.get('MYSQL_PORT') DB_HOST = os.environ.get('MYSQL_HOST') DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': DB_NAME, 'USER': DB_USER, 'PASSWORD': DB_PASS, 'HOST': DB_HOST, 'PORT': DB_PORT, } }
解决方法
1. 修正数据库连接地址
Docker Compose默认创建的网络中,容器之间通过服务名互相访问。当前.env里的MYSQL_HOST=localhost会让Django容器尝试连接自身的MySQL服务(不存在),而非db容器。修改.env:
MYSQL_HOST=db
2. 确保MySQL服务就绪后再启动Django
depends_on仅保证容器启动顺序,不确保MySQL服务完全就绪。可以给Django的启动命令添加等待逻辑,修改docker-compose.yml中backend的command:
command: bash -c "until nc -z db 3306; do sleep 1; done && ./manage.py collectstatic --noinput && ./manage.py migrate && ./manage.py runserver 0.0.0.0:8000"
注意:需要在Django的Dockerfile中安装netcat工具,添加命令:
RUN apt-get update && apt-get install -y netcat-traditional && rm -rf /var/lib/apt/lists/*
3. 验证MySQL容器配置
进入MySQL容器确认数据库和用户是否正确创建:
docker exec -it [你的MySQL容器名] mysql -u root -p # 输入MYSQL_ROOT_PASSWORD后执行以下命令 SHOW DATABASES; -- 确认test_db存在 SELECT user FROM mysql.user; -- 确认user存在
内容的提问来源于stack exchange,提问作者Mihail Bury
相关产品推荐
相关产品推荐

