简体   繁体   中英

How can I pass environment variables to mongo docker-entrypoint-initdb.d?

I am trying to do the following tutorial: https://itnext.io/docker-mongodb-authentication-kubernetes-node-js-75ff995151b6

However, in there, they use raw values for the mongo init.js file that is placed within docker-entrypoint-initdb.d folder.

I would like to use environment variables that come from my CI/CD system (Gitlab). Does anyone know how to pass environment variables to the init.js file? I have tried several things like for example use init.sh instead for the shell but without any success.

If I run manually the init shell version, I can have it working because I call mongo with --eval and pass the values, however, the docker-entrypoint-blabla is called automatically, so I do not have control of how this is called and I do not know what I could do for achieving what I want.

Thank you in advance and regards.

you can make use of a shell script to retrieve env variables and create the user.

initdb.d/init-mongo.sh

set -e

mongo <<EOF
use $MONGO_INITDB_DATABASE

db.createUser({
  user: '$MONGO_INITDB_USER',
  pwd: '$MONGO_INITDB_PWD',
  roles: [{
    role: 'readWrite',
    db: '$MONGO_INITDB_DATABASE'
  }]
})
EOF

docker-compose.yml

version: "3.7"

services:
  mongodb:
    container_name: "mongodb"
    image: mongo:4.4
    hostname: mongodb
    restart: always
    volumes:
      - ./data/mongodb/mongod.conf:/etc/mongod.conf
      - ./data/mongodb/initdb.d/:/docker-entrypoint-initdb.d/
      - ./data/mongodb/data/db/:/data/db/
    environment:
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=root
      - MONGO_INITDB_DATABASE=development
      - MONGO_INITDB_USER=mongodb
      - MONGO_INITDB_PWD=mongodb
    ports:
      - 27017:27017
    command: [ "-f", "/etc/mongod.conf" ]

Now you can connect to development database using mongodb as user and password credentials.

Use shell script (eg mongo-init.sh ) to access variables. Can still run JavaScript code inside as below.

set -e

mongo <<EOF
use admin

db.createUser({
  user: '$MONGO_ADMIN_USER',
  pwd:  '$MONGO_ADMIN_PASSWORD',
  roles: [{
    role: 'readWrite',
    db: 'dummydb'
  }]
})
EOF

Shebang line is not necessary at the beginning as this file will be sourced.

You can use envsubs . If command not found : here . Install it on your runners host if you use shell runners, else, within the docker image used by the runner, or directly in your script.

(NB: Your link isn't free, so I can't adapt to your situation :p )

Example:

init.js.template :

console.log('$GREET $PEOPLE $PUNCTUATION')
console.log('Pipeline from $CI_COMMIT_BRANCH')

gitlab_ci.yml :

variables:
  GREET: "hello"
  PEOPLE: "world"
  PUNCTUATION: "!"
# ...
script:
  - (envsubst < path/to/init.js.template) > path/to/init.js
  - cat path/to/init.js

Output:

$ (envsubst < init.js.template) > init.js
$ cat init.js
console.log('hello world !')
console.log('Pipeline from master')

At the end the answer is that you can use a .sh file instead of a .js file within the docker-entrypoint-initdb.d folder. Within the sh script, you can use directly environment variables. However, I could not do that at the beginning because I had a typo and environment variables were not created properly.

I prefer this method because it allows you to keep a normal .js file which you lint instead of embedding the .js file into a string.

Create a dockerfile like so:

FROM mongo:5.0.9

USER mongodb
WORKDIR /docker-entrypoint-initdb.d
COPY env_init_mongo.sh env_init_mongo.sh

WORKDIR /writing
COPY mongo_init.js mongo_init.js

WORKDIR /db/data

At the top of your mongo_init.js file, you can just define variables you need

db_name = DB_NAME
schema_version = SCHEMA_VERSION

and then in your env_init_mongo.sh file, you can just replace the strings you need with environment variables or add lines to the top of the file:

mongo_init="/writing/mongo_init.js"
sed "s/SCHEMA_VERSION/$SCHEMA_VERSION/g" -i $mongo_init
sed "s/DB_NAME/${MONGO_INITDB_DATABASE}/g" -i $mongo_init
sed "1s/^/use ${MONGO_INITDB_DATABASE}\n/" -i $mongo_init # add to top of file
mongo < $mongo_init

Until recently, I simply used a .sh shell script in the docker-entrypoint-initdb.d directory to access ENV variables, much like @Lazaro answer.

It is now possible to access environment variables from javascript files using process.env , provided the file is run with the newer mongosh instead of mongo , which is now deprecated.

However, according to the Docs (see 'Initializing a fresh instance'), mongosh is only used for .js files in docker-entrypoint-initdb.d if using version 6 or greater. I can confirm this is working using the mongo:6 image tag.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM