Authentication issue in Docker-MongoDB - mongodb

I have installed MongoDB in Linux Ubuntu through the docker image.
I have set the parameters in the YAML file like below to implement the authentication for mongodb. But when I up the server using the command docker-compose up -d, I'm getting error like
"Unsupported config option for 'db' service: 'security'".
How can I resolve the issue?
docker-compose.yaml:
db:
image: mongo:2.6.4
command: ["mongod", "--smallfiles"]
expose: "27017"
ports: "27017:27017"
security: keyFile: "/home/ubuntu/dockerlab/keyfile.key"
authorization: "enabled"

security and authorization are not a keyword for the docker-compose YAML file, so take them out of there.
If that file key file needs copying into the container, you should put something like:
FROM: mongo:2.6.4
ADD /home/ubuntu/dockerlab/keyfile.key /tmp
ENV AUTH yes
in a Dockerfile.
And change in the docker-compose.yml file:
image: mongo:2.6.4
into
build: .
and the command value into
command: ["mongod", "--smallfiles", "--keyFile /tmp/keyfile.key" ]
Alternatively you can use a volume entry in your docker-compose.yml to map the keyfile.key into your container, and instead of the ENV in the Dockerfile you add , "--auth" to sequence that is the value for command. Then you can continue to use the image stanza and leave out the Dockerfile altogether:
db:
image: mongo:2.6.4
command: ["mongod", "--smallfiles", "--auth", "--keyFile /tmp/keyfile.key" ]
expose: "27017"
ports: "27017:27017"
volumes:
- /home/ubuntu/dockerlab/keyfile.key: /tmp

Related

docker-entrypoint-initdb.d not executing scripts

I'm using docker-compose version 1.25.5, build 8a1c60f6 &
Docker version 19.03.8, build afacb8b
I'm trying to initialise database with Users in MongoDb container using docker-entrypoint-initdb.d but,
js/scripts aren't being executed when container starts.
I know /data/db must be empty for it execute so I've been deleting it every time before start. But still doesn't execute. Going into the container and manually executing mongo mongo-init.js works.
Not sure why it's not working when it should.
docker-compose.yml:
version: '3'
services:
mongodb:
container_name: "mongodb"
image: tonyh308/cv-mongodb:1
build: ./mongo
container_name: mongodb
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_DATABASE: test
volumes:
- ./docker-entrypoint-initdb.d/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
- ./mongo/mongodb:/data/db
labels:
com.qa.description: "MongoDb Container for application."
# other services ...
Dockerfile:
FROM mongo:3.6.18-xenial
RUN apt-get update
COPY ./Customers /Customers
COPY ./test /test
WORKDIR /data
ENTRYPOINT ["mongod", "--bind_ip_all"]
EXPOSE 27017
Feb 26 2021: still no solution

Starting Tryton server with docker-compose file

I am trying to link an external postgres to tryton/tryton from docker hub.
docker-compose.yaml
version: '3.7'
services:
tryton-postgres:
image: postgres
ports:
- 5432:5432
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_DB=tryton
restart: always
gnuserver:
image: tryton/tryton:4.6
links:
- tryton-postgres:postgres
ports:
- 8000:8000
depends_on:
- tryton-postgres
entrypoint: /entrypoint.sh trytond
when i ssh into the container and run trytond-admin --all -d tryton it seems to be looking for sqlite file instead of the connected postgres database. Are there some env variagbles i must set? What am i missing in my docker compose file?
Instead of changing the configuration file, with Docker it is simpler to set environment variable like:
DB_USER=
DB_PASSWORD=
DB_HOSTNAME=tryton-postgres
DB_PORT=5432
you need to edit /etc/tryton/trytond.conf to look at postgresql:
uri = postgresql://USERNAME:PASSWORD#tryton-postgres:5432/
see the Docs

How do I properly set up my Keystone.js app to run in docker with mongo?

