Reputation: 1183
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.
Upvotes: 12
Views: 20603
Reputation: 1
I dont't know, is it needs yet, but I find the solution for docker-compose with mongo-init.js.
My docker-compose.yml:
services:
mongo-0:
image: mongo:7.0.16
...
environment:
...
- CUSTOM_USER_DB_USERNAME=local_user
- CUSTOM_USER_DB_PASSWORD=local_password
volumes:
...
- E://GIT/Mongo/scripts/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
And my mongo-init.js:
let dbName = 'aaa';
db = db.getSiblingDB(dbName);
const userCreationResult = db.createUser({
user: process.env.CUSTOM_USER_DB_USERNAME,
pwd: process.env.CUSTOM_USER_DB_PASSWORD,
roles: [
{ role: 'readWrite', db: dbName }
]
});
Upvotes: 0
Reputation: 111
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.
Upvotes: 2
Reputation: 518
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
Upvotes: 0
Reputation: 1932
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.
Upvotes: 20
Reputation: 352
Use shell script (e.g 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.
Upvotes: 1
Reputation: 1183
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.
Upvotes: 0
Reputation: 429
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 )
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')
Upvotes: 0