Linking web app to mongoDB in Docker - mongodb

I'm new to Docker and I need help setting up my web app.
So I'm able to get my mongo container up and running - it is also the latest version - by running docker run -d --name mongo1 mongo.
I then launch the web-app with linking mongoDB by running docker run -it --link mongo1:mongo --name webapp1 webapp
It then errors out on the build: Error: connect ECONNREFUSED 127.0.0.1:27017
Here's the build that should be exposing the ports:
FROM node:latest
RUN mkdir -p /webapp /home/nodejs && \
groupadd -r nodejs && \
useradd -r -g nodejs -d /home/nodejs -s /sbin/nologin nodejs && \
chown -R nodejs:nodejs /home/nodejs
WORKDIR /webapp
COPY package.json typings.json /webapp/
RUN npm install
COPY . /webapp
RUN chown -R nodejs:nodejs /webapp
USER nodejs
EXPOSE 3000
EXPOSE 27017
CMD [ "npm", "start" ]
What am I missing?
EDIT: This like may be useful, alongside cml.co's answer: http://www.ifdattic.com/how-to-mongodb-nodejs-docker/

Your nodejs app should connect to mongodb using mongo:27017 (as you set mongo as the mongodb alias inside container --link mongo1:mongo) and not localhost:27017 neither127.0.0.1:27017.
So, check mongodb connection url.
By the way, exposing port 27017 seems to be not necessary in webapp container

Related

Docker container of flask app is possible connect to localhost MongoDB [duplicate]

This question already has answers here:
How to connect local Mongo database to docker
(2 answers)
Closed 2 years ago.
I’m new to docker.
I have the one flask app was running on my docker container and the application needs to connect to MongoDB for the CRUD action.
but I have some connection problems between the docker and the localhost. The container cannot connect to my localhost MongoDB.
So is a possible flask app from docker container connect to the localhost MongoDB?
My Flask app MongoDB config setup:
cilent = pymongo.MongoClient('127.0.0.1',27017)
My Dockerfile config:
FROM ubuntu:latest
MAINTAINER Michael Levan
CMD tail -f /dev/null
RUN apt-get update -y && apt-get install -y python3-pip python-dev
EXPOSE 8080
EXPOSE 5000
COPY ./requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip3 install -r requirements.txt
COPY . /app
ENTRYPOINT [ "python3" ]
CMD [ "app.py" ]
As a suggestion, it'll be easy to create mongodb inside the Docker. However you could check connect docker to local db and docker to local mongo.

Mongodb on debian docker image - unable to stand

