docker compose 使用节点 js 和 mysql - 无法与 mysql 连接

Posted

技术标签:

【中文标题】docker compose 使用节点 js 和 mysql - 无法与 mysql 连接【英文标题】:docker compose using node js and mysql - unable to connect with mysql 【发布时间】:2019-10-31 19:43:31 【问题描述】:

我正在尝试使用 docker 部署我的节点 js 应用程序,但是当我运行 docker compose 时,它​​最后会出现错误。我尝试了一些解决方案,例如使用 wait-for-it.sh 文件,但问题仍然存在。

docker-compose.yml

version: '3'
services:
  db:
    build:
      context: .
      dockerfile: ./docker/Dockerfile-mysql
    environment:
      - MYSQL_ALLOW_EMPTY_PASSWORD=yes
      - MYSQL_DATABASE=dbautokab
      - MYSQL_USER=root
      - MYSQL_PASSWORD=
    networks:
      - helicopter-network
    healthcheck:
      test: "exit 0"

  helicopter-api:
    build:
      context: .
      dockerfile: ./docker/Dockerfile-api
    depends_on:
      - db
    networks: ['helicopter-network']
    environment:
        - PORT=3000
        - DATABASE_HOST=db
        - DATABASE_PASSWORD=
        - EGG_SERVER_ENV=local
        - NODE_ENV=development
    ports:
      - "3000:3000"
networks:
  helicopter-network:
    driver: bridge

Dockerfile-api

FROM node:10-slim

USER node

RUN mkdir -p /home/node/app

WORKDIR /home/node/app

COPY --chown=node package*.json ./

RUN npm install

COPY --chown=node . .

COPY wait-for-it.sh /

ENV HOST=0.0.0.0 PORT=3000

EXPOSE $PORT

# Run when the container launches
#CMD [ "node", "." ]
CMD /wait-for-it.sh db:3306 -- npm start

Dockerfile-mysql

FROM mysql 

COPY ./docker/init_db.sql /docker-entrypoint-initdb.d/

init_db.sql

CREATE DATABASE IF NOT EXISTS dbautokab;
GRANT ALL PRIVILEGES on dbautokab.*
TO 'root'@'%'
WITH GRANT OPTION;

db.js

var mysql = require('mysql');

var db_config = 
host     : '127.0.0.1', // Your host - either local or cloud  
user     : 'root', // your username
password : '', // your password
database : 'dbautokab' // database name
;

var connection;

function handleDisconnect() 
connection = mysql.createConnection(db_config); // Recreate the     connection, since
                                                // the old one cannot be reused.

connection.connect(function(err)               // The server is either down
    if(err)                                      // or restarting (takes a while sometimes).
        console.log('error when connecting to db:', err);
        setTimeout(handleDisconnect, 2000); // We introduce a delay before attempting to reconnect,
    

                                 // to avoid a hot loop, and to allow our node script to
);                                     // process asynchronous requests in the meantime.
                                        // If you're also serving http, display a 503 error.
connection.on('error', function(err) 
    console.log('db error', err);
    if(err.code === 'PROTOCOL_CONNECTION_LOST')  // Connection to the MySQL server is usually
        handleDisconnect();                         // lost due to either server restart, or a
     else                                       // connnection idle timeout (the wait_timeout
        throw err;                                  // server variable configures this)
    
);


handleDisconnect();

module.exports = connection;

错误:

直升机-api_1 |服务器已启动 3000 直升机-api_1 |连接到 db 时出错: 错误:连接 ECONNREFUSED 127.0.0.1:3306 直升机-api_1 |在 TCPConnectWrap.afterConnect [as oncomplete] (net.js:1106:14) 直升机-api_1 | -------------------- 直升机-api_1 |在 Protocol._enqueue (/home/node/app/node_modules/mysql/lib/protocol/Protocol.js:144:48) 直升机-api_1 |在 Protocol.handshake (/home/node/app/node_modules/mysql/lib/protocol/Protocol.js:51:23) 直升机-api_1 |在 Connection.connect (/home/node/app/node_modules/mysql/lib/Connection.js:119:18) 直升机-api_1 |在 handleDisconnect (/home/node/app/db.js:16:16) 直升机-api_1 |在对象。 (/home/node/app/db.js:35:1) 直升机-api_1 |在 Module._compile (internal/modules/cjs/loader.js:776:30) 直升机-api_1 |在 Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10) 直升机-api_1 |在 Module.load (internal/modules/cjs/loader.js:653:32) 直升机-api_1 |在 tryModuleLoad (internal/modules/cjs/loader.js:593:12) 直升机-api_1 |在 Function.Module._load (internal/modules/cjs/loader.js:585:3) 直升机-api_1 |错误号:'ECONNREFUSED', 直升机-api_1 |代码:'ECONNREFUSED', 直升机-api_1 |系统调用:“连接”, 直升机-api_1 |地址:'127.0.0.1', 直升机-api_1 |端口:3306, 直升机-api_1 |致命:真 db_1 | db_1 | /usr/local/bin/docker-entrypoint.sh:运行 /docker-entrypoint-initdb.d/init_db.sql db_1 | db_1 |

【问题讨论】:

【参考方案1】:

您的nodejs appdb 不在同一个容器中,因此db.js 无法访问带有ip 127.0.0.1 的数据库。

container_name: mydb 添加到您的数据库服务中,如下所示:

services:
  db:
    build:
      context: .
      dockerfile: ./docker/Dockerfile-mysql
    container_name: mydb

然后,在db.js使用容器名访问db:

var db_config = 
 host     : 'mydb', // Your host - either local or cloud  
 user     : 'root', // your username
 password : '', // your password
 database : 'dbautokab' // database name
;

【讨论】:

我已经尝试过,现在又遇到了另一个错误。连接数据库时出错: 错误:ER_NOT_SUPPORTED_AUTH_MODE:客户端不支持服务器请求的身份验证协议;考虑升级 MySQL 客户端 是的,这是另一个问题。看看this post 是否有帮助?如果没有,也许你需要提出另一个问题......

以上是关于docker compose 使用节点 js 和 mysql - 无法与 mysql 连接的主要内容,如果未能解决你的问题,请参考以下文章

docker-compose 用于将 VS Code 中的 node.js 调试器附加到 WSL docker 中的节点进程

找不到在 docker compose 环境中运行的节点 js 应用程序的模块

docker-compose搭建redis-cluster集群

使用 docker-compose up 运行时如何优雅地停止 Dockerized Python ROS2 节点?

在节点 Docker 容器中运行项目时出现 Tailwind CSS EACCESS 错误(Docker Compose)

docker-swarm 和 docker-compose 如何动态添加节点并让它们可以被服务解析