Docker mongo image always save the data inside /data/db directory - mongodb

I am using docker image for mongo. I changed the directory where I want to save my data inside the mongo.conf file:
dbpath=/mnt/sda1/data/db/
Also I am using docker-compose to create my development environment:
mongo:
image: mongo
ports:
- 27017:27017
volumes:
- $HOME/Desktop/development/mongo/data/:/mnt/sda1/data/db/
- $HOME/Desktop/mongo/config/mongod.conf:/etc/mongod.conf.orig
command: mongod --smallfiles
When I go inside my mongo container and I check the /mnt/sda1/data/db directoy, it is empty and then go to /data/db and the data is here.
I don't understand why the data isn't inside the directory /mnt/sda1/data/db is I defined it has the dbpath for mongo configuration file.

Seems that you are naming the config file /etc/mongod.conf.orig inside the container. You probably should name it /etc/mongod.conf.
Also, unlike docker run, you can use relative path for the volume option in your docker-compose.yml file and don't have to use $HOME.

Related

Mongodb authentication issue when using same volume

I am using mongo db in the docker container. I am using docker compose to spin up mongo. Now we have old mongo containers running and authentication is not enforced. In order to use authentication enforced and start up script I am using .env filein my docker compose file as below. But .env file and startup script are taking place only if I change the volume. By using same volume both .env file and startup script is not taking any effect. Is there any way to use the same volume and create users using .env and also use start up script.
services:
mongo:
image: mongo
container_name: mongot
restart: always
env_file:
- .env
ports:
- 27019:27017
volumes:
- /data/db8/configdb:/data/configdb
- /data/db8/db:/data/db
- $PWD/mongoentry/:/docker-entrypoint-initdb.d/
network_mode: "bridge"
command: mongod
Environment files and startup scripts are only used when creating a new database. If a database already exists, they aren't used.
In your case, you already have a database in the volume, so they aren't used. But if you change the volume so no database exists, Mongo creates a new one using your values and scripts.
From the docs:
When you start the mongo image, you can adjust the initialization of
the MongoDB instance by passing one or more environment variables on
the docker run command line. Do note that none of the variables below
will have any effect if you start the container with a data directory
that already contains a database

Creating mongo docker container with local storage on hos

I want to run mongo db in docker container. I've pulled image and run it. So it seems work ok.
But every time I start it the DB is overwritten so I loose any changes. So I want to want to map somehow internal container storage on my local host folder.
Should I write Dockerfile or/and docker-compose.yaml? I suppose this is simple question but being new in docker I can't understand what to read to get full understanding.
You do not need to write Dockerfile and make thing complex, just use offical image as mentioned in command or compose file.
You can use both options either docker run or docker-compose but the path should be correct in mapping to keep data persistent.
Here is way
Create a data directory on a suitable volume on your host system, e.g. /my/own/datadir.
Start your mongo container like this:
$ docker run --name some-mongo -v /my/own/datadir:/data/db -d mongo
The -v /my/own/datadir:/data/db part of the command mounts the
/my/own/datadir directory from the underlying host system as /data/db
inside the container, where MongoDB by default will write its data
files.
mongo docker volume
with docker-compose
version: "2"
services:
mongo:
image: mongo:latest
restart: always
ports:
- "27017:27017"
environment:
- MONGO_INITDB_DATABASE=pastime
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=root_password
volumes:
- /my/own/datadir:/data/db

How to reduce mongo log verbosity in a docker-compose image?

