1

How to read env variable in mongo-init.js? docker-compose.yml able to read from .env file but mongo-init.js can't as mongo-init.js will copy to /docker-entrypoint-initdb.d volume (not sure I'm right or wrong). This mean mongo-init.js will read process.env.MONGODB_USERNAME as undefined.

Is it possible to convert env value in mongo-init.js first before copy to /docker-entrypoint-initdb.d

docker-compose.yml

version: '2'

services:
  mongodb:
    image: mongo:4.4.2
    restart: always
    container_name: local-mongodb
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGODB_ROOT_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGODB_ROOT_PASSWORD}
    ports:
      - ${MONGODB_PORT}:27017
    volumes:
      - mongodb_database:/data/db
      - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js

volumes:
  mongodb_data:

mongo-init.js

require('dotenv').config()

print('mongo init start --------------------');

const pms = db.getSiblingDB(process.env.MONGODB_DATABASE)

pms.createUser({
  user: process.env.MONGODB_USERNAME,
  pwd: process.env.MONGODB_PASSWORD,
  roles: [
    {
      role: 'readWrite',
      db: process.env.MONGODB_DATABASE,
    },
  ],
});

print('mongo init end --------------------');

.env

MONGODB_ROOT_USERNAME=root
MONGODB_ROOT_PASSWORD=password
MONGODB_DATABASE=product
MONGODB_USERNAME=user
MONGODB_PASSWORD=password
MONGODB_PORT=27017

3 Answers 3

1

I believe the best way to achieve what you want in an elegant way is using direnv.

Solution

The proposed solution uses the following files:

  • Dotenv file .env
  • Direnv file .envrc
  • Docker compose file docker-compose.yml
  • Create Mongo init script create_mongo_init.sh
  • Startup script up.sh

Direnv

First of all make sure you have direnv installed.

Docker-compose file

Edit the docker-compose.yml file and make sure it is as follows:

version: '3.7'

services:
    mongo:
        image: mongo:latest
        restart: always
        environment:
            MONGO_INITDB_ROOT_USERNAME: ${DB_USERNAME}
            MONGO_INITDB_ROOT_PASSWORD: ${DB_PASSWORD}
            MONGO_INITDB_DATABASE: ${DB_NAME}
        ports:
            - '27017-27019:27017-27019'
        volumes:
            - mongodb_database:/data/db
            - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro

.env file creation

Create a .env file and enter:

DB_USERNAME=username
DB_PASSWORD=password
DB_NAME=db_name

.envrc file creation

Type in your terminal:

echo dotenv > .envrc

You should see the output as follows:

direnv: error .envrc is blocked. Run `direnv allow` to approve its content.

Loading environment variables

So type in your terminal:

direnv allow .

If your Direnv installtion is alright, it loads the variables and outputs the following:

direnv: loading .envrc                                                                               
direnv: export +DB_NAME +DB_PASSWORD +DB_USERNAME

Mongo init script

Create a file named create_mongo_init.sh with the following:

#!/bin/sh

echo "\
print('mongo init start --------------------'); \n\
\n\
db.createUser( \n\
    { \n\
        user: \"$DB_USERNAME\", \n\
        pwd: \"$DB_PASSWORD\", \n\
        roles: [ \n\
            { \n\
                role: \"readWrite\", \n\
                db: \"$DB_NAME\" \n\
            } \n\
        ] \n\
    } \n\
) \n\
\n\
print('mongo init end ----------------------'); \n\
" > mongo-init.js

Startup script

Create a file named up.sh with the following contents:

#!/bin/sh

./create_mongo_init.sh
docker-compose up -d
rm mongo-init.js # Delete initialization script to avoid credentials leakage.

And the run it by entering:

. ./up.sh
Sign up to request clarification or add additional context in comments.

Comments

0

This will help someone out!

Docker-compose.yml

