Thursday, January 16, 2014

MongoDB with an External Volume - Docker

I am still playing with different features of Docker and today was "External Volumes".  I thought I'd just try it with MongoDB.  So, lets get started.

1.  Check out the Dockerfile that I am using to do the MongoDB build:

FROM fedora

RUN yum -y update
RUN yum -y install mongodb-server
RUN mkdir -p /data/db
RUN sed -i 's/dbpath =\/var\/lib\/mongodb/dbpath =\/data\/db/' /etc/mongodb.conf

VOLUME ["/data/db"]

EXPOSE 27017
ENTRYPOINT ["/usr/bin/mongod"]

The are two important entries here.  The first is the RUN command that calls sed to make a change to the /etc/mongodb.conf file.  I need to tell it to store it's data in /data/db instead of the default location.  The other important entry is the VOLUME entry.  This tells the container to make the /data/db directory available.

2. Build the image.

# docker build -rm -t scollier/mongodb .

3. Confirm the image was successfully built

# docker images

4. Check the filesystem to make sure there is no data in the host machine's /data/db directory.

# ls -l /data/db/.

4. Now launch the container.

# docker run -p 27017:27017 -v /data/db:/data/db mongo/mongodb
/usr/bin/mongod --help for help and startup options
Wed Jan 15 21:13:23.566 [initandlisten] MongoDB starting : pid=1 port=27017 dbpath=/data/db/ 64-bit host=7492eff49ee2
Wed Jan 15 21:13:23.569 [initandlisten] db version v2.4.6
Wed Jan 15 21:13:23.569 [initandlisten] git version: nogitversion
Wed Jan 15 21:13:23.569 [initandlisten] build info: Linux 3.10.9-200.fc19.x86_64 #1 SMP Wed Aug 21 19:27:58 UTC 2013 x86_64 BOOST_LIB_VERSION=1_54
Wed Jan 15 21:13:23.569 [initandlisten] allocator: tcmalloc
Wed Jan 15 21:13:23.570 [initandlisten] options: {}
Wed Jan 15 21:13:23.605 [initandlisten] journal dir=/data/db/journal
Wed Jan 15 21:13:23.606 [initandlisten] recover : no journal files present, no recovery needed
Wed Jan 15 21:13:23.685 [initandlisten] waiting for connections on port 27017
Wed Jan 15 21:13:23.685 [websvr] admin web console waiting for connections on port 28017

I launched this one and didn't put it into "daemon" mode.  The reason why is I want to watch the logs and make sure the correct data directory is getting called and that  I can tell when the MongoDB server is ready to accept connections.

5. Now check and see if the /data/db directory has any content.

# ls /data/db/
dockerdb.0 dockerdb.1 dockerdb.ns journal local.0 local.ns mongod.lock

And it does.  This is good!

6. Lets make sure that data is persistent. So we'll access the database and insert some data, stop the container and then start another container and see if it can access the data.  I used examples from here for MongoDB data insertion.

# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7492eff49ee2 mongo/mongodb:latest /usr/bin/mongod 4 minutes ago Up 4 minutes>27017/tcp trusting_mccarthy

Get the IP address of the container -

# docker inspect 7492eff49ee2 | grep -i ipaddr "IPAddress":

Log into the MongoDB server and insert some data, then exit-

# mongo --host
MongoDB shell version: 2.4.6
connecting to:

> show dbs;
dockerdb 0.203125GB
local 0.078125GB
> use dockerdb
switched to db dockerdb
> db.bios.insert(
... {
...   _id: 1,
...   name: { first: 'John', last: 'Backus' },
...   birth: new Date('Dec 03, 1924'),
...   death: new Date('Mar 17, 2007'),
...   contribs: [ 'Fortran', 'ALGOL', 'Backus-Naur Form', 'FP' ],
...   awards: [
...                  {
...                     award: 'W.W. McDowell Award',
...                     year: 1967,
...                     by: 'IEEE Computer Society'
...                  },
...                  {
...                     award: 'National Medal of Science',
...                     year: 1975,
...                     by: 'National Science Foundation'
...                  },
...                  {
...                    award: 'Turing Award',
...                    year: 1977,
...                    by: 'ACM'
...                 },
...                 {
...                    award: 'Draper Prize',
...                    year: 1993,
...                    by: 'National Academy of Engineering'
...                 }
...             ]
...        }
... )

Stop the container -

Either hit CTRL-C on the running container or use docker stop CONTAINER ID to stop it.

Run the container again and make sure the dockerdb database is still there.

# docker run -p 27017:27017 -v /data/db:/data/db mongo/mongodb

# docker ps

# docker inspect a7df912dc83c | grep -i ipaddr

# mongo --host
> use dockerdb;
> show collections;

That's it!  Now you've moved the MongoDB to an external volume.

No comments:

Post a Comment