I am using docker compose with my app and are trying to connect mongodb to the server. When i run my app locally outside of docker i get this as output(works as intended)
[nodemon] 2.0.15
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node index.js`
Server running
Mongoose connected to db...
Mongodb connected....
When i run the docker-compose up command and the server runs in the container i get this output
[nodemon] 2.0.15
docker-server | [nodemon] to restart at any time, enter `rs`
docker-server | [nodemon] watching path(s): *.*
docker-server | [nodemon] watching extensions: js,mjs,json
docker-server | [nodemon] starting `node index.js`
docker-server | Works
docker-server | Works
docker-server | Mongoose connection is disconnected...
After a while the mongoose disconnects.
My package.json is
{
"name": "make-me-a-sandwich",
"version": "1.1.0",
"description": "This is the Swagger 2.0 API for Web Architectures course group project work. ",
"main": "index.js",
"scripts": {
"prestart": "npm install",
"start": "nodemon index.js"
},
"keywords": [
"swagger"
],
"license": "Unlicense",
"private": true,
"dependencies": {
"connect": "^3.2.0",
"js-yaml": "^3.3.0",
"swagger-tools": "0.10.1",
"mongoose": "^6.1.5",
"nodemon": "^2.0.15"
}
}
My index.js file is
const http = require('http');
const connect = require('./models/db');
const PORT = 80;
const server = http.createServer(function (request, response) {
const { url, method, headers } = request;
const filePath = new URL(url, `http://${headers.host}`).pathname;
if (filePath === '/' && method.toUpperCase() === 'GET') {
console.log("Works")
response.statusCode = 200;
response.setHeader('Content-Type', 'text/plain');
response.end('Hello, World! GET\n');
} else {
response.statusCode = 200;
response.setHeader('Content-Type', 'text/plain');
response.end('Hello, World! Teemu\n');
}
});
server.on('error', err => {
console.error(err);
server.close();
});
server.on('close', () => console.log('Server closed.'));
server.listen(PORT, () => {
console.log("Server running");
});
connect.connectDB();
model/db.js
const mongoose = require('mongoose');
function connectDB() {
mongoose
.connect('mongodb://mongo_db:27017', {
useNewUrlParser: true,
})
.then(() => {
console.log('Mongodb connected....');
})
.catch(err => console.log(err.message));
mongoose.connection.on('connected', () => {
console.log('Mongoose connected to db...');
});
mongoose.connection.on('error', err => {
console.log(err.message);
});
mongoose.connection.on('disconnected', () => {
console.log('Mongoose connection is disconnected...');
});
};
function disconnectDB() {
mongoose.disconnect();
}
module.exports = { connectDB, disconnectDB };
Dockerfile
FROM node:17.3.0
WORKDIR /server
COPY package.json .
RUN npm install
COPY . .
EXPOSE 80
CMD ["npm", "start"]
docker-compose file
version: "3"
services:
server-a:
container_name: docker-server
build:
dockerfile: Dockerfile
context: ./backend/server-a
ports:
- "3000:80"
links:
- mongo_db
networks:
- backend
mongo_db:
container_name: mongo
image: mongo:latest
ports:
- '27017:27017'
networks:
backend:
Help would be really appreciated. Let me also know if i can offer any other information.
CodePudding user response:
Different containers need to be on the same Compose network to communicate. If a service doesn't have a networks:
block, Compose automatically attaches it to a default
network. So in your example, the server-a
container is only on the backend
network, but the mongo_db
container is only on the default
network, and that's why they can't communicate.
The easiest way to resolve this is to delete all of the networks:
blocks in the file. Then Compose will attach all of the containers to the default
network. Removing other unnecessary options, you could reduce this Compose file to just
version: "3.8"
services:
server-a:
build: ./backend/server-a
ports:
- "3000:80"
mongo_db:
image: mongo:latest
ports:
- '27017:27017'
In a comment you suggest that it's important to keep a second named network. If that's the case, then you need to make sure the database container also has a networks:
block that names a network in common with the application container.