Containerizing a NodeJs App with Docker
I was reading a lot about docker and the container way of deploying apps. So I got interested and started playing with docker, here is what I learned.
For those who don’t know docker, Docker is an open platform for distributed applications for developers and sysadmins. What docker does is that it acts like a container with its own configuration, dependencies and linux base so you can develop and test your application within an isolated environment. This leave you with a clean environment that you can use in your machine or deploy to a digital ocean droplet.
I gonna asume that you have docker installed, if not the docker installation documentation is the best way to start. I am running docker v1.4.1 in Osx Yosemite 10.1.
Images are the blueprint for building a docker container. It contains all the steps for running configurations and installing dependencies in the docker container, in this case we are going to create a base image with git installed based in a nodejs image pulled from the docker hub registry, for pulling this image you just have to run docker pull <tag of the container> in this case docker pull dockerfile/nodejs.
Once downloaded you can see in the list of images you have available just by running docker images command.
Now you can just run this image or use it as a base for creating another container, We are going to take the second option and create a base container with git and strongloop installed, to do this we must create a folder that contains a Dockerfile with this code.
The code is self explanatory but what it does is:
- select dockerfile/nodejs image as base so we have nodejs and npm installed.
- use npm to globally install strongloop
- download, make and install git.
- config git
Now that we have our image we just have to change directory out and run docker build <your directory> once it finishes to run it will give you a unique hash something like this
Successfully built 6cf7461f59b2
This is the id of your image but we can give it a name using docker tag <container-id> <name>, In this case: docker tag 6cf7461f59b2 4dstudios/loopback_app_base, now if you run docker images you will find it have a new name. Repeating the same process we create a new one that will contain our app in this case is called 4dstudios/remote_job_board using our new created base container we ensured we have git and strongloop installed.
Again this code does:
- Use our previous container as base ensuring we have git and loopback installed.
- Creates a /data/app folder where our repository is going to be cloned
- Clones our repository
- Change working directory to our new cloned app
- Runs npm install
- Expose 3000 port
- Run our strongloop app
Now with our image builded and tagged we are going to create our container.
Running a container from our image
Now we have an image that is our blueprint we can start running our container. To do this we need to use the command docker run.
docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG...]
In our case it would be docker run -p 3000:3000 -d 4dstudios/remote_job_board, this command will create the container in detached mode (-d) this means that it will detach itself from the command line IO, the -p option will forward the port 3000 in our machine to the port 3000 in the container, now if you go to localhost:3000 you could see that your app is up and running.
Also you can use the command docker ps to see what containers you have running.
For the sake of this tutorial we are cloning the app in the container using the image, this is not the best practice to do this, because you would need to rebuild the image every time you need to deploy for your container to have the last version of your code. Is better to have something like Capistrano to do the deployment when the container is up and running.