Dockerize Your Node.js Web App
Learn how to use Docker to create a container for your Node.js web app
A wise engineer once told me to treat your production machines like cattle, rather than pets. The philosophy behind this is pretty easy to understand when you think about your personal computer versus your deployment servers. Most developers care quite a bit about the computer they use every day. If they had to switch it out for a new one it would be a bit of an ordeal. It's almost like we are emotionally attached. I built my own desktop a few years ago and would definitely not want to change it for an entirely new machine. Production machines are different. The idea behind treating your machines like cattle is that you avoid the emotional sentiment I just described. Your servers are made to do something, and if one malfunctions you shouldn't have any issues trading one for another. This is the same relationship a farmer has to his livestock. They are meant to perform a function for you, and can be replaced when they stop performing. Docker is what facilitates easily managing your servers through container services. Containers require fewer resources than VMs and can be easily transitioned between servers as you need.
A container is a wrapper around your software that can be shipped and deployed into any system that supports it. A server hosts the container, but the container takes care of the gritty details about running your software. You can imagine real shipping containers in this scenario.
We know the container has certain dimensions that let us use it, but we don't care about what's inside. This container can fit into receiving bays, on the back of an 18-wheeler, or among hundreds of others on a large carrier in the ocean. Again, nobody cares about what's inside as long as the container is a standard size.
So you have a Node.js web app you want to deploy using Docker. You can create an image that you will place into a container easily by adding a
dockerfile. You'll also want to add a
.dockerignore for ignoring things like
npm-debug.log. Put both of these files into the root of your application.
# dockerfile FROM node:carbon # Create container working directory RUN mkdir -p /usr/src/app WORKDIR /usr/src/app # Install app dependencies COPY ./package.json /usr/src/app/ RUN npm install # Bundle app source COPY ./app /usr/src/app/ # Expose your port and start your application EXPOSE 8080 CMD ["npm", "start"]
To create an image we need to run
docker build, which will run each step in the
dockerfile. For cleanliness, I like to have my entire application in a single directory, with my Docker files at the same directory level like below.
ls -al total 22 drwxr-xr-x 1 jaearle 1049089 0 Dec 14 12:55 ./ drwxr-xr-x 1 jaearle 1049089 0 Dec 13 16:24 ../ -rw-r--r-- 1 jaearle 1049089 27 Dec 14 12:55 .dockerignore drwxr-xr-x 1 jaearle 1049089 0 Dec 14 12:55 myapp/ -rw-r--r-- 1 jaearle 1049089 448 Dec 14 12:57 Dockerfile docker build ./ -t myapp
-t argument is used to tag your image with a name you can use to reference it later. As the command goes through each step in your
dockerfile you will see the output progress. A success message is shown when it's done, and then you can experiment with your image locally before deploying it. You can check it out by running
docker images REPOSITORY TAG IMAGE ID CREATED SIZE myapp latest da6142b4ef25 2 minutes ago 67.4MB
Next try running your image in a local container.
docker run -d -p 8080:80 myapp
This will create a container and run your image against the port you exposed. You can now go to
localhost:8080 and see the local version of your app running from a container! If you're having trouble accessing it, try using
docker ps -l to list all containers. Here you can check their status to see if they're running or if they exited in an error. If there was an exit or crash you can inspect the container logs by using
docker logs with the container ID.
docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 54546e74256f myapp "npm start" 24 minutes ago Up 24 minutes 8080/tcp, 0.0.0.0:8080->80/tcp suspicious_golick docker logs 54546e74256f > firstname.lastname@example.org start /usr/src/app > node app.js
Now that you've got your app Dockerized the next step is to deploy it to a cloud registry, and then publish to a web server with a provider of your choosing. Azure has great CLI tools that can get you deployed in just a few commands, you can read more about them here.
Have a suggestion or feedback for this post? Tweet at me!