I'm running MongoDB inside a larger server, controlled by docker-compose.
I'd like to reduce the verbosity of the Mongo logs (and probably eventually control other Mongo settings too). Not sure where to fit this into my minimal config; I currently just have:
mongo:
image: mongo:3.2
volumes:
- ${MONGO_DATA_DB}:/data/db
ports:
- ${EXPOSED_MONGO_PORT}:27017
I've tried the accepted answer but mongo log was still quite verbose. Then, following this thread, I've omitted the whole log and it's much better in my case:
mongo:
command: mongod --quiet --logpath /dev/null
Reading the description of the official image of MongoDB at DockerHub (same image you are using) I deduced that you can pass commands to mongod using command section of the docker-compose. Then you could use the --quiet option to limit the amount of output.
In this way you docker-compose would be as follows:
mongo:
image: mongo:3.2
volumes:
- ${MONGO_DATA_DB}:/data/db
ports:
- ${EXPOSED_MONGO_PORT}:27017
command: --quiet
You can find the entire list of options that mongod accepts here or also check the --help output of mongod in your bash.
Sometimes docker images, accepts configuration params as an environment variables, so you could change the configuration of the service at runtime. Sadly I couldn't find any official information about available environment variables in this docker image, but I encourage you to continue investigating about this alternative path.
I hope it helps!
EDIT
Another approach from the image documentation:
For a more complicated configuration setup, you can still use the MongoDB configuration file. mongod does not read a configuration file by default, so the --config option with the path to the configuration file needs to be specified. Create a custom configuration file and put it in the container by either creating a custom Dockerfile FROM mongo or mounting it from the host machine to the container. See the MongoDB manual for a full list of configuration file options.
For example, /my/custom/mongod.conf is the path to the custom configuration file. Then start the MongoDB container like the following:
$ docker run --name some-mongo -v /my/custom:/etc/mongo -d mongo --config /etc/mongo/mongod.conf
In this way, your docker-compose would be as follows:
mongo:
image: mongo:3.2
volumes:
- ${MONGO_DATA_DB}:/data/db
- ${MONGO_DATA_CONFIG}:/etc/mongo/
ports:
- ${EXPOSED_MONGO_PORT}:27017
command: --config /etc/mongo/mongod.conf
Setting logpath worked for me. It's not showing the logs output instead it's saving to the file.
mongo:
container_name: mongo
image: mongo
restart: unless-stopped
command:
- '--logpath'
- '/var/log/mongodb/mongod.log'
ports:
- '27017:27017'
An alternative MongoDB image by Bitnami offers this functionality via environment variables in compose file.
https://hub.docker.com/r/bitnami/mongodb. Explained in the section Configuring system log verbosity level

How to persist default data and running app data of mongo db with docker images and docker-compose

