Как мне подключить мою базу данных mon go к моему приложению узла с помощью этой строки подключения mongoDB, используя docker -compose? - PullRequest
1 голос
/ 23 февраля 2020

Это часть моего приложения узла

app.configure('development', function() {
  app.set('db-uri', 'mongodb://localhost/nodepad-development');
  app.use(express.errorHandler({ dumpExceptions: true }));
  app.set('view options', {
    pretty: true
  });
});

app.configure('test', function() {
  app.set('db-uri', 'mongodb://localhost/nodepad-test');
  app.set('view options', {
    pretty: true
  });  
});

app.configure('production', function() {
  app.set('db-uri', 'mongodb://localhost/nodepad-production');
});

Отредактировано в

app.set('db-uri', 'mongodb://mongoDB:27017/nodepad-development');

Все та же ошибка. Я уже создал контейнер для моего приложения узла, которое работает на локальном хосте, но я не могу подключить его к другому контейнеру mon go, из-за которого я не могу делать запросы POST к приложению.

Это мой docker составить файл

version: '3'
services:
  apptest:
    container_name: apptest
    restart: always
    image: ekamzf/nodeapp:1.1
    ports:
      - '8080:8080
    depends_on:
          - mongoDB

  mongoDB:
    container_name: mongoDB
    image: mongo
    volumes:
      - ./data:/usr/src/app
    ports:
      - '27017:27017'  

И ошибка, которую я получаю, когда пытаюсь зарегистрировать данные учетной записи в своем приложении узла,

Error: Timeout POST /users
    at null._onTimeout (/usr/src/app/node_modules/connect-timeout/index.js:12:22)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)

Чего мне не хватает? В общем, как мне в любом случае связать этот тип кода с mongodb? Какова роль «дб-ури»?

1 Ответ

2 голосов
/ 23 февраля 2020

Docker Составьте псевдонимы имен сервисов для имен хостов.

Поскольку вы назвали свой контейнер с изображением mongo как mongoDB, mongodb (без учета регистра) будет именем хоста и имя, под которым вы должны ссылаться на него из вашего Node.JS контейнера и приложения.

  1. Замените localhost в URI на mongodb

MongoDB По умолчанию в базе данных используется порт 27017. Если вы не изменили порт, вам следует указать это значение.

Добавьте порт в URI, чтобы у вас было mongodb:27017

Необязательно, но хорошая практика , реорганизуйте приложение для использования переменных среды, а не жестко закодированные значения.

Это имеет как минимум 2 преимущества:

a. Ваш код становится более гибким; б. Ваш файл Compose, указав эти значения, станет более понятным.

См. Документацию DockerHub для образа здесь

См. Документацию MongoDB для строк подключения здесь

Поиск Google возвращает много примеров с использованием Compose, MongoDB и Node.JS

Обновление: repro

Я уверен Ваша проблема может быть связана с синхронизацией контейнеров Compose. Я полагаю, что ваше приложение пытается подключиться к БД до того, как контейнер DB будет готов. Это общая проблема с Compose, и не решается с помощью Compose depends_on. Вместо этого вы должны найти решение MongoDB (или, возможно, другой базы данных) для этого.

В моем воспроизведении index.js (см. Ниже) вводит ложную задержку, прежде чем он пытается подключиться к базе данных. 5 секунд достаточно для готовности контейнера БД, и, таким образом, это работает:

docker-compose build --no-cache
docker-compose up

Тогда:

docker-compose logs app
Attaching to 60359441_app_1
app_1            | URL: mongodb://mongodb:27017/example
app_1            | Connected

дает Connected, что хорошо.

В качестве альтернативы пр Помимо проблемы синхронизации, вы можете запускать контейнеры отдельно (и вы можете удалить функцию sleep, чтобы база данных была готова до приложения:

HOST=localhost  # No DNS naming
PORT=37017      # An arbitrary port to prove the point

# In one session
docker run \
--interactive --tty --rm \
--publish=${PORT}:27017 \
mongo

# In another session
docker run \
--interactive --tty --rm \
--net=host \
--env=HOST=${HOST} --env=PORT=${PORT} --env=DATA=example --env=WAIT=0 \
app
URL: mongodb://localhost:37017/example
Connected

docker -compose.yaml:

version: "3"

services:
  app:
    image: app
    build:
      context: ./app
      dockerfile: Dockerfile
    environment:
      - HOST=mongodb
      - PORT=27017
      - DATA=example
      - WAIT=5000
    volumes:
      - ${PWD}/app:/app

  mongodb:
    image: mongo
    restart: always
    # environment:
    #   MONGO_INITDB_ROOT_USERNAME: root
    #   MONGO_INITDB_ROOT_PASSWORD: example

  mongo-express:
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_SERVER: mongodb
      # ME_CONFIG_MONGODB_ADMINUSERNAME: root
      # ME_CONFIG_MONGODB_ADMINPASSWORD: example

NB Поскольку я следовал вашему названию mongodb, контейнеру mongo-express необходимо предоставить это имя хоста через ME_CONFIG_MONGODB_SERVER

NB Другие переменные среды, показанные с изображениями mongo и mongo-express, являются значениями по умолчанию и поэтому являются необязательными.

Dockerfile:

FROM node:13.8.0-slim

WORKDIR /usr/src/app

COPY package.json .
RUN npm install

COPY . .

ENTRYPOINT ["node","index.js"]

index. js:

// Obtain config from the environment
const HOST = process.env.HOST;
const PORT = process.env.PORT;
const DATA = process.env.DATA;
const WAIT = parseInt(process.env.WAIT, 10);

// Create MongoDB client
var MongoClient = require("mongodb").MongoClient;

let url = `mongodb://${HOST}:${PORT}/${DATA}`;
console.log(`URL: ${url}`);

// Artificially delay the code
setTimeout(function() {
  MongoClient.connect(url, function(err, db) {
    if(!err) {
      console.log("Connected");
    }
  });
}, WAIT);

NB index.js использует среду (HOST, PORT, DB) для своей конфигурации, что является хорошей практикой.

Включая mongo-express обеспечивает возможность просматривать сервер mongo для быстрого наблюдения за происходящим:

enter image description here

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