I want to create a Docker image that starts a mongo server and automatically restores from a previous mongodump
on startup.
Here is my Dockerfile for
This is an old question and the solution above could still work but in later versions, you can add .sh and .js scripts in /docker-entrypoint-initdb.d/
, which will be executed in case the instance is first loading (/data/db
is empty).
Now, Dockerfile could look something like:
FROM mongo
COPY ./data-dump/ /tmp/dump/mydb/
COPY ./import_data.sh /docker-entrypoint-initdb.d/import_data.sh
CMD chmod 777 /docker-entrypoint-initdb.d/import_data.sh #this is probably too permissive
With that, whatever is in import_data.sh
will be run (or whatever other file(s) you have there) first time the container is started.
# change the mongorestore command to match your case, adding user/password and other options.
mongorestore /tmp/dump # note we can possibly restore many DBs.
It is documented here under Initializing a fresh instance section
With help from this answer, Marc Young's answer, and the Dockerfile reference I was able to get this working.
Dockerfile
FROM mongo
COPY dump /home/dump
COPY mongo.sh /home/mongo.sh
RUN chmod 777 /home/mongo.sh
CMD /home/mongo.sh
mongo.sh
#!/bin/bash
# Initialize a mongo data folder and logfile
mkdir -p /data/db
touch /var/log/mongodb.log
chmod 777 /var/log/mongodb.log
# Start mongodb with logging
# --logpath Without this mongod will output all log information to the standard output.
# --logappend Ensure mongod appends new entries to the end of the logfile. We create it first so that the below tail always finds something
/entrypoint.sh mongod --logpath /var/log/mongodb.log --logappend &
# Wait until mongo logs that it's ready (or timeout after 60s)
COUNTER=0
grep -q 'waiting for connections on port' /var/log/mongodb.log
while [[ $? -ne 0 && $COUNTER -lt 60 ]] ; do
sleep 2
let COUNTER+=2
echo "Waiting for mongo to initialize... ($COUNTER seconds so far)"
grep -q 'waiting for connections on port' /var/log/mongodb.log
done
# Restore from dump
mongorestore --drop /home/dump
# Keep container running
tail -f /dev/null
A similar solution to RyanNHG's, but without an sh file.
Dockerfile
FROM mongo:3.6.8
COPY dump/ /tmp/dump/
CMD mongod --fork --logpath /var/log/mongodb.log; \
mongorestore /tmp/dump/; \
mongod --shutdown; \
docker-entrypoint.sh mongod
You probably don't want to use this for production but it does what you need:
== Dockerfile ==
FROM mongo:3
COPY restore.sh /restore.sh
COPY ./mongodump /dump/
ENTRYPOINT /restore.sh
then
== restore.sh ==
#!/usr/bin/env bash
# Execute restore in the background after 5s
# https://docs.docker.com/engine/reference/run/#detached--d
sleep 5 && mongorestore /dump &
# Keep mongod in the foreground, otherwise the container will stop
docker-entrypoint.sh mongod
the problem isn't with docker.
If you look at the dockerfile for mongo it runs CMD ["mongod"]
which starts the mongo service.
You said FROM MONGO
but you overwrote the CMD
line. this means mongo never started via mongod
. so try CMD mongod; mongorestore /home/dump