I have to create a mongo image with some default collection and data. I am able to create mongo image with this data by referring the following link :-
How to create a Mongo Docker Image with default collections and data?
so when I run the container I get the default data.
Now when I use the app and some more data is generated(by calling API's) which gets saved again in mongodb with default data.
Now for some reason if docker container is re-started, unfortunately, all the run-time created data is gone and only default data is left. Though I am saving data using volumes.
So how to persist the run time data and default data each time docker is restarted?
I am using following docker file and docker-compose file
Dockerfile :
FROM mongo
####### working isnerting data $##########
# Modify child mongo to use /data/db2 as dbpath (because /data/db wont persist the build)
RUN mkdir -p /data/db2 \
&& echo "dbpath = /data/db2" > /etc/mongodb.conf \
&& chown -R mongodb:mongodb /data/db2
COPY . /data/db2
RUN mongod --fork --logpath /var/log/mongodb.log --dbpath /data/db2 --smallfiles \
&& mongo 127.0.0.1:27017/usaa /data/db2/config-mongo.js \
&& mongod --dbpath /data/db2 --shutdown \
&& chown -R mongodb /data/db2
# Make the new dir a VOLUME to persists it
VOLUME /data/db2
CMD ["mongod", "--config", "/etc/mongodb.conf", "--smallfiles"]
and a part of docker-compose.yml
services:
mongo:
build: ./mongodb
image: "mongo:1.2"
container_name: "mongo"
ports:
- "27017:27017"
volumes:
- ${LOCAL_DIRECTORY}:/data/db2
networks:
- some-network
Reason may be, by rebuilding docker image its creating /data/db2 directory with only default data defined in .js file. But not sure.
Please correct me what I am doing wrong or suggest a new work-flow for this problem.
Thanks much!
Because docker is stateless by default. Each time you call docker run it rebuilds the container. If you want some data to persist, you have 2 general approaches:
Not to remove the container after it exits. Just give the lovely name to your container when first starting it, like docker run --name jessica mongo and then, on subsequent calls, use docker start jessica
Use volumes to store data and share it between containers. In this case you will start your container with volume arguments, like docker run -v /home/data:/data mongo. Also, you will have to reconfigure your mongodb to save data in path /data inside container. This approach is easier and can be used to share data between different containers, as well as providing default data for the first run
UPD
When using docker-compose to start the containers, if you need your data to persist between sessions, you can simply use external volumes, which you create in advance.
First create volume, lets say lovely:
docker volume create lovely
Then use it in docker-compose.yml:
version: '3'
services:
db1:
image: whatever
volumes:
- lovely:/data
db2:
image: whatever
volumes:
- lovely:/data
volumes:
lovely:
external: true

Need some advice dockerizing MongoDB

I am playing with MongoDB and Docker and at this point I am trying to create a useful image for myself to use at work. I have created the following Dockerfile:
FROM mongo:2.6
VOLUME /data/db /data/configdb
CMD ["mongod"]
EXPOSE 27017
And I have added it to my docker-compose.yml file:
version: '2'
services:
### PHP/Apache Container
php-apache:
container_name: "php55-dev"
image: reynierpm/php55-dev
ports:
- "80:80"
environment:
PHP_ERROR_REPORTING: 'E_ALL & ~E_DEPRECATED & ~E_NOTICE'
volumes:
- ~/mmi:/var/www
- ~/data:/data
links:
- mongodb
### MongoDB Container
mongodb:
container_name: "mongodb"
build: ./mongo
environment:
MONGODB_USER: "xxxx"
MONGODB_DATABASE: "xxxx"
MONGODB_PASS: "xxxx"
ports:
- "27017:27017"
volumes:
- ~/data/mongo:/data/db
I have some questions regarding this setup I have made:
Do I need VOLUME /data/db /data/configdb at the Dockerfile or would be enough to have this line ~/data/mongo:/data/configdb at docker-compose.yml?
I am assuming (and I took it from here) that as soon as I build the Mongo image I will be creating a database and giving full permissions to the user with password as it's on the environment variables? I am right? (I couldn't find anything helpful here)
How do I import a current mongo backup (several JSON files) into the database that should be created on the mongo container? I believe I need to run mongorestore command but how? do I need to create an script and run it each time the container start? or should I run during image build? What's the best approach?
Do I need VOLUME /data/db /data/configdb at the Dockerfile or would be enough to have this line ~/data/mongo:/data/configdb at docker-compose.yml?
VOLUME is not required when you are mounting a host directory but it is helpful as metadata. VOLUME does provide some special "copy data on volume creation" semantics when mounting a Docker volume (non host dir) which will impact your data initialisation method choice.
am assuming (and I took it from here) that as soon as I build the Mongo image I will be creating a database and giving full permissions to the user with password as it's on the environment variables? I am right? (I couldn't find anything helpful here)
MONGO_USER, MONGO_DATABASE and MONGO_PASS do not do anything in the official mongo Docker image or to mongod itself.
The mongo image has added support for similar environment variables:
MONGO_INITDB_ROOT_USERNAME
MONGO_INITDB_ROOT_PASSWORD
MONGO_INITDB_DATABASE
How do I import a current mongo backup (several JSON files) into the database that should be created on the mongo container? I believe I need to run mongorestore command but how? do I need to create an script and run it each time the container start? or should I run during image build? What's the best approach?
Whether you initialise data at build or runtime is up to your usage. As mentioned previously, Docker can copy data from a specified VOLUME into a volume it creates. If you are mounting a host directory you probably need to do the initialisation at run time.
mongorestore requires a running server to restore to. During a build you would need to launch the server and restore in the same RUN step. At runtime you might need to include a startup script that checks for existence of your database.
Mongo is able to initialise any empty directory into a blank mongo instance so you don't need to be worried about mongo not starting.