NodeJS и Sequelize не могут подключиться к MySQL в docker compose - PullRequest
0 голосов
/ 20 февраля 2020

У меня очень похожая проблема, которая появляется здесь: Node.js подключение к MySQL Docker контейнеру ECONNREFUSED

Но, к сожалению, предлагаемое решение не работает. У меня есть проект NodeJS с Typescript (возможно, не связанным), Sequelize и базой данных MySQL. Я создал docker -компонентный файл со скриптами, которые их настраивают и раскручивают, а также на основе скриптов github, чтобы управлять ими всеми.

script/setup просто создает том для БД и раскручиваем его:

...
docker-compose down
docker volume create --name=tournaments-data
docker-compose up -d tournaments-db

Как только это закончится, я запускаю script/start, который просто раскручивает веб-приложение:

...
docker-compose up web
version: '3'

volumes:
  tournaments-data:

services:
  base: &app_base
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - tournaments-db

  web:
    <<: *app_base
    command: npm run watch-debug
    volumes:
      - ./dist:/usr/src/app/dist
    ports:
      - 3000:3000
      - 5858:5858

  tournaments-db:
    image: mysql:5.6.45
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 'whatever'
      MYSQL_DATABASE: tournaments
    expose:
      - '3307'
    ports:
      - '3307:3306'
    volumes:
      - tournaments-data:/var/lib/mysql

Моя конфигурация сиквелиза выглядит следующим образом:

...
development: {
    username: 'root',
    password: 'whatever',
    database: 'tournaments',
    host: 'tournaments-db',
    port: '3307',
    dialect: 'mysql',
    operatorsAliases: false,
  }
...

Все контейнеры вращаются правильно, и я могу подключить успешно в контейнер MySQL как из командной строки, используя это: mysql -uroot -p -h 127.0.0.1 -P 3307 --protocol=tcp, а также используя JetBrains Datagrip.

Похоже, приложение NodeJS не может корректно подключиться к mysql db, поскольку я получаю следующую ошибку:

Unable to connect to the database: ConnectionRefusedError [SequelizeConnectionRefusedError]: connect ECONNREFUSED 127.0.0.1:3306

Я попытался дать root доступ со всех IP-адресов (и не только с локального хоста), но это тоже не сработало. Также подумал, что это проблема с сетью docker -compose, поэтому я проверил, что они находятся в одной сети (они есть), также попытался создать для них другую сеть с помощью docker -compose, но это тоже не сработало.

У кого-нибудь есть идеи, что может отсутствовать? Так как я могу подключиться к экземпляру mysql извне, я предполагаю, что мне не хватает какой-то конфигурации или чего-то подобного, но после просмотра множества предлагаемых решений не работает.

PS Версия MySQL привязан к этому из-за бизнес-ограничений, поэтому я не могу обновить / использовать другую версию

Сообщение полной ошибки, возвращаемое из Sequelize:

web_1             | [Node] Unable to connect to the database: ConnectionRefusedError [SequelizeConnectionRefusedError]: connect ECONNREFUSED 127.0.0.1:3306
web_1             | [Node]     at /usr/src/app/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:123:19
web_1             | [Node]     at tryCatcher (/usr/src/app/node_modules/bluebird/js/release/util.js:16:23)
web_1             | [Node]     at Promise._settlePromiseFromHandler (/usr/src/app/node_modules/bluebird/js/release/promise.js:547:31)
web_1             | [Node]     at Promise._settlePromise (/usr/src/app/node_modules/bluebird/js/release/promise.js:604:18)
web_1             | [Node]     at Promise._settlePromise0 (/usr/src/app/node_modules/bluebird/js/release/promise.js:649:10)
web_1             | [Node]     at Promise._settlePromises (/usr/src/app/node_modules/bluebird/js/release/promise.js:725:18)
web_1             | [Node]     at _drainQueueStep (/usr/src/app/node_modules/bluebird/js/release/async.js:93:12)
web_1             | [Node]     at _drainQueue (/usr/src/app/node_modules/bluebird/js/release/async.js:86:9)
web_1             | [Node]     at Async._drainQueues (/usr/src/app/node_modules/bluebird/js/release/async.js:102:5)
web_1             | [Node]     at Immediate._onImmediate (/usr/src/app/node_modules/bluebird/js/release/async.js:15:14)
web_1             | [Node]     at processImmediate (internal/timers.js:439:21) {
web_1             | [Node]   name: 'SequelizeConnectionRefusedError',
web_1             | [Node]   parent: Error: connect ECONNREFUSED 127.0.0.1:3306
web_1             | [Node]       at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1134:16) {
web_1             | [Node]     errno: 'ECONNREFUSED',
web_1             | [Node]     code: 'ECONNREFUSED',
web_1             | [Node]     syscall: 'connect',
web_1             | [Node]     address: '127.0.0.1',
web_1             | [Node]     port: 3306,
web_1             | [Node]     fatal: true
web_1             | [Node]   },
web_1             | [Node]   original: Error: connect ECONNREFUSED 127.0.0.1:3306
web_1             | [Node]       at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1134:16) {
web_1             | [Node]     errno: 'ECONNREFUSED',
web_1             | [Node]     code: 'ECONNREFUSED',
web_1             | [Node]     syscall: 'connect',
web_1             | [Node]     address: '127.0.0.1',
web_1             | [Node]     port: 3306,
web_1             | [Node]     fatal: true
web_1             | [Node]   }
web_1             | [Node] }

1 Ответ

0 голосов
/ 21 февраля 2020

Итак, я наконец понял, что случилось. Я исправил одну проблему, но вызвал другую. По сути, создаваемый мной экземпляр Sequelize не прошел настройку хост + порт, поэтому он использовал стандартную конфигурацию 127.0.0.1:3306

По сути, это было:

export const sequelize = new Sequelize({
  database: config.database,
  username: config.username,
  password: config.password,
  models: [path.join(__dirname, '/models')],
  dialect: config.dialect,
});

Вместо этого :

export const sequelize = new Sequelize({
  host: config.host,
  port: config.port,
  database: config.database,
  username: config.username,
  password: config.password,
  models: [path.join(__dirname, '/models')],
  dialect: config.dialect,
});


So config was correct, but I was just not using it properly in my code.
...