Let’s say I have the following docker compose that consists of 2 services: a nodeJS app and a mongoDB database that is backing it:
version: "3.8"
services:
mongodb-local:
image: mongo:latest
restart: unless-stopped
env_file: ./.env
# see: https://stackoverflow.com/questions/52373098/disable-default-authentication-in-mongo-docker
# environment:
# - MONGO_INITDB_ROOT_USERNAME=$MONGODB_USER
# - MONGO_INITDB_ROOT_PASSWORD=$MONGODB_PASSWORD
# - MONGO_INITDB_DATABASE=$MONGODB_DATABASE
ports:
- "27017:27017"
volumes:
- db:/data/db
app:
depends_on:
- mongodb-local
build: .
restart: unless-stopped
env_file: ./.env
ports:
- 3000:3000
environment:
- DB_HOST=mongodb
- DB_USER=$MONGODB_USER
- DB_PASSWORD=$MONGODB_PASSWORD
- DB_NAME=$MONGODB_DATABASE
- DB_PORT=$MONGODB_DOCKER_PORT
stdin_open: true
tty: true
Let’s say that the nodeJS code uses mongoose to kind of bootsrap all the schemas and models, in such a way that once the nodeJS app starts, I can hit specific endpoints to register users, add some data, etc.
What I want to do now is to be able to "seed" the DB in such a way that I create users and/or add data "upon start up" so that when doing: docker-compose up
I will get a "seeded" DB with the app ready to use for local develpment.
Now it’s a 2 step process:
- run docker-compose up to spin up both services
- Run curl commands via postman against the nodeJS app to seed the DB by making mongoose "work".
What I want is a mechanism to "seed" the DB with a few test data upon doing a docker-compose up immediately.
I tried using the curl image like so:
version: "3.8"
services:
mongodb-local:
image: mongo:latest
restart: unless-stopped
env_file: ./.env
# see: https://stackoverflow.com/questions/52373098/disable-default-authentication-in-mongo-docker
# environment:
# - MONGO_INITDB_ROOT_USERNAME=$MONGODB_USER
# - MONGO_INITDB_ROOT_PASSWORD=$MONGODB_PASSWORD
# - MONGO_INITDB_DATABASE=$MONGODB_DATABASE
ports:
- "27017:27017"
volumes:
- db:/data/db
app:
depends_on:
- mongodb-local
build: .
restart: unless-stopped
env_file: ./.env
ports:
- 3000:3000
environment:
- DB_HOST=mongodb
- DB_USER=$MONGODB_USER
- DB_PASSWORD=$MONGODB_PASSWORD
- DB_NAME=$MONGODB_DATABASE
- DB_PORT=$MONGODB_DOCKER_PORT
stdin_open: true
tty: true
curl-run:
depends_on:
- mongodb-local
- app
image: curlimages/curl
command: "sleep 20 && curl --location --request POST 'http://localhost:3000/register'
--header 'Content-Type: application/json'
--data-raw '{
'username': 'user',
'password': 'pass',
'role': 'admin'
}'"
volumes:
db:
but, no luck… Any pointers would be greatly appreciated.
I have read about mongodump
and restore
but didn’t manage to get that working.
Note that if there is an approach to do it directly via a volume or directly against the DB container that would be the best!
Thanks in advance!
2
Answers
I managed to fix this by leveraging a tweak on the mongo image entrypoint:
/docker-entrypoint-initdb.d
Essentially, I copy an init file, in Javascript, that gets copied over into the container entrypoint via the volume configuration and that gets executed on startup, which allows me to achieve what I want: seed the DB with data upon startup!
Here's my modified docker service for mongoDB:
And, here's my actual "seed" file:
Have you tried using
/docker-entrypoint-initdb.d
?From the documentation:
The only caveat I see here is that this likely only works on a fresh build (
docker-compose up -b
) vs. every time it is started. If you don’t care about preserving the data between ups/downs, this should work.