DEV Community

Omar Elwakeel
Omar Elwakeel

Posted on • Edited on

Docker, easy start with nodejs-express app

Hello Docker

Docker, what is it? how is it beneficial? how to easily use it?

This is going to be a series of posts, this will be the first of them to explain some easy steps to start using docker containers and deploy apps with it, in this very step we are going to use nodejs with express framework to host a hello world app.

So what is docker?

Docker is lovely developer tool that makes it easy to install and run software without worrying about setup and dependencies.

How is it beneficial?

This is because it makes containers, imagine a multi layer cake where you take a verticle slice of it, so you take from each layer a portion but you don't care about the rest of the slices. Here is an illustration for it.

Docker containers

Which makes it easy for microservices, one example that we will be seeing soon is deploying multiple services with different environemnts or maybe different versions of the very same dependency, like different nodejs versions.

How to use it?

This is my favorite part, where it's enough with the talking and we start to write some code!!

Pre-requirements:
  • Installed NodeJs, any version and that's what is cool with docker!!
  • Installed npm, which usually comes with Nodejs.
  • Installed Docker for windows,linux,...etc
  • Registered Dockerhub account, it's for free ;)

First lets setup our server we start by initializing the folder structure

npm init -y
Enter fullscreen mode Exit fullscreen mode

So you get a package.json file with initial setup.

now for express

npm add express
Enter fullscreen mode Exit fullscreen mode

add the script to the scripts part in package.json
package.json

....
  "scripts": {
    "start": "node index.js",
  },
....
Enter fullscreen mode Exit fullscreen mode

create index.js file in the root directory

index.js

const express = require('express')

const app = express()

app.get('/', (req,res) => {
  res.send('Hello World!!')
})

server.listen(3000, () => {
  console.log(`Listening on port 3000`);
})
Enter fullscreen mode Exit fullscreen mode

in the terminal type, npm run start

go to the browser and hit localhost:3000 and here it's there, 'Hello world!!'

So Where is docker??? Here it comes in the next steps ;)

in the root directory create a file with no extension with the name Dockerfile with the following content

Dockerfile

FROM node:alpine

WORKDIR /app
COPY package.json .
RUN npm install
COPY . .

CMD ["npm", "start"]
Enter fullscreen mode Exit fullscreen mode

So What is going on???

  1. FROM node:alpine -> is you saying to docker you want to start from an initial image that exists publicly on dockerhub, because once you go with docker you have no nodejs runtime that you have on your machine so you need this dependency.

  2. WORKDIR /app -> this is the work directory inside the container you are making.

  3. COPY package.json .-> here you are copying the package.json file to the work directory, please take notice the '.' context which means to copy in the context directory.

  4. RUN npm install -> to install the required packages, in our case it's expressjs

  5. COPY . . -> here we copy everything else to the work directory, which is the source code.

  6. CMD ["npm", "start"] -> our start script that much match the one in the package.json

Right now you should be having a question, why did we copy twice, why not only one time at the end??

To answer this, I need you to wait for a second an start make use of this docker image. At this moment you have an image but you cant really use it, we need to do two things:

  1. Build it
  2. Push it to dockerhub

After that we can run it.

So in you terminal run the following code

docker build -t <your docker id>/<name of the image(eg. hello-world)> .
Enter fullscreen mode Exit fullscreen mode

again notice the . context

now you should be seeing something like this

Docker build

now you have this image locally, to view all your images

docker image ls
Enter fullscreen mode Exit fullscreen mode

Docker images

now we need to make this image have its way to your hub, So in you terminal run the following code

docker push <your docker id>/<name of the image(eg. hello-world)>
Enter fullscreen mode Exit fullscreen mode

Now to answer the question about copying twice in the Dockerfile configuration, this was because each command makes a layer, so we:
1.Copy the package.json file which has all the dependencies in the project
2.Install them using npm install
3.We copy the rest of the files which is the code
So whenever we make a change in the source code, only the layer that copies the code is affected and we dont install the packages again, in other words the rest of the layers are cahced.

after that you can got to your docker hub after signing in and you will find it there

Docker hub

Atlast, let's run this image, but notice something while running docker you can adjust the port it's listening on, so this app should be listening to port 3000, but we can adjust the port where it should take requests from, think of it as an outside port

So in you terminal run the following code

docker run -p 3005:3000 <your docker id>/<name of the image(eg. hello-world)>
Enter fullscreen mode Exit fullscreen mode

Voila!!!

Image running

go and hit localhost:3005/

and you should be seeing the following

Hello world response

I hope you liked this post, I'm intending the post some other related posts (actually other parts of this series where we take it a bit harder and a bit more advanced), I'm a starter myself, so if you noticed anything that you recommend against, I'm happy to hear from you, Thanks again!!

Top comments (0)