This is a part of my node app
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');
});
Edited to
app.set('db-uri', 'mongodb://mongoDB:27017/nodepad-development');
Still the same error. I have already created container for my node app which runs on local host but I am unable to connect it to another mongo container due to which I cannot do POST requests to the app.
This is my docker compose file
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'
And the error I get when I try to register account details in my node app is
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)
What am I missing? Basically, how should I connect this type of code with mongodb anyway ? What's the role of 'db-uri'?
Docker Compose aliases service names to host names.
Because you named your container running the mongo
image as mongoDB
, mongodb
(case insensitive) will be the name of the host and the name by which you should refer to it from your Node.JS container and app.
localhost
in the URI with mongodb
The MongoDB database defaults to port 27017. Unless you've changed the port, you should specify this value.
Add the port to URI so that you have mongodb:27017
Optional but good practice , refactor the app to use environment variables rather than hard-coded values.
This has at least 2 benefits:
a. Your code becomes more flexible; b.Your Compose file, by then specifying these values, will be clearer.
See the DockerHub documentation for the image here
See MongoDB"s documentation on connection strings here
A Google search returns many examples using Compose, MongoDB and Node.JS
I'm confident your issue may be related to the timing of the Compose containers. I believe your app tries to connect to the DB before the DB container is ready. This is a common issue with Compose and is not solved using Compose's depends_on
. Instead you must find a MongoDB (or perhaps other database) solution to this.
In my repro, index.js
(see below) introduces a false delay before it tries to connect to the database. 5 seconds is sufficient time for the DB container to be ready and thus this works:
docker-compose build --no-cache
docker-compose up
Then:
docker-compose logs app
Attaching to 60359441_app_1
app_1 | URL: mongodb://mongodb:27017/example
app_1 | Connected
yields Connected
which is good.
Alternatively, to prove the timing issue, you may run the containers separately (and you could remove the sleep
function to ensure the database is ready before the app:
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 Because I followed your naming of mongodb
, the mongo-express
container must be provided this host name through ME_CONFIG_MONGODB_SERVER
NB The other environment variables shown with mongo
and mongo-express
images are the defaults and thus optional.
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
uses the environment ( HOST
, PORT
, DB
) for its config which is good practice.
Including mongo-express
provides the ability to browse the mongo
server to readily observe what's going on:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.