ECONNREFUSED при попытке подключить приложение NodeJS к образу MySQL через docker-compose - PullRequest
1 голос
/ 25 июня 2019

У меня есть проект, который использует NodeJS в качестве сервера (с ExpressJS) и MySQL для обработки баз данных.Чтобы загрузить их обоих вместе, я использую Docker.Хотя этот проект включает в себя клиент ReactJS (и у меня есть папка клиента для реакции и папка сервера для nodejs), я проверил связь между сервером и клиентом, и она работает.Вот код, который относится как к server, так и к mysql сервисам:

docker-compose.yml

mysql:
    image: mysql:5.7
    environment:
      MYSQL_HOST: localhost
      MYSQL_DATABASE: sampledb
      MYSQL_USER: gfcf14
      MYSQL_PASSWORD: xxxx
      MYSQL_ROOT_PASSWORD: root
    ports:
      - 3307:3306
    restart: unless-stopped
    volumes:
      - /var/lib/mysql
      - ./db/greendream.sql:/docker-entrypoint-initdb.d/greendream.sql
    .
    .
    .
server:
    build: ./server
    depends_on:
      - mysql
    expose:
      - 8000
    environment:
      API_HOST: "http://localhost:3000/"
      APP_SERVER_PORT: 8000
    ports:
      - 8000:8000
    volumes:
      - ./server:/app
    links:
      - mysql
    command: yarn start

Тогда есть Dockerfile для сервера:

FROM node:10-alpine

RUN mkdir -p /app
WORKDIR /app

COPY package.json /app
COPY yarn.lock /app

RUN yarn install
COPY . /app

CMD ["yarn", "start"]

На сервере package.json скрипт start выглядит просто так: "start": "nodemon index.js" И исполняемый файл index.js выглядит так:

const express = require('express');
const cors = require('cors');
const mysql = require('mysql');

const app = express();

const con = mysql.createConnection({
  host: 'localhost',
  user: 'gfcf14',
  password: 'xxxx',
  database: 'sampledb',
});

app.use(cors());

app.listen(8000, () => {
  console.log('App server now listening on port 8000');
});

app.get('/test', (req, res) => {
  con.connect(err => {
    if (err) {
      res.send(err);
    } else {
      res.send(req.query);
    }
  })
});

Так что всеЯ хочу сделать сейчас, чтобы подтвердить, что соединение имеет место.Если это сработает, я отправлю обратно параметры, полученные от внешнего интерфейса, который выглядит следующим образом:

axios.get('http://localhost:8000/test', {
  params: {
    test: 'hi',
  },
}).then((response) => {
  console.log(response.data);
});

Итак, до того, как я установил соединение, я получил бы { test: 'hi' } в консоли браузера,Я ожидаю получить это, как только соединение установится успешно, но вместо этого я получаю следующее:

{
  address: "127.0.0.1"
  code: "ECONNREFUSED"
  errno: "ECONNREFUSED"
  fatal: true
  port: 3306
  syscall: "connect"
  __proto__: Object
}

Я думал, что, возможно, у меня неправильные привилегии, но я также попытался сделать это, используя root какпользователь и пароль, но я получаю то же самое.Как ни странно, если я обновлю страницу, я получу ECONNREFUSED, но PROTOCOL_ENQUEUE_AFTER_FATAL_ERRORfatal: false).Почему это происходит, если я использую правильные учетные данные?Пожалуйста, дайте мне знать, если вы заметили что-то, что я, возможно, пропустил

1 Ответ

1 голос
/ 25 июня 2019

В вашем методе mysql.createConnection необходимо указать хост mysql. Хост Mysql не является localhost, так как mysql имеет свой собственный контейнер с собственным IP. Лучший способ добиться этого - экстернализировать ваш хост mysql и позволить docker-compose разрешить имя сервиса mysql (в вашем случае это mysql) во внутреннем IP-адресе, что нам и нужно. По сути, ваш сервер nodejs будет подключаться к внутреннему IP-адресу контейнера mysql.

Вывести узел mysql на сервер nodejs:

const con = mysql.createConnection({
  host: process.env.MYSQL_HOST_IP,
  ...
});

Добавьте это в службу вашего сервера в docker-compose:

environment:
      MYSQL_HOST_IP: mysql // the name of mysql service in your docker-compose, which will get resolved to the internal IP of the mysql container
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...