簡體   English   中英

在 Docker 中運行 MySQL/MariaDB 時出現 django.db.utils.OperationalError:在“讀取初始通信數據包”時失去與 MySQL 服務器的連接

[英]django.db.utils.OperationalError when running MySQL/MariaDB in Docker: Lost connection to MySQL server at 'reading initial communication packet'

在 Docker 容器中運行 MySQL/MariaDB:

docker run -p 3306:3306 --name $(DATABASE_NAME) -v /tmp/mysql:/var/lib/mysql -e MYSQL_DATABASE=$(DATABASE_NAME) -e MYSQL_USER=$(DATABASE_USER) -e MYSQL_ROOT_PASSWORD=$(DATABASE_PASSWORD) -d mariadb:latest > /dev/null

然后在本地運行 Django 版本 4:

manage.py runserver 127.0.0.1:8000

錯誤

django.db.utils.OperationalError: (2013, "Lost connection to MySQL server at 'reading initial communication packet', system error: 2")

我可以使用 MySQL Workbench 以及以下命令成功連接到數據庫:

mysql -h 127.0.0.1 -P 3306 -u root -p <database>

我正在從 Makefile 啟動 Django 和 MySQL/MariaDB Docker 容器。

生成文件

SHELL := /bin/bash

.PHONY: dj-start-local
dj-start-local: start-mysql
    PYTHONPATH=. django_project/src/manage.py runserver 127.0.0.1:8000

.PHONY: start-mysql
start-mysql:
    docker run -p 3306:3306 --name $(DATABASE_NAME) -v /tmp/mysql:/var/lib/mysql -e MYSQL_DATABASE=$(DATABASE_NAME) -e MYSQL_USER=$(DATABASE_USER) -e MYSQL_ROOT_PASSWORD=$(DATABASE_PASSWORD) -d mariadb:latest > /dev/null

該問題可能是由於競爭條件造成的,其中 Django 試圖在數據庫准備好之前連接到數據庫。 嘗試在啟動 Docker 容器后等待幾秒鍾。

生成文件

.PHONY: start-mysql
start-mysql:
    docker run -p 3306:3306 --name $(DATABASE_NAME) -v /tmp/mysql:/var/lib/mysql -e MYSQL_DATABASE=$(DATABASE_NAME) -e MYSQL_USER=$(DATABASE_USER) -e MYSQL_ROOT_PASSWORD=$(DATABASE_PASSWORD) -d mariadb:latest > /dev/null
    sleep 4

使用容器中的healthcheck.sh 使用MARIADB_MYSQL_LOCALHOST_USER=1創建腳本可用於訪問數據庫的mysql@localhost用戶,

無論時間如何,運行狀況檢查都會等到其完全啟動。

生成文件:

.PHONY: start-mariadb
start-mariadb:
    docker run -p 3306:3306 --name $(DATABASE_NAME) \
        -e MARIADB_DATABASE=$(DATABASE_NAME) \
        -e MARIADB_USER=$(DATABASE_USER) \
        -e MARIADB_PASSWORD=$(DATABASE_PASSWORD) \
        -e MARIADB_ROOT_PASSWORD=$(DATABASE_PASSWORD) \
        -e MARIADB_MYSQL_LOCALHOST_USER=1 \
        -v /tmp/mysql:/var/lib/mysql \
        -d mariadb:latest
    while ! docker exec $(DATABASE_NAME) healthcheck.sh --su=mysql --connect --innodb_initialized; do sleep 1; done
    docker exec --user mysql $(DATABASE_NAME) mariadb -e 'select "hello world"'

測試運行:

$ make start-mariadb 
docker run -p 3306:3306 --name dd \
    -e MARIADB_DATABASE=dd \
    -e MARIADB_USER=dd \
    -e MARIADB_PASSWORD=dd \
    -e MARIADB_ROOT_PASSWORD=dd \
    -e MARIADB_MYSQL_LOCALHOST_USER=1 \
    -d mariadb:latest
53066fffa293ed061743024e387bd7fb6f1c664efd603c7a657ba88e307be308
while ! docker exec dd healthcheck.sh --su=mysql --connect --innodb_initialized; do sleep 1; done
healthcheck connect failed
healthcheck connect failed
healthcheck connect failed
healthcheck connect failed
docker exec --user mysql dd mariadb -e 'select "hello world"'
hello world
hello world

注意:添加MARIADB_PASSWORD否則將不會創建數據庫/用戶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM