Create a MongoDB database through docker-compose - mongodb

docker-compose.yml
mongo:
image: mongo:3.4.13-jessie
restart: always
ports:
- "27019:27017"
volumes:
- ./db1.js:/docker-entrypoint-initdb.d/db1.js:ro
- ./db2.js:/docker-entrypoint-initdb.d/db2.js:ro
db1.js
use testdba;
db.getCollection("users").insert({
"name": "A"
})
db2.js
use testdbb;
db.getCollection("users").insert({
"name": "B"
})
the files are copied in the mongo container but not executed
my understanding is that files(*.js) inside docker-entrypoint-initdb.d/ gets executed, but with above setup it doesn't
does anyone know what am I missing?
also in some of the post I found
environment:
MONGO_INITDB_ROOT_USERNAME: test
MONGO_INITDB_ROOT_PASSWORD: test
MONGO_INITDB_DATABASE: admin
do I need to add root user before the .js fils can be executed ?

MongoDB finds your files and tries to execute them but it fails. You can see that in the logs: docker-compose logs -f and look for the line where it tries to run your first js file.
To fix it use this syntax in your js files:
db.testdba.getCollection("users").insert({
"name": "A"
});
After you edit both your files start your service with docker-compose up -d. Check again the logs and you will see that the files are executed successfully.

Related

Failed Authentication when connecting with Flask through PyMongo to MongoDB in Docker Compose

I'm using Docker Compose and trying to make two containers talk to each other. One runs a MongoDB database and the other one is a Flask app that needs to read data from the first one using PyMongo.
The Mongo image is defined with the following Dockerfile:
FROM mongo:6.0
ENV MONGO_INITDB_ROOT_USERNAME admin
ENV MONGO_INITDB_ROOT_PASSWORD admin-pwd
ENV MONGO_INITDB_DATABASE admin
COPY mongo-init.js /docker-entrypoint-initdb.d/
EXPOSE 27017
And my data is loaded through the following mongo-init.js script:
db.auth('admin','admin-pwd')
db = db.getSiblingDB('quiz-db')
db.createUser({
user: 'quiz-admin',
pwd: 'quiz-pwd',
roles: [
{
role: 'readWrite',
db: 'quiz-db'
}
]
});
db.createCollection('questions');
db.questions.insertMany([
{
question: "Do you like sushi?",
answers: {
0:"Yes",
1:"No",
2:"Maybe"
}
}
]);
The Flask app is pretty straightforward. I'll skip the Dockerfile for this one as I don't think it's important to the issue. I try to connect to the database with the following code:
from flask import Flask, render_template
from pymongo import MongoClient
app = Flask(__name__)
MONGO_HOST = "questions-db"
MONGO_PORT = "27017"
MONGO_DB = "quiz-db"
MONGO_USER = "quiz-admin"
MONGO_PASS = "quiz-pwd"
uri = "mongodb://{}:{}#{}:{}/{}?authSource=quiz-db".format(MONGO_USER, MONGO_PASS, MONGO_HOST, MONGO_PORT, MONGO_DB)
client = MongoClient(uri)
db=client["quiz-db"]
questions=list(db["questions"].find())
I'm not an expert when it comes to Mongo, but I've set authSource to 'quiz-db' since that's the database where I've created the user in the 'mongo-init.js' script. I tried to run the database container alone and I did successfully log in using mongosh with the user 'quiz-db'. All the data is there and everything works fine.
The problem is only coming up when trying to connect from the Flask app. Here's my Docker compose file:
version: '3.9'
services:
#Flask App
app:
build: ./app
ports:
- "8000:5000"
depends_on:
- "questions-db"
networks:
- mongo-net
#Mongo Database
questions-db:
build: ./questions_db
hostname: questions-db
container_name: questions-db
ports:
- "27017:27017"
networks:
- mongo-net
networks:
mongo-net:
driver: bridge
When I run 'docker compose up' I get the following error on the Flask container startup:
pymongo.errors.OperationFailure: command find requires authentication
full error: {'ok': 0.0, 'errmsg': 'command find requires authentication', 'code': 13, 'codeName': 'Unauthorized'}
MongoDB stores all user credentials in the admin database, unless you are using a really ancient version.
Use authSource=admin in the URI

Running command during docker compose or docker build failed