version: "3.3"
services:
  mongo:
    image: mongo
    restart: always
    ports:
      - 27017:27017
    environment:
      MONGO_INITDB_ROOT_USERNAME: myuser
      MONGO_INITDB_ROOT_PASSWORD: mypass
      MONGO_URI: ${MONGO_URI}
      MONGO_USER: ${MONGO_USER}
      MONGO_PWD: ${MONGO_PWD}
      MONGO_DB_NAME: ${MONGO_DB_NAME}
      MONGO_URI_TEST: ${MONGO_URI_TEST}
      MONGO_USER_TEST: ${MONGO_USER_TEST}
      MONGO_PWD_TEST: ${MONGO_PWD_TEST}
      MONGO_DB_NAME_TEST: ${MONGO_DB_NAME_TEST}
      MONGO_URI_DOCKER: ${MONGO_URI_DOCKER}
      MONGO_USER_DOCKER: ${MONGO_USER_DOCKER}
      MONGO_PWD_DOCKER: ${MONGO_PWD_DOCKER}
      MONGO_DB_NAME_DOCKER: ${MONGO_DB_NAME_DOCKER}
    volumes:
      - ./volume/mongo-data:/data/db
      - ./mongo-init:/docker-entrypoint-initdb.d/:ro
      

mongo-entrypoint.sh

echo '################ MONGO ENTRYPOINT START ################';

mongo -- "$MONGO_INITDB_DATABASE" <<EOF
db = db.getSiblingDB('$MONGO_DB_NAME_DOCKER');
db.createUser(
  {
    user: '$MONGO_USER_DOCKER',
    pwd: '$MONGO_PWD_DOCKER',
    roles: [{ role: 'readWrite', db: '$MONGO_DB_NAME_DOCKER' }],
  },
);
db.createCollection('users');

db = db.getSiblingDB('$MONGO_DB_NAME');
db.createUser(
  {
    user: '$MONGO_USER',
    pwd: '$MONGO_PWD',
    roles: [{ role: 'readWrite', db: '$MONGO_DB_NAME' }],
  },
);
db.createCollection('users');

db = db.getSiblingDB('$MONGO_DB_NAME_TEST');
db.createUser(
  {
    user: '$MONGO_USER_TEST',
    pwd: '$MONGO_PWD_TEST',
    roles: [{ role: 'readWrite', db: '$MONGO_DB_NAME_TEST' },{ role: 'dbAdmin', db: '$MONGO_DB_NAME_TEST' }],
  },
);
db.createCollection('users');
EOF

echo '################ MONGO ENTRYPOINT END ################';

.env

MONGO_URI="mongodb://localhost:27017/vinsys_db_dev"
MONGO_USER='fancyuser'
MONGO_PWD='fancypass'
MONGO_DB_NAME='vinsys_db_dev'

MONGO_URI_TEST="mongodb://localhost:27017/vinsys_db_test"
MONGO_USER_TEST='fancyuser'
MONGO_PWD_TEST='fancypass'
MONGO_DB_NAME_TEST='vinsys_db_test'

MONGO_URI_DOCKER="mongodb://mongo:27017/vinsys_db_prod"
MONGO_USER_DOCKER='fancyuser'
MONGO_PWD_DOCKER='fancypass'
MONGO_DB_NAME_DOCKER='vinsys_db_prod'

Comments

-1

The following code worked in mongo:6.0.4 docker image.

mongo-init.js

db.auth(process.env["MONGO_INITDB_ROOT_USERNAME"], process.env["MONGO_INITDB_ROOT_PASSWORD"])

db = db.getSiblingDB(process.env["MONGO_INITDB_DATABASE"])

db.createUser({
  user: process.env["MONGODB_USERNAME"],
  pwd: process.env["MONGODB_PASSWORD"],
  roles: [
    {
      role: 'readWrite',
      db: process.env["MONGODB_DATABASE"],
    },
  ],
});

.env file

MONGO_INITDB_ROOT_USERNAME=root
MONGO_INITDB_ROOT_PASSWORD=1qaz2WSX
MONGO_INITDB_DATABASE=admin
MONGODB_USERNAME=user
MONGODB_PASSWORD=password
MONGODB_DATABASE=rr-platform

docker-compose.yml

version: '3.8'

services:
  mongodb:
    image: mongo:6.0.4
    restart: unless-stopped
    env_file: .env
    ports:
      - '27017:27017'
    volumes:
      - ./.data/mongo:/data/db
      - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.