I have built my app which runs fine locally. When I try to run it in docker (docker-compose up) it appears to start, but then throws an error message:
Creating mongodb ... done
Creating webcms ... done
Attaching to mongodb, webcms
...
Mongoose connection "error" event fired with:
MongoError: failed to connect to server [localhost:27017] on first connect
...
webcms exited with code 1
I have read that with Keystone.js you need to configure the Mongo location in the .env file, which I have:
MONGO_URI=mongodb://localhost:27017
Here is my Docker file:
# Use node 9.4.0
FROM node:9.4.0
# Copy source code
COPY . /app
# Change working directory
WORKDIR /app
# Install dependencies
RUN npm install
# Expose API port to the outside
EXPOSE 3000
# Launch application
CMD ["node","keystone"]
...and my docker-compose
version: "2"
services:
# NodeJS app
web:
container_name: webcms
build: .
ports:
- 3000:3000
depends_on:
- mongo
# MongoDB
mongo:
container_name: mongo
image: mongo
volumes:
- ./data:/data/db/mongo
ports:
- 27017:27017
When I run docker ps it confirms that mongo is up and running in a container...
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3e06e4a5cfe mongo "docker-entrypoint.s…" 2 hours ago Up 2 hours 0.0.0.0:27017->27017/tcp mongodb
I am either missing some config or I have it configured incorrectly. Could someone tell me what that is?
Any help would be appreciated.
Thanks!
It is not working properly because you are sending the wrong host.
your container does not understand what is localhost:27017 since it's your computer address and not its container address.
Important to understand that each service has it's own container with a different IP.
The beauty of the docker-compose that you do not need to know your container address! enough to know your service name:
version: "2"
volumes:
db-data:
driver: local
services:
web:
build: .
ports:
- 3000:3000
depends_on:
- mongo
environment:
- MONGO_URI=mongodb://mongo:27017
mongo:
image: mongo
volumes:
- "db-data:/data/db/mongo"
ports:
- 27017:27017
just run docker-compose up and you are all-set
A couple of things that may help:
First. I am not sure what your error logs look like but buried in my error logs was:
...Error: The cookieSecret config option is required when running Keystone in a production environment.Update your app or environment config so this value is supplied to the Keystone constructor....
To solve this problem, in your Keystone entry file (eg: index.js) make sure your Keystone constructor has the cookieSecret parameter set correctly: process.env.NODE_ENV === 'production'
Next. Change the mongo uri from the one Keystone generated (mongoUri: mongodb://localhost/my-keystone) to: mongoUri: 'mongodb://mongo:27017'. Docker needs this because it is the mongo container address. This change should also be reflected in your docker-compose file under the environment variable under MONGO_URI:
... environment: - MONGO_URI=mongodb://mongo:27017 ...
After these changes your Keystone constructor should look like this:
const keystone = new Keystone({
adapter: new Adapter(adapterConfig),
cookieSecret: process.env.NODE_ENV === 'production',
sessionStore: new MongoStore({ url: 'mongodb://mongo:27017' }),
});
And your docker-compose file, something like this (I used a network instead of links for my docker-compose as Docker has stated that links are a legacy option. I've included mine in case its useful for anyone else):
version: "3.3"
services:
mongo:
image: mongo
networks:
- appNetwork
ports:
- "27017:27017"
environment:
- MONGO_URI=mongodb://mongo:27017
appservice:
build:
context: ./my-app
dockerfile: Dockerfile
networks:
- appNetwork
ports:
- "3000:3000"
networks:
appNetwork:
external: false
It is better to use mongo db atlas if you does not want complications. You can use it in local and in deployment.
Simple steps to get the mongo url is available in https://www.mongodb.com/cloud/atlas
Then add a env variable
CONNECT_TO=mongodb://your_url
For passing the .env to docker, use
docker run --publish 8000:3000 --env-file .env --detach --name kb keystoneblog:1.0

Docker-compose mongoose

I'm new to Docker, and I'm trying the simplest of setups with docker-compose, but don't succeed to connect to Mongodb.
My docker-compose.local.yaml file:
version: "2"
services:
posts-api:
build:
dockerfile: Dockerfile.local
context: ./
volumes:
- ".:/app"
ports:
- "6820:6820"
depends_on:
- mongodb
mongodb:
image: mongo:3.5
ports:
- "27018:27018"
command: mongod --port 27018
My Docker file:
FROM node:7.8.0
MAINTAINER Livefeed 'project.livefeed#gmail.com'
RUN mkdir /app
VOLUME /app
WORKDIR /app
ADD package.json yarn.lock ./
RUN eval rm -rf node_modules && \
yarn
ADD server.js .
RUN mkdir config src
ADD config config/
ADD src src/
EXPOSE 6820
EXPOSE 27018
CMD yarn run local
In server.js I try to connect with:
mongoose.connect('mongodb://localhost:27018');
I also tried:
mongoose.connect('mongodb://mongodb:27018');
To run docker-compose:
docker-compose -f docker-compose.local.yaml up --build
And I receive the error:
connection error: { MongoError: failed to connect to server [localhost:27018] on first connect [MongoError: connect ECONNREFUSED 127.0.0.1:27018]
What am I missing?
In server.js use mongodb instead of localhost:
mongoose.connect('mongodb://mongodb:27018');
Because containers in the same network can communicate using their service name.
Bear in mind that each container and your host have their own localhost. Each localhost is a different host: container A, container B, your host (each one has its own network interface).
Edit:
Be sure to get your mongo up:
docker-compose logs mongodb
docker-compose ps
Sometimes it doesn't get up because of disk space.
Edit 2:
With newer versions of mongo, you need to specify to listen to all interfaces too:
command: mongod --port 27018 --bind_ip_all
I think, that you should add links option in your config. Like this:
ports:
- "6820:6820"
depends_on:
- mongodb
links:
- mongodb
update
As I promised
version: '2.1'
services:
pm2:
image: keymetrics/pm2-docker-alpine:6
restart: always
container_name: pm2
volumes:
- ./pm2:/app
links:
- redis_db
- db
environment:
REDIS_CONNECTION_STRING: redis://redis_db:6379
nginx:
image: firesh/nginx-lua
restart: always
volumes:
- ./nginx:/etc/nginx
- /var/run/docker.sock:/tmp/docker.sock:ro
ports:
- 80:80
links:
- pm2
s3: # mock for development
image: lphoward/fake-s3:latest
redis_db:
container_name: redis_db
image: redis
ports:
- 6379:6379
db: # for scorebig-syncer
image: mysql:5.7
ports:
- 3306:3306

How to create user in mongodb with docker-compose

I'm trying to create some kind of script that will create a docker with mongodb and automatically create a user.
I can usually manage my docker images with docker-compose but this time, I don't know how to do it.
Basically, here is what I have to do:
clean/destroy container (docker-compose down)
create a docker container with mongodb and start it (without --auth parameter)
execute a java script containing db.createUser()
stop the container
restart the same container with --auth parameter to allow login with the user created in the javascript
I can't find how to do that properly with docker-compose because when it starts, I have to give it the command --auth. If I do that, I cannot execute my javascript to add my user. MongoDB allows users creation without being logged in if there is no user and if --auth parameter is not provided.
I want to do that automatically, I do not want to manually do some commands. The goal is to have a script that can be executed before each integration tests to start from a clean database.
Here is my project:
integration-test/src/test/resources/scripts/docker-compose.yml
mongodb:
container_name: mongo
image: mongo
ports:
- "27017:27017"
volumes:
- .:/setup
command: --auth
integration-test/src/test/resources/scripts/docker-init.sh
docker-compose down
docker-compose up -d
sleep 1
docker exec mongo bash -c "mongo myDatabase /setup/mongodb-setup.js"
integration-test/src/test/resources/scripts/mongodb-setup.js
db.createUser(
{
user: "myUser",
pwd: "myPassword",
roles: [
{ role: "readWrite", db: "myDatabase" }
]
})
Finding a way to start again a container with a new parameter (in this case --auth) would help but I can't find how to do that (docker start does not take parameters).
Any idea how I should do what I would like ?
If not, I can still delete everything from my database with some Java code or something else but I would like a complete mongodb docker setup created with a script.
The official mongo image now supports following environment variables that can be used in docker-compose as below:
environment:
- MONGO_INITDB_ROOT_USERNAME=user
- MONGO_INITDB_ROOT_PASSWORD=password
- MONGO_INITDB_DATABASE=test
more explanation at:
https://stackoverflow.com/a/42917632/1069610
This is how I do it, my requirement was to bring up a few containers along with mongodb, the other containers expect a user to be present when they come up, this worked for me. The good part is, the mongoClientTemp exits after the command is executed so the container doesn't stick around.
version: '2'
services:
mongo:
image: mongo:latest
container_name: mongo
ports:
- "27017:27017"
volumes:
- /app/hdp/mongo/data:/data/db
mongoClientTemp:
image: mongo:latest
container_name: mongoClientTemp
links:
- mongo:mongo
command: mongo --host mongo --eval "db.getSiblingDB('dashboard').createUser({user:'db', pwd:'dbpass', roles:[{role:'readWrite',db:'dashboard'}]});"
depends_on:
- mongo
another-container:
image: another-image:v01
container_name: another-container
ports:
- "8080:8080"
volumes:
- ./logs:/app/logs
environment:
- MONGODB_HOST=mongo
- MONGODB_PORT=27017
links:
- mongo:mongo
depends_on:
- mongoClientTemp
EDIT: tutumcloud repository is deprecated and no longer maintained, see other answers
I suggest that you use environment variables to set mongo user, database and password. tutum (owned by Docker) published a very good image
https://github.com/tutumcloud/mongodb
docker run -d -p 27017:27017 -p 28017:28017 -e MONGODB_USER="user" -e MONGODB_DATABASE="mydatabase" -e MONGODB_PASS="mypass" tutum/mongodb
You may convert these variables into docker-compose environments variables. You don't have to hard code it.
environment:
MONGODB_USER: "${db_user_env}"
MONGODB_DATABASE: "${dbname_env}"
MONGODB_PASS: "${db_pass}"
This configuration will read from your session's environment variables.
In your project directory create another directory docker-entrypoint-initdb.d then the
file tree looks like this:
📦Project-directory
┣ 📂docker-entrypoint-initdb.d
┃ ┗ 📜mongo-init.js
┗ 📜docker-compose.yaml
The docker-compose.yml contains:
version: "3.7"
services:
mongo:
container_name: container-mongodb
image: mongo:latest
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: root-db
volumes:
- ./docker-entrypoint-initdb.d/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
mongo-init.js contains the javascript code to create user with different roles.
print("Started Adding the Users.");
db = db.getSiblingDB("admin");
db.createUser({
user: "userx",
pwd: "1234",
roles: [{ role: "readWrite", db: "admin" }],
});
print("End Adding the User Roles.");
You can modify the mongo-init.js as you need.
After reading the the official mongo docker page, I've found that you can create an admin user one single time, even if the auth option is being used. This is not well documented, but it simply works (hope it is not a feature).
Therefore, you can keep using the auth option all the time.
I created a github repository with scripts wrapping up the commands to be used. The most important command lines to run are:
docker exec db_mongodb mongo admin /setup/create-admin.js
docker exec db_mongodb mongo admin /setup/create-user.js -u admin -p admin --authenticationDatabase admin
The first line will create the admin user (and mongo will not complain even with auth option). The second line will create your "normal" user, using the admin rights from the first one.
Mongo image provides the /docker-entrypoint-initdb.d/ path to deploy custom .js or .sh setup scripts.
Check this post to get more details :
How to create a DB for MongoDB container on start up?
file: docker-compose.yaml
mongo:
image: mongo:latest
volumes_from:
- data
ports:
- "27017:27017"
command: --auth
container_name: "db_mongodb"
data:
image: mongo:latest
volumes:
- /var/lib/mongo
- ./setup:/setup
command: "true"
container_name: "db_mongodb_data"
file: .buildMongo.sh
#!/bin/sh
docker-compose down
docker-compose up -d
sleep 1
docker exec db_mongodb mongo admin /setup/create-admin.js
docker exec db_mongodb mongo myDb /setup/create-user.js -u admin -p admin --authenticationDatabase admin
The create-admin.js and create-user.js files are commands that you use using the mongo shell. So they must be easy for you to understand. The real direction is like the jzqa answer, "environment variables".
So the question here is how to create a user. I think this answers that point at least, you can check the complete setup here https://github.com/Lus1t4nUm/mongo_docker_bootstrap
For initializing mongo with initial user-password-db triple and initdb scripts with only one docker-compose.yml, without any extra configuration, you can use bitnami/mongo image.
In my case, I didn't run my scripts under /docker-entrypoint-initdb.d directory in the container after setting environment variables; MONGODB_USERNAME and MONGODB_PASSWORD (specific env variables for bitnami image) because mongod runs with --auth option automatically when you set these variables. Consequently, I got authentication errors when the container was in the process of executing the scripts.
Because, it was connecting to: mongodb://192.168.192.2:27017/compressors=disabled&gssapiServiceName=mongodb
TERMINAL LOG OF THE ERROR
FIRST DOCKER-COMPOSE FILE:
version: "3"
services:
mongodb:
container_name: mongodb
image: 'docker.io/bitnami/mongodb:4.2-debian-10'
ports:
- "27017:27017"
volumes:
- "mongodb_data:/bitnami/mongodb"
- "./mongodb/scripts:/docker-entrypoint-initdb.d"
environment:
- MONGODB_INITSCRIPTS_DIR=/docker-entrypoint-initdb.d
- MONGODB_USERNAME=some_username
- MONGODB_PASSWORD=some_password
- MONGODB_DATABASE=some_db_name
networks:
backend:
restart: unless-stopped
volumes:
mongodb_data:
networks:
backend:
driver: bridge
INIT JS FILE UNDER ./mongodb/scripts PATH:
let db = connect("localhost:27017/some_db_name");
db.auth("some_username", "some_password");
let collections = db.getCollectionNames();
let storeFound = false;
let index;
for(index=0; index<collections.length; index++){
if ("store" === collections[index]){
storeFound = true;
}
}
if(!storeFound ){
db.createCollection("store");
db.store.createIndex({"name": 1});
}
So, I decided to add new environment variables to my docker-compose.yml after inspecting https://github.com/bitnami/bitnami-docker-mongodb/blob/master/4.2/debian-10/rootfs/opt/bitnami/scripts/libmongodb.sh file.
In this sh file, there is function like mongodb_custom_init_scripts() for executing the scripts. For executing all script files, it runs mongodb_execute() method. In this method, after mongod instance is up and run, mongo client is connecting to the mongod instance by using some parameters.
########################
# Execute an arbitrary query/queries against the running MongoDB service
# Stdin:
# Query/queries to execute
# Arguments:
# $1 - User to run queries
# $2 - Password
# $3 - Database where to run the queries
# $4 - Host (default to result of get_mongo_hostname function)
# $5 - Port (default $MONGODB_PORT_NUMBER)
# $6 - Extra arguments (default $MONGODB_CLIENT_EXTRA_FLAGS)
# Returns:
# None
########################
mongodb_execute() {
local -r user="${1:-}"
local -r password="${2:-}"
local -r database="${3:-}"
local -r host="${4:-$(get_mongo_hostname)}"
local -r port="${5:-$MONGODB_PORT_NUMBER}"
local -r extra_args="${6:-$MONGODB_CLIENT_EXTRA_FLAGS}"
local result
local final_user="$user"
# If password is empty it means no auth, do not specify user
[[ -z "$password" ]] && final_user=""
local -a args=("--host" "$host" "--port" "$port")
[[ -n "$final_user" ]] && args+=("-u" "$final_user")
[[ -n "$password" ]] && args+=("-p" "$password")
[[ -n "$extra_args" ]] && args+=($extra_args)
[[ -n "$database" ]] && args+=("$database")
"$MONGODB_BIN_DIR/mongo" "${args[#]}"
}
After that I added new environment variables to my docker-compose like MONGODB_ADVERTISED_HOSTNAME, MONGODB_PORT_NUMBER, and, MONGODB_CLIENT_EXTRA_FLAGS
So my final docker-compose.yml looks like:
version: "3"
services:
mongodb:
container_name: mongodb
image: 'docker.io/bitnami/mongodb:4.2-debian-10'
ports:
- "27017:27017"
volumes:
- "mongodb_data:/bitnami/mongodb"
- "./mongodb/scripts:/docker-entrypoint-initdb.d"
environment:
- MONGODB_INITSCRIPTS_DIR=/docker-entrypoint-initdb.d
- MONGODB_USERNAME=some_username
- MONGODB_PASSWORD=some_password
- MONGODB_DATABASE=some_db_name
- MONGODB_ADVERTISED_HOSTNAME=localhost
- MONGODB_PORT_NUMBER=27017
- MONGODB_CLIENT_EXTRA_FLAGS=--authenticationDatabase=some_db_name
networks:
backend:
restart: unless-stopped
volumes:
mongodb_data:
networks:
backend:
driver: bridge
Now, it was connecting by this url:
mongodb://localhost:27017/?authSource=some_db_name&compressors=disabled &gssapiServiceName=mongodb
add --noauth option to the mongo command
extract from my docker-compose.yml file
mongors:
image: mongo:latest
command: mongod --noprealloc --smallfiles --replSet mongors2 --dbpath /data/db --nojournal --oplogSize 16 --noauth
environment:
TERM: xterm
volumes:
- ./data/mongors:/data/db