You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose部署的MySQL用localhost连接报错,127.0.0.1正常的原因?

MySQL Docker Compose连接问题解析

问题描述

通过Docker Compose部署MySQL后,使用以下两个命令能正常连接:

  • mysql --host=127.0.0.1 --user=root --password=team6 --port=53366
  • mysql --host=0.0.0.0 --user=root --password=team6 --port=53366

但执行mysql --host=localhost --user=root --password=team6 --port=53366时,报错:

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

最终目标是让这段Node.js代码正常运行:

con = await mysql.createConnection({
  host:  'localhost',
  port:  '53366', //We need to consider adding new users
  user: 'root',
  password: 'team6',
  database: 'Yahtzee',
});

使用的Docker Compose文件如下:

# Compose file for creating a database named Yahtzee in a mysql container
version: '3.8'
services:
  team6db:
    image: mysql/mysql-server:latest
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: team6
      MYSQL_DATABASE: Yahtzee
      MYSQL_ROOT_HOST: '%'
    volumes:
      - team6db:/var/lib/mysql
      - ./Initdb.sql:/docker-entrypoint-initdb.d/Initdb.sql
      - ./InsertSampleGameRecords.sql:/docker-entrypoint-initdb.d/InsertSampleGameRecords.sql
    ports:
      - '53366:3306'

  team6phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    restart: always
    depends_on:
      - team6db
    environment:
      PMA_HOST: team6db
      PMA_USER: root
      PMA_PASSWORD: team
    ports:
      - '50086:80'

volumes:
  team6db:

原因解析

  1. 连接方式差异:MySQL客户端指定host=localhost时,默认优先使用Unix套接字连接,而非TCP/IP端口;而127.0.0.1或0.0.0.0会强制触发TCP/IP连接。
  2. Docker隔离性:MySQL运行在容器内,宿主机的Unix套接字和容器内的完全独立。用localhost连接时,宿主机客户端会尝试找本地的MySQL套接字,而非容器内的,自然无法匹配到正确的服务,进而抛出权限错误。
  3. 用户权限不匹配:你设置了MYSQL_ROOT_HOST='%',这仅授权root用户通过TCP/IP从任意主机连接,但MySQL中root@localhost是专门对应套接字连接的用户,这个用户要么没设置密码,要么在你指定MYSQL_ROOT_HOST='%'时未被正确创建。

解决方法

方法1:修改代码,强制TCP/IP连接

直接把代码中的host: 'localhost'改为host: '127.0.0.1',强制使用TCP/IP连接映射的53366端口,最直接有效:

con = await mysql.createConnection({
  host:  '127.0.0.1',
  port:  '53366',
  user: 'root',
  password: 'team6',
  database: 'Yahtzee',
});

方法2:映射容器套接字到宿主机

在Docker Compose的team6db服务中添加卷映射,把容器内的MySQL套接字目录同步到宿主机:

services:
  team6db:
    # 保留原有配置
    volumes:
      - team6db:/var/lib/mysql
      - ./Initdb.sql:/docker-entrypoint-initdb.d/Initdb.sql
      - ./InsertSampleGameRecords.sql:/docker-entrypoint-initdb.d/InsertSampleGameRecords.sql
      - ./mysql-socket:/var/run/mysqld  # 新增套接字映射

然后在Node.js代码中指定套接字路径:

con = await mysql.createConnection({
  host:  'localhost',
  port:  '53366',
  user: 'root',
  password: 'team6',
  database: 'Yahtzee',
  socketPath: './mysql-socket/mysqld.sock'  # 指定套接字路径
});

注意:先在宿主机创建./mysql-socket目录,并确保权限足够,避免容器无法写入。

方法3:创建支持套接字连接的root用户

进入MySQL容器,手动创建root@localhost用户并授权:

  1. 进入容器:docker exec -it team6db bash(替换为你的容器名称/ID)
  2. 登录MySQL:mysql -uroot -pteam6
  3. 执行SQL:
CREATE USER 'root'@'localhost' IDENTIFIED BY 'team6';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;

此方法需要配合方法2的套接字映射,否则宿主机客户端仍无法访问容器内的套接字。

内容的提问来源于stack exchange,提问作者Ilan Rosenbaum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 15:48:10