Node.js 如何使用docker compose使用此mongoDB连接字符串将我的mongo数据库连接到我的节点应用程序?

Node.js 如何使用docker compose使用此mongoDB连接字符串将我的mongo数据库连接到我的节点应用程序?,node.js,mongodb,docker,docker-compose,database-connection,Node.js,Mongodb,Docker,Docker Compose,Database Connection,这是我的节点应用程序的一部分 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(

这是我的节点应用程序的一部分

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');
还是一样的错误。 我已经为在本地主机上运行的节点应用程序创建了容器,但我无法将其连接到另一个mongo容器,因此我无法向该应用程序发送请求

这是我的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连接起来?
“db uri”的作用是什么?

Docker将别名服务名组合到主机名

因为您将运行mongo映像的容器命名为mongoDB,所以mongoDB不区分大小写将是主机的名称,以及您在Node.JS容器和应用程序中引用主机的名称

用mongodb替换URI中的localhost MongoDB数据库默认为端口27017。除非已更改端口,否则应指定此值

将端口添加到URI,这样您就有了mongodb:27017

可选,但重构应用程序以使用环境变量而不是硬编码值

这至少有两个好处:

a。您的代码变得更加灵活; B通过指定这些值,您的合成文件将更加清晰

有关图像,请参阅DockerHub文档

请参阅有关连接字符串的MongoDB文档

谷歌搜索使用Compose、MongoDB和Node.JS返回

更新:repo 我相信您的问题可能与编写容器的时间有关。我相信你的应用程序会在DB容器准备好之前尝试连接到DB。这是Compose的常见问题,无法使用Compose的解决方案。相反,您必须找到MongoDB或其他数据库解决方案

在我的复制中,index.js在尝试连接到数据库之前引入了错误延迟。5秒是DB容器准备就绪的足够时间,因此:

docker compose生成-无缓存 码头工人整理 然后:

docker撰写日志应用程序 附于60359441_app_1 应用程序1 | URL:mongodb://mongodb:27017/example app|U 1 |已连接 这是好的

或者,为了证明时间问题,您可以单独运行容器,并且可以删除sleep函数,以确保数据库在应用程序启动之前准备就绪:

主机=本地主机无DNS命名 端口=37017一个任意端口来证明这一点 一次会议 码头工人赛跑\ -交互式-tty-rm\ -publish=${PORT}:27017\ 蒙戈 在另一届会议上 码头工人赛跑\ -交互式-tty-rm\ -网络=主机\ -env=HOST=${HOST}-env=PORT=${PORT}-env=DATA=example-env=WAIT=0\ 应用程序 网址:mongodb://localhost:37017/example 有联系的 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
注意:因为我遵循了您对mongodb的命名,所以必须通过ME_CONFIG_mongodb_服务器向MongoExpress容器提供此主机名

注意: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使用环境主机、端口和数据库进行配置,这是一种很好的做法

包括mongo express在内,您可以浏览mongo服务器,随时观察正在发生的事情:


Docker将别名服务名合成为主机名

因为您将运行mongo映像的容器命名为mongoDB,所以mongoDB不区分大小写将是主机的名称,以及您在Node.JS容器和应用程序中引用主机的名称

用mongodb替换URI中的localhost MongoDB数据库默认为端口27017。除非已更改端口,否则应指定此值

将端口添加到URI,这样您就有了mongodb:27017

可选,但重构应用程序以使用环境变量而不是硬编码值

这至少有两个好处:

a。您的代码变得更加灵活; B通过指定这些值,您的合成文件将更加清晰

有关图像,请参阅DockerHub文档

请参阅有关连接字符串的MongoDB文档

谷歌搜索使用Compose、MongoDB和Node.JS返回

更新:repo 我相信您的问题可能与编写容器的时间有关。我相信你的应用程序会在DB容器准备好之前尝试连接到DB。这是Compose的常见问题,无法使用Compose的解决方案。相反,您必须找到MongoDB或其他数据库解决方案

在我的复制中,index.js在尝试连接到数据库之前引入了错误延迟。5秒是DB容器准备就绪的足够时间,因此:

docker compose生成-无缓存 码头工人整理 然后:

docker撰写日志应用程序 附于60359441_app_1 应用程序1 | URL:mongodb://mongodb:27017/example 附件1康涅茨 特德 这是好的

或者,为了证明时间问题,您可以单独运行容器,并且可以删除sleep函数,以确保数据库在应用程序启动之前准备就绪:

主机=本地主机无DNS命名 端口=37017一个任意端口来证明这一点 一次会议 码头工人赛跑\ -交互式-tty-rm\ -publish=${PORT}:27017\ 蒙戈 在另一届会议上 码头工人赛跑\ -交互式-tty-rm\ -网络=主机\ -env=HOST=${HOST}-env=PORT=${PORT}-env=DATA=example-env=WAIT=0\ 应用程序 网址:mongodb://localhost:37017/example 有联系的 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
注意:因为我遵循了您对mongodb的命名,所以必须通过ME_CONFIG_mongodb_服务器向MongoExpress容器提供此主机名

注意: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使用环境主机、端口和数据库进行配置,这是一种很好的做法

包括mongo express在内,您可以浏览mongo服务器,随时观察正在发生的事情:


是的,我确实将localhost更改为mongoDB:27017。同样的错误仍然存在。可能是!您的Node.JS正在尝试在MongoDB服务准备就绪之前访问它。这是撰写的常见问题。JS容器准备就绪,尝试访问数据库,数据库还不可用,代码退出。在谷歌上搜索MongoDB和Docker Compose,然后等待。请参阅:。我对MongoDB不熟悉,但这可能是一个骗局,但如果您确信自己的代码和编写在其他方面都很好,那么值得一试。您可以通过在compose之外运行MongoDB容器来证明这一点,一旦准备好,也可以在容器中启动应用程序。别忘了重命名主机并使用-net=host等。我认为您关于我的mongo容器准备就绪的观点是正确的。我现在所做的是在kubernetes上作为POD部署,现在两者都在各自的服务上运行和侦听,但我有一个问题,我应该在我的nodeapp容器的ENV块中提到什么?因为我的连接字符串没有使用环境变量,所以我不想弄乱代码。使用Kubernetes,您可以更好地控制部署的时间,以便在部署节点应用程序之前知道您的数据库服务正在运行。如果您没有在节点应用程序中使用环境变量,那么在YAML规范中不需要环境块。显然,您需要将MongoDB的主机名替换为Kubernetes服务名。同样的错误仍然存在。可能是!您的Node.JS正在尝试在MongoDB服务准备就绪之前访问它。这是撰写的常见问题。JS容器准备就绪,尝试访问数据库,数据库还不可用,代码退出。在谷歌上搜索MongoDB和Docker Compose,然后等待。请参阅:。我对MongoDB不熟悉,但这可能是一个骗局,但如果您确信自己的代码和编写在其他方面都很好,那么值得一试。您可以通过在compose之外运行MongoDB容器来证明这一点,一旦准备好,也可以在容器中启动应用程序。别忘了重命名主机并使用-net=host等。我认为您关于我的mongo容器准备就绪的观点是正确的。我现在所做的是在kubernetes上作为POD部署,现在两者都在各自的服务上运行和侦听,但我有一个问题,我应该在我的nodeapp容器的ENV块中提到什么?因为我的连接字符串没有使用环境变量,所以我不想弄乱代码。使用Kubernetes,您可以更好地控制部署的时间,以便在部署节点应用程序之前知道您的数据库服务正在运行。如果您没有在节点应用程序中使用环境变量,那么在YAML规范中不需要环境块。显然,您需要将MongoDB的主机名替换为Kubernetes服务名。