Mongo: No documentation on accessing ENV variables from docker-entrypoint_initdb.d

Created on 23 Mar 2018  路  15Comments  路  Source: docker-library/mongo

As the name said, i couldn't find a way of accessing env variables from docker.
What i need is to access some var that is defined in docker-compose file over here:

let res = [
'use admin',
db.createUser({
user: 'apUser', // it should be this: ENV_APP_SERVER_USERNAME
pwd: '12345',
roles: [
{
role: 'readWrite',
db: 'dummydb'
}
]
})
];

printjson(res);

This is the content of javascript file that gets copied into docker-entrypoint-inidb.d

Most helpful comment

I am quite sure you can just put it in one file and just use bash to insert the variables directly into the js. I don't see this as a necessary addition to the docs.

#!/bin/bash
set -e

mongo <<EOF
use admin
db.createUser({
  user:  '$ENV_APP_SERVER_USERNAME',
  pwd: '$ENV_APP_SERVER_PW',
  roles: [{
    role: 'readWrite',
    db: 'dummydb'
  }]
})
EOF

All 15 comments

There is an open issue on Mongo's Jira about this: https://jira.mongodb.org/browse/SERVER-4895

Thanks for the link @bchrobot

But what is the purpose of defining users in docker-entrypoint_initdb.d if you can't even access the password through env variables?
How else would one securely set passwords?

If you need environment variables, I'd recommend using a .sh initdb file
instead of .js.

ah so with a shell script it is possible. Thanks for the info @tianon Nice! So to convert the JS into a .sh script I would have written:

use admin
db.createUser({
  user:  $ENV_APP_SERVER_USERNAME,
  pwd: $ENV_APP_SERVER_PW,
  roles: [{
    role: 'readWrite',
    db: 'dummydb'
  }]
})

Is that correct? Without the whole printjson thing...

Shell scripts are also executed (/docker-entrypoint-initdb.d/*.sh) so you could access ENV variables there.

From this SO post it seems like something along the following lines would work:

/docker-entrypoint-initdb.d/create_secure_user.sh:

# Executed during Mongo container startup, concatenates scripts to pass ENV var

mongo --eval "var secureUsername = '$ENV_APP_SERVER_USERNAME'" create_user-js

/docker-entrypoint-initdb.d/create_user-js:

// Skipped during Mongo container startup due to lack of .js extension.
// Instead, is executed by above shell script.

let res = [
  'use admin',
  db.createUser({
    user: secureUsername,
    pwd: '12345',
    roles: [
      {
        role: 'readWrite',
        db: 'dummydb'
      }
    ]
  })
];

printjson(res);

@tianon if the above seems like a reasonable approach I will add it as an example for ENV usage in the 'Initializing a fresh instance' section in my docker-docs PR

I am quite sure you can just put it in one file and just use bash to insert the variables directly into the js. I don't see this as a necessary addition to the docs.

#!/bin/bash
set -e

mongo <<EOF
use admin
db.createUser({
  user:  '$ENV_APP_SERVER_USERNAME',
  pwd: '$ENV_APP_SERVER_PW',
  roles: [{
    role: 'readWrite',
    db: 'dummydb'
  }]
})
EOF

Thanks @yosifkit This script works perfectly fine.

Thanks @yosifkit
But may I ask why you don't want to put this in the docs? The fact that we had to open an issue to get this information is proof for me that the info is not easily accessable.

No need for shebang, it's sourced.

No need for shebang, it's sourced.

Thanks @x-yuri to point to this location in the code, that's great information.

For short commands, you could also use a pipe instead of a heredoc to send the commands to mongo's stdin:

~bash
echo "db.createUser({...})" | mongo admin
~

edit: sorry I found the stupid error; I had a typo I did not notice and was importing badly my environment variable, sorry for the trouble! I am going to run it now through the entire CI/CD flow and see if it works.
Sorry @yosifkit I am trying your code snippet, however, it does not work. Has this changed?

I have an initDatabase.sh file with the following content:

#!/bin/bash
set -e

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

I have in my shell the environment variables defined, but if I run the script it does not go ok, the error is:

Error: couldn't add user: User passwords must not be empty

What am I missing?

Thank you very much in advance and regards.

FWIW, here's my answer on Stack Overflow. Although I'd avoid using Docker Swarm (buggy) and secrets (environment variables are easier to use). Also from a cursory glance at docker-entrypoint.sh, it looks like without MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORD authentication is disabled, so no point in creating a user. On the other hand if you do specify the variables, you've got to authenticate first (before creating a user), as I did in my example. Whether it makes sense to create a non-root user if the database is accessed just by one application... I'm not sure.

Thanks @x-yuri Indeed at the end I just placed those variables (INITDB_ROOT_blabla) because as you pointed out, without them, auth is not enabled and I was having issues connecting because of that.

A function named _getEnv was added here. Usage:

_getEnv("MONGO_INITDB_ROOT_USERNAME")
Was this page helpful?
0 / 5 - 0 ratings

Related issues

thomasbeauvais picture thomasbeauvais  路  5Comments

deployable picture deployable  路  3Comments

ltdev22 picture ltdev22  路  4Comments

SimonTulettIdeaco picture SimonTulettIdeaco  路  6Comments

jamesongithub picture jamesongithub  路  6Comments