Create mongo image having initial collections with docker file - mongodb

I am trying to create a custom mongo image from the official image with few custom collections baked into the image.
I have created a init script that runs and import json into the database using mongoimport.
Docker file builds correctly and I can see the scripts runs successfully.
But when i run the container with the generated image I am unable to see the added collecitons.
Docker file:
FROM mongo:latest
RUN mkdir -p /data/db2 \
&& echo "dbpath = /data/db2" > /etc/mongodb.conf \
&& chown -R mongodb:mongodb /data/db2
COPY ./upload.json /json/
COPY ./init.sh .
RUN ./init.sh
VOLUME /data/db2
CMD ["mongod", "--config", "/etc/mongodb.conf"]
#docker build -f Dockerfile -t my-mongo/test:1.0 .
init.sh:
#!/usr/bin/env bash
mongod --fork --logpath /var/log/mongodb.log --dbpath /data/db2
mongoimport -d testStore -c authors --file ./json/upload.json --jsonArray
mongod --dbpath /data/db2 --shutdown
upload.json:
[
{ "Name": "Design Patterns", "Price": 54.93, "Category": "Computers", "Author": "Ralph Johnson" },
{ "Name": "Clean Code", "Price": 43.15, "Category": "Computers", "Author": "Robert C. Martin" }
]

Related

Trying to set replica-set in custom made mongodb-org on top of linux ubuntu:20.04 Image in dockerfile

I have tried the mongodb installation by trying the official instruction for installing mongodb-org in ontop ubuntu:20.04 docker image manualy. but the problem is when i install it. it does not run properly. and also after successful installation i also wants to set replicaset inside this image. I cannot use. and i also cannot use official docker image of mongo for mongodb because may goal is to add conda setting with some other settings inside docker container along with mongodb-org setup inside same container. but it is not working i have tried so many solution but nothin found for custom images. please suggest what should i do i have taken two weeks already for this project already.
here is the Dockerfile
# syntax=docker/dockerfile:1
FROM ubuntu:20.04
FROM mongo:4.4
ENV DEBIAN_FRONTEND=noninteractive
SHELL ["/bin/bash", "-c"]
RUN mkdir /var/DS_Services
WORKDIR /var/server_setup
# COPY DS_Services /var/
COPY basic_libs/ .
COPY mongo_files/ .
COPY DS_Services /var/DS_Services
COPY ml_env.yml .
RUN bash basic_libs.sh && bash install_mongo.sh && \
bash start.sh && \
# CMD ['mongod']
# RUN mongod --replSet rs0 --bind_ip_all
# CMD [ "/usr/bin/mongod", "--replSet", "rs0", "--bind_ip_all"]
bash replicaSet.sh
ENV CONDA_DIR /var/anaconda3
ENV PATH=$CONDA_DIR/bin:$PATH
# SHELL ["conda", "run", "-n", "ml_env", "/bin/bash", "-c"]
ENTRYPOINT [ "/usr/bin/mongod", "--replSet", "rs0", "--bind_ip_all"]
# CMD ["conda", "run", "-n", "ml_env", "/bin/bash", "start.sh"]
CMD ["start_services.sh"]
and here is my install_mongo.sh file:
echo "Begining installation of MongoDB Server ... "
wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
apt-get update \
&& apt-get -y install mongodb-org
mkdir -p /opt/mongo
openssl rand -base64 756 > /opt/mongo/mongo-keyfile
sudo chown mongodb:mongodb /opt/mongo/mongo-keyfile
chmod 400 /opt/mongo/mongo-keyfile
cp -r /var/server_setup/mongod.conf /etc/mongod.conf
sudo service mongod restart
sleep 5
# sudo service mongod restart
echo "SETTING REPLICA"
sudo mongod --repair --dbpath /var/lib/mongodb
sudo mongod --fork --logpath /var/lib/mongodb/mongodb.log --dbpath /var/lib/mongodb
# mongod --replSet "rs0" --bind_ip_all
mongo --host 127.0.0.1 --port 27017 --eval 'rs.initiate({_id: "rs0", members: [{_id: 0, host: "127.0.0.1:27017"}]})'
echo "REPLICA SET"
sleep 5
# read -p 'Set Mongo Password: ' PASSWORD
export PASSWORD="TBbuaxROrspF8K6ugQJ29s8ZMqc"
mongo --port 27017 <<EOF
use admin;
db.createUser({user: "mongoAdmin", pwd: "$PASSWORD", roles: [ { role: "root", db: "admin" } ]})
EOF
cp -r /var/server_setup/mongod_auth.conf /etc/mongod.conf
After run docker build . command it throws error
first one is mondog:unrecodnised service
and after that
mongo --host local --port 27017 --eval 'rs.initiate({_id: "rs0", members: [{_id: 0, host: "127.0.0.1:27017"}]})':
#15 0.508 MongoDB shell version v4.4.16
#15 0.625 connecting to: mongodb://local:27017/?
compressors=disabled&gssapiServiceName=mongodb
#15 10.66 Error: couldn't connect to server local:27017, connection attempt failed:
HostNotFound: Could not find address for local:27017: SocketException: Host not found
(non-authoritative), try again later :
#15 10.66 connect#src/mongo/shell/mongo.js:374:17
#15 10.66 #(connect):2:6
#15 10.68 exception: connect failed
#15 10.68 exiting with code 1
All other setting has been configured just mongodb not installing properly kindly help and thanks in advance.

