First off, this became a much longer post than I expected, tl;dr; How can I make my config DRY with docker (I'm assuming with env variables)
I am developing a node.js server with a mongodb database and I am switching over to docker to (hopefully) simplify my environment and keep it consistant for my server. Let me start out by saying that I definitely do not understand the entire docker-container life cycle, but I am learning as I go. I cannot find a solution to what I am trying to do after a lot of searching. I am using Docker for Windows with Hyper-V. (docker version
at the bottom)
So, I would like to be able to configure
- Database name
- Database user
- Database password
- App port
- and few other things
And allow these configured values to be used in several places including
- Docker build phase (to setup database)
- Node App (to connect to database)
What is the best way to be able to set the database name, user and pass, once and use it to initiate the database in the container, and then connect to it whenever the container is spun up?
Current Setup
Currently I have a docker-compose file that is the following (./docker-compose.yml)
version: "2"
services:
myapp:
image: node:boron
volumes:
- ./dist:/usr/src/app
working_dir: /usr/src/app
command: sh -c 'npm install; npm install -g nodemon; nodemon -e js app.js'
ports:
- "9021:9021"
depends_on:
- mongo
networks:
- all
mongo:
build: ./build/mongo
networks:
- all
networks:
all:
Mongo Dockerfile (./build/mongo/Dockerfile)
# Image to make this from
FROM mongo:3
# Add files into the container for db setup
ADD initDB.js /tmp/
ADD createDBAdmin.js /tmp/
ADD mongod.conf /data/configdb
# Map the host directory mongo/myapp to /data
VOLUME /mongo/myapp:/data
RUN ls /data/*
RUN mongod -f /data/configdb/mongod.conf && sleep 5 && mongo ${DB_NAME} /tmp/createDBAdmin.js && sleep 5 && mongo ${DB_NAME} /tmp/initDB.js
CMD mongod --smallfiles --storageEngine wiredTiger
The initDB.js script (./build/mongo/initdb.js)
db.createUser(
{
user: "${DB_USER}",
pwd: "${DB_PASS}",
roles: [
{ role: "dbOwner", db: "${DB_NAME}" }
]
},
{
w: "majority",
wtimeout: 5000
}
);
// For some reason this is needed to save the user
db.createCollection("test");
docker version
Client:
Version: 1.13.0
API version: 1.25
Go version: go1.7.3
Git commit: 49bf474
Built: Tue Jan 17 21:19:34 2017
OS/Arch: windows/amd64
Server:
Version: 1.13.0
API version: 1.25 (minimum version 1.12)
Go version: go1.7.3
Git commit: 49bf474
Built: Wed Jan 18 16:20:26 2017
OS/Arch: linux/amd64
Experimental: true
Extra credit How can I persist database information outside of the container for backup purposes etc. and view the files? Do I need to map a directory on my host machine to data/db in the container and am i doing this correctly?
EDIT: This seems to be a good solution to the "Extra credit" question. How to deal with persistent storage (e.g. databases) in docker