Building a Multi-Purpose Docker Image
Try the image first, and then run it in production
This is about building a multi-purpose docker image, which you can ask users to try out your app first. If they need to use the app in production allow them to use the same image simply changing some configurations.
Background Story
I was hacking for NodeKnockout last week and we’ve built an OpenSource Commenting Platform called Open Comment Box. It is a simple NodeJS app backed by a MongoDB database.
We wanted to provide a docker image for our app, which allows users to try out the app by just running the docker image.
In the same time, If someone going to use an external mongodb database or link another mongo container, it should works too.
So, we build a multi-purpose docker image for our app.
Demo
Let’s see how this works. The image I am using(arunoda/ocb) is available in the public docker registry.
1. Trying Out The App
docker run -p 8080:80 -d arunoda/ocb
This starts the app and the mongodb instance inside the container. You can simply point to port 8080 and try out the app.
So, its just a single step to try out the app
2. Using The App With An External MongoDB Database
MONGO_URL=mongodb://u:p@externalhost:port/db
docker run -p 8080:80 -e MONGO_URL=$MONGO_URL -d arunoda/ocb
This uses an external mongodb database via the MONGO_URL environmental variable. Our docker image understand it and pick it up correctly.
3. Using A Linked MongoDB Container
Latest Docker release (0.6.6) comes with a new way to link docker images. With that you can easily communicate between docker containers without knowing their IP Addresses.
First, lets start a named mongo container
docker run -d -name mongolocal -p 10001:27017 arunoda/mongo
This starts a mongodb container and name it as mongolocal. Don’t worry about the port mapping, we simply need to export mongo’s default port.
Let’s run our app with the above mongo container
docker run -p 8080:80 -link mongolocal:mongo -d arunoda/ocb
Here we simply linked a container named mongolocal as the mongo. Our docker image detects this and use the mongolocal as the mongodb database.
What’s Happening Behind The Scene
Our Dockerfile is not much different from the others. But for the ENTRYPOINT we’ve used a shell script which creates the enviroment for the app.
Here’s the script we’ve used.
#!/bin/bash#setting up the mongodb environment
if [[ "$MONGO_URL" != "" ]]; then
#if the MONGO_URL provided via an env variable use that
echo "[Mongo] Using MONGO_URL";elif [[ "$MONGO_PORT_27017_TCP_ADDR" != "" ]]; then
#if there is an mongo container linked, use it
echo "[Mongo] Using a linked Mongo container"
export MONGO_URL="mongodb://$MONGO_PORT_27017_TCP_ADDR/ocb"else
#otherwise start an local mongo server
echo "[Mongo] Using local mongodb server(not recommended)"
mongod &
sleep 5
fi#starting the app
cd app
NODE_ENV=production node server.js
Click here to get the raw script
Future of App Distribution
I hope docker will be the future of app distribution and most of the apps will provide an official docker image.
If they adapt a technique like this, it will be really useful.