Docker化Node应用连接MySQL数据库时出现权限拒绝问题
问题分析与解决方案
核心错误点
- Sequelize参数顺序完全错误:Sequelize构造函数的正确顺序为
(数据库名, 用户名, 密码, 配置项),你当前代码将用户名、密码、数据库名的顺序搞反,导致凭据不匹配。 - MySQL容器未初始化目标数据库:Docker官方MySQL镜像需要
MYSQL_DATABASE环境变量自动创建指定数据库,否则admin用户没有对应数据库的访问权限。 - 健康检查命令格式错误:
mysqladmin ping的密码参数不需要引号,且当前命令未正确传递root密码,导致健康检查失败并干扰服务依赖逻辑。 - 数据库Host配置错误:Docker Compose中应使用服务名
mysql而非容器名mysql2作为连接地址,默认网络通过服务名解析容器IP。
修正后的代码
1. Sequelize数据库实例代码
const { Sequelize } = require("sequelize"); require("dotenv").config(); // 修正参数顺序:数据库名 -> 用户名 -> 密码 const sequelize = new Sequelize("app_db", "admin", "password", { host: "mysql", // 使用docker-compose中的服务名 dialect: "mysql", port: 3306, }); module.exports = sequelize;
2. Docker Compose配置文件
services: server: build: context: . ports: - "3001:3001" depends_on: mysql: condition: service_healthy # 可选:用环境变量替代硬编码凭据,提升可维护性 environment: DB_NAME: app_db DB_USER: admin DB_PASS: password DB_HOST: mysql mysql: image: mysql:8.0.33 container_name: mysql2 environment: MYSQL_USER: admin MYSQL_ROOT_PASSWORD: password MYSQL_PASSWORD: password MYSQL_DATABASE: app_db # 新增:自动创建目标数据库 ports: - "3307:3306" healthcheck: # 修正密码格式:-p后直接跟密码,无空格无引号 test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-ppassword"] interval: 30s timeout: 10s retries: 5 start_period: 30s
3. Dockerfile(仅修正格式问题)
FROM node:20-alpine WORKDIR /server COPY package.json . RUN npm install --production COPY . . EXPOSE 3001 CMD ["node", "index.js"]
验证步骤
- 清理旧环境:执行
docker-compose down -v彻底删除旧容器和数据卷,避免残留配置干扰 - 重新构建启动:执行
docker-compose up --build - 检查日志:
- MySQL容器应输出
ready for connections - Node容器应无
AccessDeniedError报错
- MySQL容器应输出
内容的提问来源于stack exchange,提问作者Marko
相关产品推荐
相关产品推荐