Good evening.
I'm noobie in docker and try to learn it a little bit. Currently writing simple java application integrated with mongodb, but I stuck on dockerfile. Basically the problem is with mongodb start. Here is my docker file:
FROM debian:buster-slim
# Install necessary libs
RUN apt-get update && apt-get install -y apt-utils wget gnupg gnupg2 curl
# Install mongodb
RUN wget -qO - https://www.mongodb.org/static/pgp/server-4.2.asc | apt-key add -
RUN echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.2.list
RUN apt-get update
RUN apt-get install -y mongodb-org
RUN systemctl enable mongod.service
RUN service mongod start
# Install jre 11
RUN apt-get install -y openjdk-11-jre
Here is the terminal output (only last step):
Setting up mongodb-org-shell (4.2.1) ...
Setting up mongodb-org-tools (4.2.1) ...
Setting up mongodb-org-mongos (4.2.1) ...
Setting up mongodb-org (4.2.1) ...
Removing intermediate container 7491080bfe9f
---> bbcf5b2ccb13
Step 7/11 : RUN service mongod start
---> Running in 46a66989ade2
mongod: unrecognized service
The command '/bin/sh -c service mongod start' returned a non-zero code: 1
Funny think is that I followed an official mongodb installation guide:
Mongodb installation on debian
During installation on 'real' debian/ubuntu machine it works.
It also doesn't work when tried to build docker image from official mongodb image from docker hub, I mean FROM mongo:4.2-bionic
After login to container and try to run mongo it returns:
root#8cc1d270a262:~# mongo
MongoDB shell version v4.2.0
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
2019-10-23T20:39:44.728+0000 E QUERY [js] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused :
connect#src/mongo/shell/mongo.js:341:17
#(connect):2:6
2019-10-23T20:39:44.729+0000 F - [main] exception: connect failed
2019-10-23T20:39:44.729+0000 E - [main] exiting with code 1
I expected that, cause mongo is unable to stand... Somehow.
Any ideas?
So, it seems when trying to follow the instructions to install MongoDB on Debian the SysVInit files are not created and error message mongod: unrecognized service. So a basic question: Does a docker container really need daemon control with either SysVInit or systemd? I don't think it really needs it, and my reason is because the container itself has a single purpose - to host the database. The container should always have the database engine running. With this philosophy in mind, I altered the Dockerfile to include an ENTRYPOINT that starts the mongod instead of relying on any daemon management system.
In order for the MongoDB database to be available outside the container I adjusted the mongod.conf file to bind to all network adapters by using bindIp: 0.0.0.0 instead of bindIp: 127.0.0.1. I also expose port 27017 in the Dockerfile. This means if you have MongoDB installed and running on the host computer using the default port 27107 that process will need to be halted to yield the port to the Docker container.
I was getting some errors in the container around the debconf stuff so I set it non-interactive as well. The installation of java was giving me fits, so I commented it out. If you need java on this container this will still need to be worked out.
Dockerfile:
FROM debian:buster-slim
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
# Install necessary libs
RUN apt-get update && apt-get install -y apt-utils wget gnupg gnupg2 curl
# Install mongodb
RUN wget -qO - https://www.mongodb.org/static/pgp/server-4.2.asc | apt-key add -
RUN echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.2.list
RUN apt-get update
RUN apt-get install -y mongodb-org
# BIND TO ALL ADAPTERS IN CONTAINER
RUN sed -i "s,\\(^[[:blank:]]*bindIp:\\) .*,\\1 0.0.0.0," /etc/mongod.conf
# Install jre 11
# RUN "apt-get install -y openjdk-11-jre"
EXPOSE 27017
ENTRYPOINT ["/usr/bin/mongod", "-f", "/etc/mongod.conf"]
Build:
To build the Docker image issue the following command...
docker build --tag mongodb .
(notice the period in the command - it is required).
Run:
To create a docker container, use the run command.
docker run --publish 27017:27017 --name mongodb -d mongodb
Notice the --publish to map host port 27017 to container port 27017. Notice the --name to name the container for easier reference if we need to get a bash shell inside the container. Run -d for detached mode so it runs in the background, and finally refer to the image named mongodb.
Connect:
Assuming MongoDB is installed on the host too the mongo shell binary will be available. Issue a mongo shell command...
mongo
No other parameters are needed. The installation of MongoDB in the container does not have authorization enabled and so does not ask for a username or password. The default port of 27107 is used by the container and mapped by the docker engine. Localhost is used by default.
Get BASH shell of container:
If you want to get a BASH shell inside of the container issue the following command...
docker exec -it mongodb bash
Try to run mongodb docker container and connect to it using mongo client before building custom images:
docker run --name some-mongo -e MONGO_INITDB_ROOT_USERNAME=mongoadmin -e MONGO_INITDB_ROOT_PASSWORD=secret -d mongo
docker exec -it some-mongo bash
mongo -u mongoadmin -p secret --authenticationDatabase admin

Starting Postgres in Docker Container

For testing, I'm trying to setup Postgres inside of a docker container so that our python app can run it's test suite against it.
Here's my Dockerfile:
# Set the base image to Ubuntu
FROM ubuntu:16.04
# Update the default application repository sources list
RUN apt-get update && apt-get install -y \
python2.7 \
python-pip \
python-dev \
build-essential \
libpq-dev \
libsasl2-dev \
libffi-dev \
postgresql
USER postgres
RUN /etc/init.d/postgresql start && \
psql -c "CREATE USER circle WITH SUPERUSER PASSWORD 'circle';" && \
createdb -O darwin circle_test
USER root
RUN service postgresql stop && service postgresql start
# Upgrade pip
RUN pip install --upgrade pip
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 5000
# Set the container entrypoint
ENTRYPOINT ["gunicorn", "--config", "/app/config/gunicorn.py", "--access-logfile", "-", "--error-logfile", "-", "app:app"]
When I run:
docker run --entrypoint python darwin:latest -m unittest discover -v -s test
I'm getting:
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
The only way I can get it to work is if I ssh into the container, restart postgres and run the test suite directly.
Is there something I'm missing here?
In a Dockerfile you have
a configuration phase, the RUN directive (and some others)
the process(es) you start, that you put in either
CMD
or
ENTRYPOINT
see the docs
https://docs.docker.com/engine/reference/builder/#cmd
and
https://docs.docker.com/engine/reference/builder/#entrypoint
when a container has completed what it has to do in this start phase, it dies.
This is why the reference Dockerfile for PostgreSQL, at
https://github.com/docker-library/postgres/blob/3d4e5e9f64124b72aa80f80e2635aff0545988c6/9.6/Dockerfile
ends with
CMD ["postgres"]
if you want to start several processes, see supervisord or such tool (s6, daemontools...)
https://docs.docker.com/engine/admin/using_supervisord/

Securing Mongo when in Docker Container

