Creating and deploying your first Dockerized web application
Tags: docker, webdev, node, dockerhub
Published: 2020-04-29 16:38:05


## PART-1: Creating a simple web application with NodeJs and express.

For creating a simple node application we will be using express, a simple light weighted framework for NodeJs.

### Create a folder on your project folder
`mkdir simple-express-app`

### Create NPM repository
`npm init -y`

This should create a `package.json` file in your root directory. The file must look like 

```json
{
  "name": "simple-express-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```
we can edit this file for adding description, author, keywords for the project. You can edit whatever you want to edit though.

### Add express dependency
`npm i express`

This will pull the express package from the NPM registry, make node_modules if not available and add in dependencies key of `package.json `.

### Create `index.js` file with express.

The file might look like 
```js
"use strict";

const express = require("express");

const PORT = 5000;
const HOST = "0.0.0.0";

const app = express();
app.get("/", (req, res) => {
  res.json({ message: `Hello from simple-express-app` });
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
```

No need to worry if you are unaware of node application, we will be looking in detail below: 

Create an express application.
```js
const app = express()
```

Create route for root get request and send the json response.
```js
app.get("/", (req, res) => {
  res.json({ message: `Hell from simple-express-app` });
});
```

Listen to port and host
```js
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

```
### Run the project 
Now we can run the express application simply with `node index.js` but make sure you have installed your node dependencies if that is missing run `npm install`.

### Verify if your project is running.
Go to your browser and check the [url](http://localhost:5000/) and we should get the `JSON` output for the message.

.
.
.
.
.
.
.
.
.

## PART-2, Dockerizing the project

For dockerizing the project we need to create `Dockerfile`. Let's create `Dockerfile` in your root.

The Docker file will look like

```docker
FROM node:10-alpine
WORKDIR /app
COPY . /app 
RUN npm install
EXPOSE 5000
CMD node index.js

```

Don't get afraid of the code herewith. We are going to discuss each part of it.

The first line will define from what image we want to start building, here we are getting node of version 10 with `alpine` which is the light Linux distribution.

```docker
FROM node:10-alpine
```
Next line will create a directory to hold the application code inside your image, this will be the working directory for your application:

```docker
WORKDIR /app
```
The third step will copy your application code with the current directory to `/app` which is the working directory for our image.

```docker
COPY . /app 
```

The fourth step will run the command for installing dependency we will have in our node application.

```docker
RUN npm install
```
The next one will bind your app to port 5000 or whatever you have exposed herewith. We will use `EXPOSE` instruction to have it mapped by `docker` daemon.

```docker
EXPOSE 5000
```
The last but not least, we will define the command to run our application using `CMD`. Here we will be using `node index.js` for starting our server.

```docker
CMD node index.js
```
Now we are ready to dockerize our project, let's build our first docker image.

```docker
docker build -t <your-username>/simple-express-app .

```
Note that period sign (.) at the last of the docker build command that tells docker-daemon to build with files with the current directory.

The -t flag lets us put a tag for our image so it will be easier to find and use with the `docker images` command.

The user name is the docker-hub username, which will be used to push the images to the docker hub.

Now find your image with `docker images` command and you will get similar output. Make sure the new docker image is created with the tag we have provided for our first docker image.

```docker
$ docker images

# Example
REPOSITORY                         TAG        ID              CREATED
node-alpine                        10         1934b0b038d1    5 days ago
<your username>/simple-express-app    latest     d64d3505b0d2    1 minute ago
```

#### Run the image

```docker
docker run -p 5000:5000 -d <your-username>/simple-express-app
```
Here -p stands for publishing or expose the port 5000. This binds the port 5000 of the container where our express app will run with the 5000 port of the host machine.

The -d tag will run the container in detached more or run the container in the background.

#### List and test if docker container is running

```yml
# list the running container and get the id
docker ps

# get logs for application
docker logs <container_id>

# test in the browser or 
curl -i localhost:5000

# If you want to stop the running container 
docker stop <container_id>

```

#### Publish

Now let's publish our first docker image to docker hub. There are very simple steps to publish 

```yml
# Login to docker hub
# however -p via CLI is not secure we can use 
# cat ~/my_password.txt | docker login --username foo --password-stdin
docker login -u <user-name> -p <password>


# Push to docker hub
# here 0.0.1.RELEASE is the release version
# Don't forget to replace learntechfree with your username

docker push learntechfree/simple-express-app:0.0.1.RELEASE 

# Now visit the docker hub and check repository we will get the currently pushed images in your repository.
```

What's Next: Improving Layer Caching (Article coming soon).

Reference: [Documentation](https://docs.docker.com/)