Попытка подключиться к Redis возвращает ECONNREFUSED - PullRequest
0 голосов
/ 05 июня 2018

У меня есть следующее docker-compose.yml:

version: '3'
services:
  web:
    build: .
    image: webapp
    env_file: .env.docker
    ports:
      - "3000:3000"
    links:
      - redis
      - mongo
  redis:
    image: "redis:alpine"
  mongo:
    image: "mongo"

И я использую следующие переменные env для подключения к Mongo и Redis

REDIS_URL=redis://redis:6379
DATABASE_URL=mongodb://mongo:27017/webapp

В этой конфигурации, когдаприложение запускается, оно может подключиться к контейнеру Mongo, но не может подключиться к Redis со следующей ошибкой:

Error: connect ECONNREFUSED 127.0.0.1:6379

Я попытался выставить и отобразить порты:

    expose:
      - "6379"
    ports:
      - "6379:6379"

, но этодо сих пор не решает проблему.Сопоставляя порты, я могу использовать redis-cli для подключения к Redis, поэтому я знаю, что контейнер работает.

Есть какие-нибудь подсказки?

РЕДАКТИРОВАТЬ: Запуск веб-приложения на моем компьютере без Docker работает нормально.Я попробовал оба, родной Redis и Mongo, а также работал с docker-compose ниже, комментируя раздел web и отображая порты.

EDIT 2: Вывод lsof

COMMAND    PID    USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
com.docke 3136 JayC   20u  IPv4 0x7dac4a08aadc94c9      0t0  TCP *:6379 (LISTEN)
com.docke 3136 JayC   21u  IPv6 0x7dac4a08bbf50781      0t0  TCP localhost:6379 (LISTEN)

РЕДАКТИРОВАТЬ 3: Добавление места подключения приложения к Redis:

const { RedisPubSub } = require('graphql-redis-subscriptions');

console.log(`-------------- REDIS_URL: ${process.env.REDIS_URL} --------------`);

const engine = new RedisPubSub({
    connection: {
        url: process.env.REDIS_URL,
    },
    connectionListener: err => {
        if (err) {
            Logger.sys.error(
                `redis connection failed at ${process.env.REDIS_URL}`,
            );
            Logger.sys.error(err);
        } else {
            Logger.sys.info(
                `pubsub connected to redis at ${process.env.REDIS_URL}`,
            );
        }
    },
});

Выход журнала:

-------------- REDIS_URL: redis://redis:6379 --------------
2018-06-05T13:21:37.658Z - error: redis connection failed at redis://redis:6379
2018-06-05T13:21:37.659Z - error: { Error: connect ECONNREFUSED 127.0.0.1:6379
    at Object._errnoException (util.js:1022:11)
    at _exceptionWithHostPort (util.js:1044:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1182:14)
  code: 'ECONNREFUSED',
  errno: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 6379 }

1 Ответ

0 голосов
/ 05 июня 2018

Конфигурация, которую вы описали, не используется вашим приложением:

REDIS_URL=redis://redis:6379

Когда вы видите, что соединение запущено, оно пытается подключиться к 127.0.0.1 вместо ip контейнера:

Error: connect ECONNREFUSED 127.0.0.1:6379

Чтобы решить эту проблему, вам нужно перенастроить ваше приложение, чтобы оно использовало DNS-имя redis вместо 127.0.0.1.Каждый контейнер имеет свой собственный закрытый интерфейс обратной связи, поэтому подключение к нему внутри контейнера приведет к подключению к самому контейнеру, а не к вашему хосту или любому другому контейнеру, работающему на хосте.

В качестве отступления, не используйте ссылки.Они устарели.Встроенный DNS даст разрешение имени для имени службы.Если у вас есть зависимости между контейнерами, лучше всего обрабатывать это в приложении или точке входа.Вы также можете использовать depends_on для вывода списка сервисных зависимостей, но это работает только с docker-compose и не проверяет работоспособность зависимых сервисов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...