I am trying to build mongo inside docker and I want to push database, collection and document inside the collection I tried with docker build and below my Dockerfile
FROM mongo
RUN mongosh mongodb://127.0.0.1:27017/demeter --eval 'db.createCollection("Users")'
RUN mongosh mongodb://127.0.0.1:27017/demeter --eval 'var document = {"_id": "61912ebb4b6d7dcc7e689914","name": "Test Account","email":"test#test.net", "role": "admin", "company_domain": "test.net","type": "regular","status": "active","createdBy": "61901a01097cb16e554f5a19","twoFactorAuth": false, "password": "$2a$10$MPDjDZIboLlD8xpc/RfOouAAAmBLwEEp2ESykk/2rLcqcDJJEbEVS"}; db.Users.insert(document);'
EXPOSE 27017
and using Docker Compose
version: '3.9'
services:
web:
build:
context: ./server
dockerfile: Dockerfile
ports:
- "8080:8080"
demeter_db:
image: "mongo"
volumes:
- ./mongodata:/data/db
ports:
- "27017:27017"
command: mongosh mongodb://127.0.0.1:27017/demeter --eval 'db.createCollection("Users")'
demeter_redis:
image: "redis"
I want to add the below records because the Web Server is using them in backend. if there is a better way of doing it I would be thankful.
What I get is the below error
demeter_db_1 | Current Mongosh Log ID: 61dc697509ee790cc89fc7aa
demeter_db_1 | Connecting to: mongodb://127.0.0.1:27017/demeter?directConnection=true&serverSelectionTimeoutMS=2000
demeter_db_1 | MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017
Knowing when I connect to interactive shell inside mongo container and add them manually things works fine.
root#8b20d117586d:/# mongosh 127.0.0.1:27017/demeter --eval 'db.createCollection("Users")'
Current Mongosh Log ID: 61dc64ee8a2945352c13c177
Connecting to: mongodb://127.0.0.1:27017/demeter?directConnection=true&serverSelectionTimeoutMS=2000
Using MongoDB: 5.0.5
Using Mongosh: 1.1.7
For mongosh info see: https://docs.mongodb.com/mongodb-shell/
To help improve our products, anonymous usage data is collected and sent to MongoDB periodically (https://www.mongodb.com/legal/privacy-policy).
You can opt-out by running the disableTelemetry() command.
------
The server generated these startup warnings when booting:
2022-01-10T16:52:14.717+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
2022-01-10T16:52:15.514+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
------
{ ok: 1 }
root#8b20d117586d:/# exit
exit
Cheers

waiting service database running before others services running in Docker [duplicate]

This question already has answers here:
Docker Compose wait for container X before starting Y
(20 answers)
Closed 3 years ago.
I am trying to run my app which depends_on my Postgresql in Docker
let say my database PostgreSQL not running now
and in my docker-compose.yml:
version: "3"
services:
myapp:
depends_on:
- db
container_name: myapp
build:
context: .
dockerfile: Dockerfile
restart: on-failure
ports:
- "8100:8100"
db:
container_name: postgres
restart: on-failure
image: postgres:10-alpine
ports:
- "5555:5432"
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: 12345678
POSTGRES_DB: dev
when I try docker-compose up -d yes it created the postgres and then create that myapp service
but it seems my Postgresql is not running yet, after finish install and running myapp,
it said:
my database server not running yet
how to make myapp running until that db service know that my db running ??
The documentation of depends_on says that:
depends_on does not wait for db to be “ready” before starting myapp - only until it have been started.
So you'll have to check that your database is ready by yourself before running your app.
Docker has a documentation that explains how to write a wrapper script to do that:
#!/bin/sh
# wait-for-postgres.sh
set -e
host="$1"
shift
cmd="$#"
until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$host" -U "postgres" -c '\q'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - executing command"
exec $cmd
Then you can just call this script before running your app in your docker-compose file:
command: ["./wait-for-postgres.sh", "db", "python", "app.py"]
There are also tools such as wait-for-it, dockerize or wait-for.
However these solutions has some limitations and Docker says that:
The best solution is to perform this check in your application code, both at startup and whenever a connection is lost for any reason.
This method will be more resilient.
Here is how I use a retry strategy in javascript:
async ensureConnection () {
let retries = 5
const interval = 1000
while (retries) {
try {
await this.utils.raw('SELECT \'ensure connection\';')
break
} catch (err) {
console.error(err)
retries--
console.info(`retries left: ${retries}, interval: ${interval} ms`)
if (retries === 0) {
throw err
}
await new Promise(resolve => setTimeout(resolve, interval))
}
}
}
Please have a look at: https://docs.docker.com/compose/startup-order/.
Docker-compose won't wait for your database, you need a way to check it externally (via script or retrying the connection as Mickael B. proposed). One of the solutions proposed in the above link is a wait-for.sh utility script - we used it in a project and it worked quite well.

Docker failed to run entry-point

So I have created a node/mongo app and I am trying to run everything on docker.
I can get everything to run just fine until I try and add the init file for the mongo instance into the entry-point.
Here is my docker file for mongo: (Called mongo.dockerfile in /MongoDB)
FROM mongo:4.2
WORKDIR /usr/src/mongo
VOLUME /docker/volumes/mongo /user/data/mongo
ADD ./db-init /docker-entrypoint-initdb.d
CMD ["mongod", "--auth"]
The db-init folder contains an init.js file that looks like so (removed the names of stuff):
db.createUser({
user: '',
pwd: '',
roles: [ { role: 'readWrite', db: '' } ]
})
Here is my docker-compose file:
version: "3.7"
services:
web:
container_name: web
env_file:
- API/web.env
build:
context: ./API
target: prod
dockerfile: web.dockerfile
ports:
- "127.0.0.1:3000:3000"
depends_on:
- mongo
links:
- mongo
restart: always
mongo:
container_name: mongo
env_file:
- MongoDB/mongo.env
build:
context: ./MongoDB
dockerfile: mongo.dockerfile
restart: always
The exact error I get when running a docker-compose up is:
ERROR: for mongo Cannot start service mongo: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"docker-entrypoint-initdb.d\": executable file not found in $PATH": unknown
I had this working at one point with another project but cannot seem to get this on to work at all.
Any thoughts on what I am doing wrong?
Also note I have seen other issues like this saying to chmod +x the path (tried that didnt work)
Also tried to chmod 777 also didnt work. (Maybe I did this wrong and I dont know exactly what to run this on?)
Your entrypoint has been modified from the upstream image, and it's not clear how from the input you've provided. You may have modified the mongo image itself and need to pull a fresh copy with docker-compose build --pull. Otherwise, you can force the entrypoint back to the upstream value:
ENTRYPOINT ["docker-entrypoint.sh"]

ERROR: yaml.parser.ParserError: while parsing a block mapping

I'm building Iroha for which i'm running a script for environment setup which is internally calling the docker-compose.yml, where i"m getting the error:
ERROR: yaml.parser.ParserError: while parsing a block mapping
in "/home/cdac/iroha/docker/docker-compose.yml", line 3, column 5
expected <block end>, but found '<scalar>'
in "/home/cdac/iroha/docker/docker-compose.yml", line 13, column 6
docker-compose.yml file is showing below.
services:
node:
image: hyperledger/iroha:develop-build
ports:
- "${IROHA_PORT}:50051"
- "${DEBUGGER_PORT}:20000"
environment:
- IROHA_POSTGRES_HOST=${COMPOSE_PROJECT_NAME}_postgres_1
- IROHA_POSTGRES_PORT=5432
- IROHA_POSTGRES_USER=iroha
- IROHA_POSTGRES_PASSWORD=helloworld
- CCACHE_DIR=/tmp/ccache
export G_ID=$(id -g $(whoami))
export U_ID=$(id -g $(whoami))
user: ${U_ID:-0}:${G_ID:-0}
depends_on:
- postgres
tty: true
volumes:
- ../:/opt/iroha
- ccache-data:/tmp/ccache
working_dir: /opt/iroha
cap_add:
- SYS_PTRACE
security_opt:
- seccomp:unconfined
postgres:
image: postgres:9.5
environment:
- POSTGRES_USER=iroha
- IROHA_POSTGRES_PASSWORD=helloworld
command: -c 'max_prepared_transactions=100'
volumes:
ccache-data:
any help will be appreciate, thanks in advance.
These lines are not belongs to the docker-compose syntax
export G_ID=$(id -g $(whoami))
export U_ID=$(id -g $(whoami))
Also this line wont be able to work as expected
user: ${U_ID:-0}:${G_ID:-0}
You should write your own shell script and use it as an entry point for the docker container (this should be done in the Dockerfile step) then run a container directly from the image that you have created without the need to assign a user or export anything within the docker-compose as it will be executed once your container is running.
Check the following URL which contains more explanation about the allowed keywords in docker-compose: Compose File: Service Configuration Reference
#MostafaHussein I removed the above 3 lines then executed the run-iroha-dev.sh script, and it started to work. it attached me to /opt/iroha in docker container and downloaded hyperledger/iroha:develop-build and iroha images and launched two containers.
is it same what you are suggesting?