6

I'm trying to set up a container running MongoDB that gets populated with data using mongorestore when it starts up. The idea is to quickly set up a dummy database for testing and mocking.

My Dockerfile looks like this:

FROM mongo:bionic
COPY ./db-dump/mydatabase/* /db-dump/

and docker-compose.yml looks like this:

version: "3.1"
  
services:
  mongo:
    build: ./mongo
    command: mongorestore -d mydatabase ./db-dump
    ports:
      - "27017:27017"

If I run this with docker-compose up, it pauses for a while and then I get an error saying:

error connecting to host: could not connect to server: server selection error: server selection timeout, current topology: { Type: Single, Servers: [{ Addr: localhost:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: connection() : dial tcp 127.0.0.1:27017: connect: connection refused }, ] }

Opening a CLI on the container and running the exact same command works without any issues, however. I've tried adding -h with the name of the container or 127.0.0.1, and it doesn't make a difference. Why isn't this command able to connect when it works fine once the container is running?

DrRelling
  • 122
  • 1
  • 4
  • 10
  • 1
    When you pass mongorestore as command in docker compose file, it overrides the default command of the image, so the database will never be started. You should run mongorestore from a different container. https://stackoverflow.com/questions/48178870/import-data-on-mongodb-using-docker-compose/64372237 – sriharip316 Feb 05 '21 at 18:11

1 Answers1

12

There is a better way than overriding the default command - using /docker-entrypoint-initdb.d:

When a container is started for the first time it will execute files with extensions .sh and .js that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. .js files will be executed by mongo using the database specified by the MONGO_INITDB_DATABASE variable, if it is present, or test otherwise. You may also switch databases within the .js script.

[Source]

So you simply write that command into a file named mongorestore.sh:

mongorestore -d mydatabase /db-dump

and then mount it inside along with the dump file:

version: "3.1"
  
services:
  mongo:
    image: mongo:bionic
    ports:
      - "27017:27017"
    volumes:
      - ./mongorestore.sh:/docker-entrypoint-initdb.d/mongorestore.sh
      - ./db-dump:/db-dump

You don't even need a Dockerfile.

anemyte
  • 17,618
  • 1
  • 24
  • 45
  • Thank you, that did it! Only one minor thing, I had to use `mongorestore -d mydatabase ./docker-entrypoint-initdb.d/db-dump` instead for the sh file - it looks like the script was running in the root directory rather than the entrypoint directory. Probably some weird quirk with my setup but adding it here just in case it helps someone else. – DrRelling Feb 08 '21 at 11:45
  • @DrRelling Thanks, I've updated the answer with an absolute path. I used a different path but it should work the same. The problem was because the working directory for these scripts is something different from `/docker-entrypoint-initdb.d`. – anemyte Feb 08 '21 at 12:21