Astrydax
Astrydax

Reputation: 465

MongoDB wipes whenever host does is down

I have a web api on a Digital Ocean Droplet. They recently did maintenance on the cluster my api is on. Afterwards, my Database is emptied of all data. This is the second time this has happened as a result of servers going down. Checking the file structure, I noticed there seems to be duplicate data, nested one level deeper.enter image description here

I have a feeling this block from docker compose might be the culprit.

mongo:
image: mongo:3.6
ports:
  - 27017:27017
volumes:
  - ./data/mongo:/data/db
networks:
  - my-api

What steps can I take to fix this issue?

Upvotes: 1

Views: 197

Answers (1)

Mani
Mani

Reputation: 5648

You have defined the bind mount(volume) in relative path which is discouraged.

./data/mongo:/data/db

As mentioned by creack in github there is no warranty that the data always resides under such path.

How? let us assume that the actual path to the compose file is /absolute/path/to/docker-compose.yml. I change directory to /absolute/path/to/data/mongo and execute docker-compose -f ../../docker-compose.yml up -d. In such case my pwd ==> /absolute/path/to/data/mongo becomes . and docker creates data/mongo as such folder is not available in this location. This is what has happened in your case.

Here : is the separator to separate Host path and docker path. eg: /host/path:/docker/path. Here the directory /host/path that you have mentioned on Left side is binded as the path inside Docker on right side i.e /docker/path. The host path and docker path doesn't need to created already. In such cases, docker creates those at both locations.

You can even mount the volume as read only, in such cases another : is used at the end and ro is used to mark it as read-only. /host/path:/docker/path:ro. Here the docker container can only read files at /docker/path (indirectly /host/path) and cannot write anything at the location.

Apart from mounting Host directories, you can also mount data volumes the same way.
There are other types of volumes available as well you can check the reference to understand some of them. Apart from these you also have plugins which allow mounting with advanced features like mounting google drive,NFS,...

I recommend you to read this in order to understand more complex ways of specifying volumes in docker-compose.

You are always encouraged to give Absolute path as it guarantees the location.

Bonus

You can also add restart:always to your compose as this is a DB and it needs to be up always. Refer this for other restart-policy options.

Solution:

So, your docker compose file should be

mongo:
image: mongo:3.6
ports:
  - 27017:27017
restart:unless-stopped
volumes:
  - /absolute/path/to/data/mongo:/data/db
networks:
  - my-api

Note: Adding restart-policy also brings up the container if the system goes to reboot when the container is running. There is a reason why I didn't use restart:always. I encourage you to find it by yourself.

References:

  1. Use volumes.
  2. Use bind mounts
  3. volumes.
  4. Manage data in Docker.
  5. Understanding Volumes in Docker.

Upvotes: 2

Related Questions