Properly escaping quotes when running a command in kubernetes

I want to run a mongodb command in Kubernetes deployment.
In my yaml file, I want to run the following:
command: ["mongo --port ${MONGODBCACHE_PORT} --host ${MONGODBCACHE_BIND_IP} \
--eval "rs.initiate('{ _id: \"test\", members: [ { _id: 0, host: \"${MONGODBCACHE_BIND_IP}:${MONGODBCACHE_BIND_IP}\" },]}')" && \
./mycommand "]
I checked that the environment variables are present correctly. How do I escape the characters when running this command?
Use only mongo in command and the others in args field which is an array. Like,
command: ["/bin/bash", "-c"]
args:
- mongo
- --port
- ${MONGODBCACHE_PORT}
- --host
- ${MONGODBCACHE_BIND_IP}
- --eval
- rs.initiate('{ _id: "test", members: [ { _id: 0, host: "${MONGODBCACHE_BIND_IP}:${MONGODBCACHE_BIND_IP}" } ] }') && ./mycommand
Hope this will help.
got it working with a slightly modified configuration in manifest :
command: ["/bin/bash", "-c"]
args:
- /usr/bin/mysql -u root -p$DB_ROOT_PASS -h $DB_HOST -e "CREATE USER IF NOT EXISTS $DB_USER#'%' IDENTIFIED BY '$DB_PASS';"
Although it's mysql cli client this should work for any other command.
ENV Variables must exists of course.

How to set up Mongo replica set in dockerfile mode

I created a dockerfile file to build the Mongo replica set.It is not a problem to start creating a copy set, but when configuring a copy of Mongo, I don't want to manually go into the Mongo shell default configuration, which is too troublesome, so I automatically execute a script to complete automatic configuration when creating docker, and try a lot of methods, the following my specific way is not running. Work
And run a script The following is my detailed document
dockerfile
FROM mongo:3.4
ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d
COPY ./setup.js /docker-entrypoint-initdb.d/
RUN chmod +x /docker-entrypoint-initdb.d/setup.js
ENTRYPOINT ["/docker-entrypoint-initdb.d/setup.js"]
setup.js
#!/bin/bash
echo "Started.."
mongod --replSet replset0
mongo 127.0.0.1/admin -u test -p test --authenticationDatabase "admin"<<EOF
var cfg = {
"_id": "replset0",
"members": [
{
"_id": 0,
"host": "192.168.1.233:27018"
}
]
};
rs.initiate(cfg, { force: true });
rs.reconfig(cfg, { force: true });
EOF
exec "$#"
After executing the mongod --replSet replset0, mongo Unable to execute.I want to know what you can do. Thank you very much.

Mongodump of docker mongoDB instance to single timestamp named file

