Data isn't persisted in the database when using MongoDB with Docker volumes?

Viewed 1297

There is a service that uses mongodb. But when I restart computer or docker machine, no data is stored in the database. docker-compose.yml:

version: "3"
Services:
...
  mongodb:
    restart: always
    image: mongo:latest
    environment:
      - MONGO_DATA_DIR=/dockerdata/db
    volumes:
        - ./dockerdata/db:/data/db
    ports:
      - 27017:27017
    command: mongod

I tried to do database storage on the host, but it didn't help either:

docker-compose.yml:

version: "3"
Services:
...
  mongodb:
    restart: always
    image: mongo:latest
    environment:
      - MONGO_DATA_DIR=/c/users/frol/mongodata/db
    volumes:
        - /c/users/frol/mongodata/db:/data/db
    ports:
      - 27017:27017
    command: mongod

If you make a named volume, docker writes an error: ERROR: for test_mongodb_1 Cannot create container for service mongodb: fa To mount local volume: mount /c/users/frol/mongodata/db:/mnt/sda1/var/lib/d ocker/volumes/test_mongodata/_data, flags: 0x1000: no such file or directory

docker-compose.yml:

version: "3"
services:
...
  mongodb:
    restart: always
    image: mongo:latest
    environment:
      - MONGO_DATA_DIR=/c/users/frol/mongodata/db
    volumes:
        - mongodata:/data/db
    ports:
      - 27017:27017
    command: mongod 
volumes:
  mongodata:
    driver: local
    driver_opts:
      type: none
      device: /c/users/frol/mongodata/db
      o: bind

Host - win 8.1, docker toolbox 19.03.1 installed.
Help me, please, I'm a novice. How do I make sure that the database data isn't lost?

3 Answers

You first attempt would work if you just fix a simple typo in your compose file:

version: "3"
services:
...
  mongodb:
    restart: always
    image: mongo:latest
    environment:
      - MONGO_DATA_DIR=/data/db  # changed
    volumes:
        - ./dockerdata/db:/data/db
    ports:
      - 27017:27017
    command: mongod

But, since /data/db is the default value of MONGO_DATA_DIR, setting it is pretty redundant.


But I'd prefer to use a named volume, that way the data persists but I don't have to see the "ugly" database storage folder:

version: "3"
services:
...
  mongodb:
    restart: always
    image: mongo:latest
    volumes:
        - mongodata:/data/db
    ports:
      - 27017:27017
    command: mongod 
volumes:
  mongodata:

Don't set $MONGO_DATA_DIR; leave it at its default of /data/db.

services:
  mongodb:
    restart: always
    image: mongo:latest
    # No need to specifically set $MONGO_DATA_DIR
    volumes:
      - ./dockerdata/db:/data/db
    ports:
      - 27017:27017
    # No need to override command:

Docker containers have a separate filesystem space from the host filesystem. A typical setup for most databases is to have the database storage in a fixed location inside the container; for MongoDB that's the /data/db directory. You can mount a named volume or filesystem path there, but the code inside the container doesn't know the difference.

If you do set environment variables like $MONGO_DATA_DIR, they need to reflect paths inside the container; they can't directly specify host-system paths. (@ruohola's answer works because it changes the container-filesystem path of the bind mount to match the container-filesystem path in the environment variable; the host ./dockerdata and container /dockerdata paths are totally unrelated.)

As you are defining the data dir explicitly, you need to map the same directory in the volume to persist the data

version: "3"
services:
...
  mongodb:
    restart: always
    image: mongo:latest
    environment:
      - MONGO_DATA_DIR=/data/db #data directory
    volumes:
        - ./dockerdata/db:/data/db #same data directory which you defined above
    ports:
      - 27017:27017
    command: mongod
Related