Currently looking at deploying mongo in a container. So far my file looks like,
############################################################
# Dockerfile to build Mongo Containers
# Based on Ubuntu
############################################################
# Set the base image to Ubuntu
FROM ubuntu:14.04
# File Author / Maintainer
MAINTAINER Maintaner felix001
# Create repo file
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
RUN echo "deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-3.0.list
# Update the default application repository sources list
RUN apt-get update && apt-get install -y \
mongodb-org \
vim
# Create the MongoDB data directory
RUN mkdir -p /data/db
# Expose port 27017 from the container to the host
EXPOSE 27017
# Set usr/bin/mongod as the dockerized entry-point application
ENTRYPOINT ["/usr/bin/mongod"]
However I need to lockdown mongo so you need a password to perform any admin actions and also create a database/user. So my question is 2 fold,
What is the best method for securing ? So far I have,
vim /etc/mongod.conf
+ auth = true
use admin
db.createUser({ user:"admin", pwd:"secretpassword", roles: ["dbAdminAnyDatabase","clusterAdmin"]})
use example
db.createUser({ user:"user1", pwd:"abc123", roles:["readWrite"] })
What is the best method for adding this to a Dockerfile ?
Thanks,
I would not recommend "baking" credentials into your image. Every database you create will then have the same password.
For an example take a look at the tutum mongodb image, where the container runs a script set the password on startup:
https://hub.docker.com/r/tutum/mongodb/
https://github.com/tutumcloud/mongodb/tree/master/3.0
Finally, I refer you to a related question concerning the use of environment variables for passwords:
Specifying superuser PostgreSQL password for a Docker Container
Here is how I secured my MongoDB docker container.
Following step-by-step process will guide you to implement the security.
Solution-1 : Using Environment Variable
A simple solution is to use environment variables when docker run command
$ docker run -d -p 27017:27017 --name mongodb -v /var/docker/mongo/data:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=superuser \
-e MONGO_INITDB_ROOT_PASSWORD=Strong_Password \
mongo:4.4.2
When you would try to access using MongoDB client like MongoDB-Compass, then you would have to supply the username and password to access the database.
Solution-2 : Create User in MongoDB Database (Recommended approach)
Create docker container using auth option
$ docker run --name <container_name> --restart=always -d -p 27017:27017 mongo mongod --auth
Bash into the container
$ sudo docker exec -it <container_name> bash
Connect to local mongo instance
# mongo
Create the first admin user
> use admin
> db.createUser({
user: 'user',
pwd: 'StrongPassword',
roles: [{ role: 'dbOwner', db:'admin'}]
})
Exit the mongo shell
> exit
Exit the container
# exit
Now you can connect with the username and password. Remember to use --authenticationDatabase "admin"
mongo -u "user" -p "StrongPassword" YOURHOSTIP --authenticationDatabase "admin"
You can also connect to mongo container via MongoDB-Compass. I connected using the following connection string. Check your string carefully if you couldn't connect
mongodb://user:*****#IP:27017/?authSource=admin&compressors=zlib&readPreference=primary&gssapiServiceName=mongodb&appname=MongoDB%20Compass&ssl=false
Ref: https://gist.github.com/davideicardi/f2094c4c3f3e00fbd490#file-mongo-docker-bash-L23

MongoDB, Docker, Meteor: Connection Refused

Meteor works perfectly if I run "meteor". If I setup MongoDB and run Meteor with MONGO_URL set to "mongodb://127.0.0.1:27017/meteor" then it too works perfectly. However, if I run a Docker Container that calls exactly the same Meteor files on the same machine with the MONGO_URL set as above then I get the error: "Exception in callback of async function: Error: failed to connect to [127.0.0.1:27017]". Logic would state that the introduction of Docker is causing the problem. Therefore, is there something I must do to specifically allow Meteor to call MongoDB from inside a container - such as something additional with the MongoDB ports etc.
Dockerfile is:
FROM ubuntu:14.04
MAINTAINER Me "me#me.com"
RUN apt-get update -y && apt-get install --no-install-recommends -y -q chrpath libfreetype6 libfreetype6-dev libssl-dev libfontconfig1
RUN apt-get install --no-install-recommends -y -q build-essential ca-certificates curl git gcc make nano python
ENV PATH /bin:/usr/local/sbin
RUN curl install.meteor.com | sh
ENV ROOT_URL 127.0.0.1
ENV PORT 3000
ENV MONGO_URL mongodb://127.0.0.1:27017/meteor
EXPOSE 3000
CMD [ "meteor" ]
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
Meteor is called with the following:
docker run --name meteor-dev -it -p 3000:3000 -v /machine/meteor:/opt/meteor -w /opt/meteor meteor-dev
When you are running a container it creates its own network which is isolated from host network.
So when you are tying to connect to Mongo using "mongodb://127.0.0.1:27017/meteor it searches for MongoDB inside your container.
Instead of using 127.0.0.1 use the host ip addresss or hostname.
Or if your MongoDB is running from a container create a link and use the link to start meteor container. Hope this helps