I'm doing backup dump of a mongoDb docker instance (mongo_db) via docker-compose (thanks to Matt for that snippet so far):
version: "3"
services:
mongo_db_backup:
image: 'mongo:3.4'
volumes:
- '/backup:/backup'
command: |
mongodump --host mongo_db --out /backup/ --db specific
Executing the command
$ docker-compose run mongo_db_backup
gives me all collections of specific db and stores them in /backup/specific.
Is it possible to get only one single (compressed) dump file, which is named as current time?
I'm using --out to get the files in the folder. The docs are saying I cannot use --archive together with --out.
Further more I need to use a env variable to set the archive output. Something like this:
mongo_db_backup:
image: 'mongo:3.4'
volumes:
- '/backup:/backup'
command:
- sh
- -c
- |
mongodump
--host mongo_db
--gzip
--db specific
$$(
if [ $TYPE = "hour" ]
then echo "--archive=/backup/hour/$$(date +"%H").gz"
elif [ $TYPE = "day" ]
then echo --archive=/backup/day/$$(date +"%d").gz
fi
)
Executing with $ docker-compose run -e TYPE=day mongo_db_backup
You can change your compose to below
version: "3"
services:
mongo_db_backup:
image: 'mongo:3.4'
volumes:
- '/backup:/backup'
command: sh -c "mongodump --host mongo_db --gzip --archive=/backup/$$(date +'%Y%m%d_%H%M%S') --db $${DB:=specific}"
Now if you want to change the DB you can run it like below
docker-compose run -e DB=abc mongo_db_backup
If you want to use it like docker-compose run mongo_db_backup abc then would need to create entrypoint.sh script handle the arguments in that. So it is easier to do it using environment variables
Edit-1 - Default behavior on missing environment variable
If you need to change the command based on environment variable being specified or not, you can change the command to below
command: sh -c "mongodump --host mongo_db --gzip --archive=/backup/$$(date +'%Y%m%d_%H%M%S') $$(if [ -z $DB ]; then echo '--db default_db'; else echo --collection $DB; fi)"
Edit-2: Multiline line command in compose with if else
To solve the issue of using multiline commands in compose you need to use a combination of array and multiline
command:
- sh
- -c
- |
multi line shell script
Below is the command I worked out for your update
command:
- bash
- -c
- |
TYPE=$${TYPE:=day}
if [ ! -d /backup/hour ]; then mkdir /backup/hour; fi
if [ ! -d /backup/day ]; then mkdir /backup/day; fi
mongodump --host mongo_db --gzip \
--db test \
$$( \
if [ "$$TYPE" == "hour" ]; then \
echo "--archive=/backup/hour/$$(date +'%H').gz"; \
elif [ "$$TYPE" == "day" ]; then \
echo "--archive=/backup/day/$$(date +'%d').gz"; \
fi \
)
Since docker-compose processes variables we need to escape each $ using $$. So $TYPE becomes $$TYPE. Also mongodump is a single command, so if you split it into multiple lines you need to use \ for multiline command continuation

Docker mongodb config file

There is a way to link /data/db directory of the container to your localhost. But I can not find anything about configuration. How to link /etc/mongo.conf to anything from my local file system. Or maybe some other approach is used. Please share your experience.
I'm using the mongodb 3.4 official docker image. Since the mongod doesn't read a config file by default, this is how I start the mongod service:
docker run -d --name mongodb-test -p 37017:27017 \
-v /home/sa/data/mongod.conf:/etc/mongod.conf \
-v /home/sa/data/db:/data/db mongo --config /etc/mongod.conf
removing -d will show you the initialization of the container
Using a docker-compose.yml:
version: '3'
services:
mongodb_server:
container_name: mongodb_server
image: mongo:3.4
env_file: './dev.env'
command:
- '--auth'
- '-f'
- '/etc/mongod.conf'
volumes:
- '/home/sa/data/mongod.conf:/etc/mongod.conf'
- '/home/sa/data/db:/data/db'
ports:
- '37017:27017'
then
docker-compose up
When you run docker container using this:
docker run -d -v /var/lib/mongo:/data/db \
-v /home/user/mongo.conf:/etc/mongo.conf -p port:port image_name
/var/lib/mongo is a host's mongo folder.
/data/db is a folder in docker container.
I merely wanted to know the command used to specify a config for mongo through the docker run command.
First you want to specify the volume flag with -v to map a file or directory from the host to the container. So if you had a config file located at /home/ubuntu/ and wanted to place it within the /etc/ folder of the container you would specify it with the following:
-v /home/ubuntu/mongod.conf:/etc/mongod.conf
Then specify the command for mongo to read the config file after the image like so:
mongo -f /etc/mongod.conf
If you put it all together, you'll get something like this:
docker run -d --net="host" --name mongo-host -v /home/ubuntu/mongod.conf:/etc/mongod.conf mongo -f /etc/mongod.conf
For some reason I should use MongoDb with VERSION:3.0.1
Now : 2016-09-13 17:42:06
That is what I found:
#first step: run mongo 3.0.1 without conf
docker run --name testmongo -p 27017:27017 -d mongo:3.0.1
#sec step:
docker exec -it testmongo cat /entrypoint.sh
#!/bin/bash
set -e
if [ "${1:0:1}" = '-' ]; then
set -- mongod "$#"
fi
if [ "$1" = 'mongod' ]; then
chown -R mongodb /data/db
numa='numactl --interleave=all'
if $numa true &> /dev/null; then
set -- $numa "$#"
fi
exec gosu mongodb "$#"
fi
exec "$#"
I find that there are two ways to start a mongod service.
What I try:
docker run --name mongo -d -v your/host/dir:/container/dir mongo:3.0.1 -f /container/dir/mongod.conf
the last -f is the mongod parameter, you can also use --config instead.
make sure the path like your/host/dir exists and the file mongod.conf in it.