Created
June 10, 2019 11:07
-
-
Save zhangyoufu/d1d43ac0fa268cda4dd2dfe55a8c834e to your computer and use it in GitHub Desktop.
ugly hack to initialize replica set for MongoDB docker container, put under /docker-entrypoint-initdb.d/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
: "${FORKED:=}" | |
if [ -z "${FORKED}" ]; then | |
echo >&2 'mongod for initdb is going to shutdown' | |
mongod --pidfilepath /tmp/docker-entrypoint-temp-mongod.pid --shutdown | |
echo >&2 'replica set will be initialized later' | |
FORKED=1 "${BASH_SOURCE[0]}" & | |
unset FORKED | |
mongodHackedArgs=(:) # bypass mongod --shutdown in docker-entrypoint.sh | |
return | |
fi | |
# FIXME: assume mongod listens on 127.0.0.1:27017 | |
mongo=( mongo --host 127.0.0.1 --port 27017 --quiet ) | |
tries=30 | |
while true; do | |
sleep 1 | |
if "${mongo[@]}" --eval 'quit(0)' &> /dev/null; then | |
# success! | |
break | |
fi | |
(( tries-- )) | |
if [ "$tries" -le 0 ]; then | |
echo >&2 | |
echo >&2 'error: unable to initialize replica set' | |
echo >&2 | |
kill -STOP 1 # initdb won't be executed twice, so fail loudly | |
exit 1 | |
fi | |
done | |
echo 'about to initialize replica set' | |
# FIXME: hard-coded replica set name & member host | |
"${mongo[@]}" <<-EOF | |
rs.initiate({ | |
_id: "rs0", | |
version: 1, | |
members: [ | |
{ _id: 0, host : "mongo" }, | |
] | |
}); | |
EOF |
I had similar issues, and found this gist from here: docker-library/mongo#339
Additionally I wanted mongo to run on a different port. Here was my final setup:
mongo.dockerfile
FROM mongo:4.4.10
COPY keyfile.pem /data/keyfile.pem
RUN mkdir -p /data/logs && chmod 777 -R /data/logs
RUN chmod 400 /data/keyfile.pem
RUN chown 999:999 /data/keyfile.pem
RUN apt-get update && apt-get install netcat -y
COPY init.sh /docker-entrypoint-initdb.d/init.sh
init.sh
#!/bin/bash
# https://gist.github.com/zhangyoufu/d1d43ac0fa268cda4dd2dfe55a8c834e
{
while ! nc -z localhost $MONGO_PORT; do
sleep 0.1 # wait for 1/10 of the second before check again
done &&
mongo --port $MONGO_PORT -- "$MONGO_INITDB_DATABASE" 2>&1 > /data/logs/mongo-init.log <<-EOJS
var rootUser = '$MONGO_INITDB_ROOT_USERNAME';
var rootPassword = '$MONGO_INITDB_ROOT_PASSWORD';
var admin = db.getSiblingDB('admin');
admin.auth(rootUser, rootPassword);
EOJS && sleep 3 &&
mongo --port $MONGO_PORT -- "$MONGO_INITDB_DATABASE" 2>&1 > /data/logs/mongo-rs-init.log <<-EOJS
var rootUser = '$MONGO_INITDB_ROOT_USERNAME';
var rootPassword = '$MONGO_INITDB_ROOT_PASSWORD';
var admin = db.getSiblingDB('admin');
admin.auth(rootUser, rootPassword);
rs.initiate({_id: 'rs0', members: [{_id: 0, host: "localhost:$MONGO_PORT"}]})
EOJS
} &
version: '3.8'
services:
mongodb-primary:
build:
dockerfile: mongo.dockerfile
context: ./docker/mongo/
ports:
- 27027:27027
restart: always
command: --keyFile /data/keyfile.pem --replSet rs0 --port 27027
environment:
- MONGO_PORT=27027
- MONGO_INITDB_ROOT_USERNAME=blah
- MONGO_INITDB_ROOT_PASSWORD=blah
volumes:
- mongo_test:/data/db
and I generated the keyfile with
openssl rand -base64 756 > .docker/mongo/keyfile.pem
Make sure you delete volumes when you recreate your mongo docker image, because the config persists with the db (i think). I'm still pretty new to mongo, so this bit me pretty hard.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If anyone stumbles upon this script it may be helpful to see an even simpler, uglier version, that adds admin/user configuration too: