Home > Mobile >  Running docker-entrypoint-initdb.d file is not working in docker-compose MongoDB
Running docker-entrypoint-initdb.d file is not working in docker-compose MongoDB

Time:05-04

I have a docker-compose that looks like this:

  stock-trading-system-db:
    container_name: stock-trading-system-db
    image: mongo
    restart: always
    ports:
      - "27017:27017"
    environment:
      - MONGO_INITDB_DATABASE=stock-trading-system-db
    volumes:
    - ./mongo-seed/import.js:/docker-entrypoint-initdb.d/import.js
    - ./mongo-seed/mongod.conf:/etc/mongod.conf
    - ./mongo/data:/data/db
    - ./mongo-seed/MOCK_DATA.csv:/mongo-seed/MOCK_DATA.csv

and import.js looks like this:

let exec = require('child_process').exec
let command1 = 'mongod --config /etc/mongod.conf'
let command2 = 'mongo --eval "rs.initiate();"'
let command3 = 'mongoimport --host=mongo1 --db=stock-trading-system-db --collection=stocks --type=csv --headerline --file=/mongo-seed/MOCK_DATA.csv'
exec(command1, (err, stdout, stderr) => {
  // check for errors or if it was succesfuly
  if(!err){
    exec(command2, (err, stdout, stderr) => {
        // check for errors or if it was succesfuly
        if(!err){
            exec(command3, (err, stdout, stderr) => {
                // check for errors or if it was succesfuly
                if(!err){
                    console.log('MongoDB seed was succesful');
                }
              })
        }
      })
  }
})

But it doesn't seem like import.js even gets recognised by the container.

The mongo docs say the following:

This variable allows you to specify the name of a database to be used for creation scripts in /docker-entrypoint-initdb.d/*.js (see Initializing a fresh instance below). MongoDB is fundamentally designed for "create on first use", so if you do not insert data with your JavaScript files, then no database is created.

This is in relation to the MONGO_INITDB_DATABASE variable in the docker-compose file, which i have included.

Where am i going wrong?

p.s. This is all to try and get a single node replica set working in a mongo container so that I can use change streams in my node app, so if you know an easier way to do this whilst also importing a csv file into the DB then please mention it :)

CodePudding user response:

First, you shouldn't be trying to start mongod in your init script; the image already does this for you. When you run your first command:

mongod --config /etc/mongod.conf

That's it. That command doesn't exit, and nothing progresses beyond that point, so your additional commands will not execute nor will the normal container startup process complete.

So don't do that.

Next, if you want to run rs.initiate() (or any other javascript command) as part of the startup process, you don't need to wrap it in a call to mongo --eval. Just drop in a .js file that contains:

rs.initiate()

And if you're just going to run a shell command, it's probably easiest just to drop that in a .sh file.

I would replace your import.js script with two seperate files. In rs-initiate.js, I would have the call to rs.initiate(), as above, and in import.sh I would have your call to mongoimport...

#!/bin/sh

mongoimport \
    --db=stock-trading-system-db \
    --collection=stocks \
    --type=csv \
    --headerline \
    --file=/mongo-seed/MOCK_DATA.csv

...so that the docker-compose.yaml would look like:

version: "3"

services:
  mongo:
    image: docker.io/mongo:latest
    ports:
      - "27017:27017"
    environment:
      - MONGO_INITDB_DATABASE=stock-trading-system-db
    volumes:
      - ./mongo-seed/import.sh:/docker-entrypoint-initdb.d/import.sh
      - ./mongo-seed/rs-initiate.js:/docker-entrypoint-initdb.d/rs-initiate.js
      - ./mongo-seed/MOCK_DATA.csv:/mongo-seed/MOCK_DATA.csv
      - ./mongo-seed/mongod.conf:/etc/mongod.conf
      - mongo_data:/data/db


volumes:
  mongo_data:

I'm using a named volume for the mongo data directory here, rather than a bind mount, but that's not necessary; everything will work fine with the bind mount as long as you have permissions configured correctly.

CodePudding user response:

When using bind mounts, the file or directory is referenced by its absolute path on the host machine (see Docker docs).

So you should rather use:

 volumes:
    - ${PWD}/mongo-seed/import.js:/docker-entrypoint-initdb.d/import.js
    - ...
  • Related