Containerising and Publishing NodeJS App With Docker

Photo by Guillaume Bolduc on Unsplash

You probably heard of Docker and all the good things about it, at the very least, you have seen the blue whale logo. Today, we are going to go through how to containerise and publish a simple application using Docker.

Prerequisite

Before we start, make sure you have Node and Docker installed on your machine. You can download Node here and Docker Desktop here. NPM(Node Package Manager) comes with Node and Docker comes with Docker Desktop.

Create Node.js App

First, let’s create the Node.js application. Run the following commands in your terminal.

# Create a directory named hello-world
mkdir hello-world
# Change directory to hello-world
cd hello-world
# Setup NPM package, this will create a package.json file
npm init -y
# Install `express` as dependency
npm install express
# Create a app.js file
touch app.js

Your current directory should have these files as of now.

Paste the following code into app.js that you have just created.

Test run the app locally by

node app.js

Then open your browser and go to localhost:80

Now that we have confirmed our app is working as expected, time to move to the main course — containerising the app.

Create a Docker image

Create a Dockerfile by running the following command:

touch Dockerfile

In your Dockerfile , paste the following code. Each line of codes is commented to help understanding the content.

If we sit back and think about it, the commands in Dockerfile are quite similar to the commands we run when we create/run our application locally.

  1. We first downloaded Node to our machine
  2. We created package.json
  3. We run npm install express to download and add the dependency to our project(if you check the content of package.json , express is added as a result)
  4. We created an app.js as the entry point of our app
  5. We run the app with node app.js

Now that we have everything ready, let’s containerise it! Run the following command to build an image of our app. Think of an image as the blueprint for our app.

docker build . -t hello-world

. indicates we want to build an image using the content from the current directory. Docker will look for Dockerfile by default and build the image according to the content of that Dockerfile . We use -t to add a name for our image.

It will take a while to build the image, after it is done, run

docker images

You should see your image being built.

REPOSITORY                  TAG       IMAGE ID       CREATED          SIZE
hello-world latest e85316d49302 5 minutes ago 948MB

Run app using Docker image

Now we can run our app using the blueprint aka image that we just built.

docker run hello-world

You should see

App listening at 80

But when you go to localhost:80, you would see this instead

Huh, what gives?

This is because when we run a container with docker run , it does not publish any of its port to the outside world by default. What we need to do is to publish and map it to a port on our machine. The port that the app runs on is 80, we are going to map port 8000 from our machine to port 80 inside the Docker container.

Let’s run the following command to publish port when we run the container

docker run -p 8000:80 hello-world

Go to localhost:8000

localhost:8000

You can run docker ps to see all running containers on your machine.

If you want to stop your application, you can use the docker stop command on another terminal, like so.

# Either one will work
docker stop [NAME]
docker stop [CONTAINER ID]

So if I want to stop my hello-world container, I can do this

docker stop unruffled_swanson
docker stop a17a441fac20

If you want to run your container on the background without keeping your terminal stuck, you can specify -d when running the app.

# -d or --detach
docker run hello-world -d

Publish image to Docker Hub

For the last part, we are going to publish the image that we have built to Docker Hub. You will need to register for an account if you have not done so. You can register it here — https://hub.docker.com/

Now that you have an account, you can login to Docker Hub on your terminal, like so

docker login

Enter your username and password when prompt to do so.

By convention, if we want to publish an image to Docker Hub, the name that we provide when we are building the image should be in this format:

[DOCKER_HUB_USERNAME]/[IMAGE_NAME]:[TAG]

The tag is added for versioning.

Say if my username is leeyoongti , the image name is hello-wolrd , and we want to tag the image as 1.0.0 , then it would be:

leeyoongti/hello-world:1.0.0

Then the full command to build the image would be:

docker build . -t leeyoongti/hello-world:1.0.0

Remember to replace the username to your Docker username.

Run docker images and you will see an image with your Docker Hub username and 1.0.0 as its tag.

Finally, you can run this command to publish to Docker Hub.

docker push leeyoongti/hello-world:1.0.0

Remember to replace leeyoongti with your Docker Hub username

Go to your Docker Hub repositories here — https://hub.docker.com/repositories, you will see your image being published successfully!

Conclusion

Now that you have learned how to publish your image to Docker Hub, go on and change the world!

Thanks for reading!

Software Engineer in Singapore