0

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!

Prakhar Patidar
  • 124
  • 1
  • 8

1 Answers1

0

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:

  1. 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

  2. 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
grapes
  • 8,185
  • 1
  • 19
  • 31
  • Thanks @grapes for the quick suggestions. I am using docker-compose up & down so it will remove container also so first option won't be a good solution here. I am following the approach mentioned in second point. I have created /data/db2 folder and configure mongo to save data in /data/db2 but also I have mounted the same directory with my folder system to persist the data changes. That works too. But when again compose up up is fired it removed all the data saved in ${LOCAL_DIRECTORY}. So all the run time data is gone. – Prakhar Patidar Dec 19 '18 at 07:09
  • VOLUME /data/db2 So this command in docker file removes all the previously stored mounted data? Shouldn't be right? – Prakhar Patidar Sep 22 '19 at 20:02