I'm pretty new to docker but I'm having some issues getting a node app to connect to a mongo database running on a separate container.
I'm using the official mongo image
I run it using:
docker run --name some-mongo --network-alias some-mongo -d mongo
It's running on port 27017 by default. I can connect to it using the mongo shell:
mongo --host mongodb://172.17.0.2:27017
But I can't connect to it by name
mongo --host mongodb://some-mongo:27017
MongoDB shell version: 3.2.19
connecting to: mongodb://some-mongo:27017/test
2018-05-07T17:23:20.813-0400 I NETWORK [thread1] getaddrinfo("some-mongo") failed: Name or service not known
2018-05-07T17:23:20.813-0400 E QUERY [thread1] Error: couldn't initialize connection to host some-mongo, address is invalid :
connect#src/mongo/shell/mongo.js:223:14
#(connect):1:6
exception: connect failed
Instead I get an error message about how I can't connect to the mongo host:
I'm trying some docker-compose tutorials but either they're too simple or they don't seem to work for me. I just want to connect a custom node app, (not the official node) to mongodb and some other dependencies.
Your approach is not altering your host's system configuration, so that the mongo service will not be available just like that. Agreeing with #unm4sk, you should compose you application's services into a single compose file like this:
version: '2'
services:
mongo:
image: mongo
expose:
- "27017"
[...]
service_utilizing_mongo:
[...]
links:
- mongo:mongo
Then, your service_utilizing_mongo would have a DNS entry that'd make this service capable of accessing your mongo service via a alias mongo on a default 27017 port.
You have to run your container with passing ports to your host machine:
docker run -p 27017:27017 --name some-mongo --network-alias some-mongo -d mongo
Then you can connect to MongoDB from your host machine:
If you don't want to do this you can connect to mongo through docker container command
docker exec -it some-mongo mongo
Related
I am trying to connect from a docker container (docker daemon running in rootless mode) to a mongo DB instance (hosted in the main host as a sudo systemctl service). The way I am trying to connect is by running
docker run --network="host" image:1.0.0
In my python script inside the docker I connect by below method:
import pymongo
from pymongo import MongoClient
connection = pymongo.MongoClient('127.0.0.1', 27017)
db = connection['test']
list_of_collections = db.list_collection_names()
My docker version: 20.10.14
Mongo DB version : 5.0.6
Pymongo version:3.11.4
Host: ubuntu-20.04
My mongo host config is like the below:
net:
port: 27017
bindIp: 0.0.0.0
The error returned from the docker container is as below :
pymongo.errors.ServerSelectionTimeoutError: 127.0.0.1:27017: [Errno 111]
Connection refused,Timeout 30s
Any help to resolve this would be appreciated.
I am trying to connect my node JS application to my mongoDB without using the ip address. The strategy which I have read up is that I must have both the containers in the same network.
My node JS application looks as below
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var PORT = 4000;
// REQUIRE MIDDLEWARE
var instantMongoCrud = require('express-mongo-crud'); // require the module
mongoose.connect('localhost:27017/user');
var options = { //specify options
host: `localhost:${PORT}`
}
//USE AS MIDDLEWARE
app.use(bodyParser.json()); // add body parser
app.use(instantMongoCrud(options)); // use as middleware
app.listen(PORT, ()=>{
console.log('started');
})
I have run my database mongodb and attached it into a network called nodenetwork.
I then did a build of my docker application as below:
docker build -t sampleapp:v1 . && docker run --net container:mongodb sampleapp:v1
the app runs correctly from the console output. However, I cannot access it via my browser.
I understand that it is because I must expose the port 4000 when i do a docker run as I had done before.
However, the issue is that when I tried to run like this instead
docker build -t sampleapp:v1 . && docker run -p 4000:4000 --net container:mongodb sampleapp:v1
it throws me: docker: Error response from daemon: conflicting options: port publishing and the container type network mode.
AS such, my question how do I modify this command and is this the best way?
You're telling your application that mongodb will be accesible on localhost but it won't, as localhost will be the application container unless you're running it with --net=host and your mongodb container is exposing the 27017 port or is running on --net=host as well.
You could create a docker network and connect both containers (mongodb and app) to it.
Example:
$ docker network create mynetwork --driver bridge
$ docker run -d --name mongodb --net=mynetwork bitnami/mongodb:latest
$ docker run -d --name app -p 4000:4000 --net=mynetwork sampleapp:v1
This will create a DNS record for mongodb with the same name of the container that will be resolvable from any container within your user-defined network.
Another solution will be to use docker-compose:
version: '3'
services:
mongodb:
image: bitnami.mongodb:latest
app:
build: ./
ports:
- 4000:4000
Place this in a file called docker-compose.yml in the same directory where the Dockerfile for sampleapp is and run docker-compose up
As docker-compose creates a user-defined network as well, you can access mongodb using the container DNS record.
In any of the cases, change your application to connect using the DNS provided by docker:
mongoose.connect('mongodb:27017/user');
Read more about docker-compose and user-defined networks here:
https://docs.docker.com/compose/overview/
https://docs.docker.com/network/bridge/
I have two apps:
MongoDB (started from the Bitnami MongoDB Docker image)
My custom node app
The two apps interact flawlessly when my node app is run natively. Now I've put it inside a Docker container and when I start both together with docker compose up, the backend can not connect to MongoDB.
This is an excerpt of the startup sequence:
mongodb_1 | 2018-11-10T22:22:52.481+0000 I NETWORK [initandlisten] waiting for connections on port 27017
[...]
backend_1 | 2018-11-10T22:23:48.119Z 'MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]'
This is my docker-compose.yml:
version: '2'
services:
mongodb:
image: bitnami/mongodb:latest
expose:
- 27017
environment:
- ALLOW_EMPTY_PASSWORD=yes
backend:
build: ./backend
environment:
API_HOST: http://localhost:3000/
APP_SERVER_PORT: 3000
expose:
- 3000
volumes:
- ./backend:/app/backend
links:
- mongodb
depends_on:
- mongodb
This is my node call to the DB:
mongoose.connect('mongodb://localhost:27017/groceryList', {
useNewUrlParser: true
});
I skimmed about 15 Stackoverflow questions asking the same and I am not getting the cause:
It is not that MongoDB is not ready when my node app tries to
connect. I wrapped my connection call into an auto reconnection
function as described here and the error repeats endlessly. It is not just about the "first
connect".
I can publish Port 27017 of the MongoDB container and
happily connect with Robo3T. The DB is definitely working.
When I connect to mongodb://mongo:27017/groceryList instead, the same applies, only with the ENOTFOUND flag instead of ECONNREFUSED.
What am I missing?
Docker 18.06.1-ce
docker-compose 1.22.0
Mongoose 5.3.6
MongoDB 4.0.3
Node 11.1.0
macOS 10.14.1
Your mongodb service is named mongodb not mongo.
Try
mongoose.connect('mongodb://mongodb:27017/groceryList', {
useNewUrlParser: true
});
The generic form is 'mongodb://mongoServiceName:27017/dbname', this uses docker's automatic dns resolution for containers within the same network.
And as you may already know from other questions/answers, within a container, the url is relative to itself, therefore since there not mongodb running inside the backend container, it can't connect to it.
It's not possible to use localhost:27017 into a container to communicate with other because the scope "localhost" is self refering (localhost:27017 will look for the port 27017 into the container backend - not in mongodb container)
Then, you ned to put or the service name (mongodb) or IP of your machine
I am trying to connect postgresdb service with nodejs web service using docker compose
My docker-compose.yml file
version: "3"
services:
web:
build: ./
ports:
- "40000:3000"
depends_on:
- postgres
postgres:
image: kartoza/postgis:9.6-2.4
restart: always
volumes:
- postgresdata:/data/db
environment:
- POSTGRES_PASS=password
- POSTGRES_DBNAME=sticki
- POSTGRES_USER=renga
- ALLOW_IP_RANGE=0.0.0.0/0
ports:
- "1000:5432"
volumes:
postgresdata:
So when i do docker-compose up in my root directory both services are running and i can access web service using localhost:40000 and postgres service using postico on localhost:1000
But in Node Web service i have written code to access postgres using Sequelize as
const sequelize = new Sequelize('sticki', 'renga', 'password', {
host: 'postgres',
dialect: 'postgres',
});
But I get the following error
SequelizeConnectionRefusedError: connect ECONNREFUSED 172.18.0.2:1000
Why does postgres Connection is made to 172.18.0.2 instead of localhost(0.0.0.0)? What i am doing wrong?
For your web container postgres is a DNS name defined in compose as a service. It fetches the postgres DNS IP address via docker internal DNS & network, that's why it's resolving to 172.18.0.2. If you go to web container & ping postgres, you will get the same IP.
As a fix, configure your node service to connect to host postgres on port 5432 since it's the container port. Port 1000 is the host machine port, if you want to use port 1000, configure node service to connect to your MACHINE_IP:1000.
PS - Localhost within a container means the container itself & nothing else.
Service name is taken from container_name - which is fixed. In your case you do not have that and name is created from folder where docker-compose.yml is + _ + service name + _1.
With this DNS name you can reach your service on the default network that docker-compose will create, from one service to reach the other.
Thanks
I have problems to connect a nodeJS application which is running as a docker container to a mongoDB. Let me explain what I have done so far:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a3732cc1d90 mongo:3.4 "docker-entrypoint..." 3 weeks ago Up 3 weeks 27017/tcp mongo_live
As you can see, there is already a mongo docker container running.
Now I'm running my nodeJS application docker container (which is a build from meteorJS):
$ docker run -it 0b422defbd59 /bin/bash
In this docker container I want to run the application by running:
$ node main.js
Now I'm getting the error
Error: MONGO_URL must be set in environment
I already tried to set MONGO_URL by setting:
ENV MONGO_URL mongodb://mongo_live:27017/
But this doesn't work:
MongoError: failed to connect to server [mongo_live:27017] on first connect
So my question is how to connect to a DB, which is - as far as I understand - 'outside' of the running container. Alternativly how do I set up a new DB to this container?
There are couple of ways to do it.
run your app in the same network as your mongodb:
docker run --net container:mongo_live your_app_docker_image
# then you can use mongodb in your localhost
$ ENV MONGO_URL mongodb://localhost:27017/
Also you can link two containers:
docker run --link mongo_live:mongo_live you_app_image ..
# Now mongodb is accessible via mongo_live
use mongodb container ip address:
docker inspect -f '{{.NetworkSettings.IPAddress}}' mongo_live
# you will get you container ip here
$ docker run -it 0b422defbd59 /bin/bash
# ENV MONGO_URL mongodb://[ip from previous command]:27017/
You can bind your mongodb port to your host and use host's hostname in your app
You can use docker network and run both apps in the same network
You could pass --add-host mongo_live:<ip of mongo container> to docker run for your application and then use mongo_live for mongodb url
You can also use docker compose to make your life easier ;)
...
When you run containers each container works in independent network. Because one container cant connect to other point to point.
The are 3 ways to connect containers
Have a little fuss with low-level docker network magic
Connect container through localhost. Each container must expose ports on localhost (as your mongo_live). But you need add to host ile on localhost 127.0.0.1 mongo_live (This is the simplest way)
Use docker-compose. It convenient tool for working many containers together. (This is right way)
Add mongodb to application container is not docker way.
Please use below snippet for your docker-compose.yml file, replace comments with your actuals. Should solve your problem.
version: '2'
services:
db:
build: <image for mongoDB>
ports:
- "27017:27017" # whatever port u r using
environment:
#you can specify mondo db username and stuff here
volumes:
- #load default config for mondodb from here
- "db-data-store:/data/db" # path depends on which image you use
networks:
- network
nodejs:
build: #image for node js
expose:
- # mention port for nodejs
volumes:
- #mount project code on container
networks:
- network
depends_on:
- db
networks:
network:
driver: bridge
Please use the below links for references :
1) NodeJs Docker
2) MongoDb docker
3) docker-compose tutorial
Best of Luck
I had problem how to connect my server.js to mongodb. And that's how i solved it hope you find it useful.
Tap For My Screenshot