Sunday, September 13, 2020

Docker Assignments #18: Node.js, Express.js application using Nodemon and Babel

ES 2015+ features are not yet fully supported in  Node.js runtime.So, Babel will be used to convert code into backward compatible version of JavaScript. 

@babel/cli comes with built-in CLI which can be used to compile files from the command line. It's much better to install it locally project by project rather than global installation. 

There are two primary reasons for this.
  • Different projects on the same machine can depend on different versions of Babel allowing you to update them individually.
  • Not having an implicit dependency on the environment you are working in makes your project far more portable and easier to setup.
@babel/node is a another CLI designed by babel team to work exactly same as Node.js's CLI, only it will compile ES6 code by using Babel presets and plugins before running it. 

Create a folder structure as per the following an image in the host machine


  1. Add "express" npm packages as a dependency in  package.json file
  2. Add "@babel/cli, @babel/core, @babel/node and @babel/preset-env" as a dev dependency in package.json file
  3. Add "nodemon" npm package as a dev dependency in package.json file
  4. configure npm build command to transpile src folder into dist folder using babel CLI
  5. configure npm dev command to use nodemon and bable-node CLI
  6. configure npm start command to run npm build command and serve "/dist" folder using node CLI
  7. write required code into src/utility/constant.js file to export a variable
  8. write required code into src/index.js file to expose an endpoint using express.js and import src/utility/constant.js file
  9. write required code into ".babelrc" file to set babel presets
  10. Configure Dockerfile with below instructions
    • set base image as "mhart/alpine-node"
    • set working directory  as "/usr/app"
    • write command to copy all files from host machine and npm install
    • expose Port 9030
    • set CMD command to execute npm run start

    11. Write following instructions in docker-compose yml file
    • Configure "testnodeexpress-service" service by specifying build context as Dockerfile
    • specify bindmount to /usr/app container path
    • specify volume mount to /usr/app/node_modules
    • Expose port 9030 and 9229
    12. Spin up container using docker-compose up command
    13. Verify "/dist" folder created or not
    14. check http://localhost:9030


    Step 1:
        > npm i express

    Step 2: 
         > npm install -D @babel/cli @babel/core @babel/node @babel/preset-env

    Step 3: 
         > npm install -D nodemon

    Step 4: 
    "scripts": {
        "build""babel src -s inline -d dist"    
      }     

    -s parameter specified to generate sourcemap files as "inline" base64 string
    -d parameter specified to store the location of traspiled files/folders (i..e "/dist" folder )
    Step 5: 
    "scripts": {
        "dev""nodemon -L --inspect=0.0.0.0 --exec babel-node src/"    
      }     
    Step 6: 
    "scripts": {
        "start""npm run build && node dist/"    
      }     
    
          Step 7: 
export const myname="Rama";

        Step 8:        
import { myname } from './utility/constant';
var express = require('express');

var app = express();


app.get('/', (req, res) => {
    res.send('Hello This  sample express app written by ' + myname);
});

app.post('/', (req, res) => {
    res.send(req);
});

app.listen(9030, () => {
    console.log('App listening on port 9030!');
});

Step 9:
{
    "presets": [
        "@babel/preset-env"
    ]
}

It is a preset with collection of babel plugins and poly-fills to use  the latest ES 2015+ features without needing to micromanage individual plugins/poly-fills 

Step 10:
FROM mhart/alpine-node
WORKDIR /usr/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm""run""start"]


Step 11:
version'3'
services:
    testnodeexpress-babel-service:
      build.
      volumes:
        - .:/usr/app 
        - /usr/app/node_modules       
      environment:
        NODE_ENVdevelopment  
      ports:
        - 9030:9030
        - 9229:9229
      commandnpm run start      
   

Step 12:
  > docker-compose up
   we can even spin up docker containers by right click on docker-compose.yml in vscode and select "Compose up" option


Happy Coding :)

Thursday, September 3, 2020

Docker Assignments #17: Debug Node.js and Express.js applications using Docker and Visual Studio Code

Visual Studio Code has built-in debugging support for Node.js applications which run in Docker containers.

We are going to use Dockercompose tool to spin up node.js app container. 

Docker Compose is a tool in the form of YAML configuration to run multi-container docker applications. With a single command, we can start or stop all the services specified in YAML configuration.

Docker Compose is a 3 step process
  1. Define app configuration using Dockerfile
  2. Define the services that app requires in docker-compose.yml so they can be run together in an isolated environment
  3. Run docker-compose up to starts and runs entire app

Create a folder structure as per below image in the host machine
 

  1. Add "express" npm packages as a dependency in  package.json file
  2. Add "nodemon" npm package as a dev dependency in package.json file
  3. configure npm start command as "nodemon -L --inspect=0.0.0.0 src/" in package.json
  4. Write required code into src/index.js file to expose an endpoint using express.js
  5. Configure Dockerfile with below instructions
    • set base image as "mhart/alpine-node"
    • set working directory  as "/usr/app"
    • write command to copy all files from host machine and npm install
    • expose Port 9030
    • set CMD command to execute npm run start
     6. Write following instructions in docker-compose yml file
    • Configure "testnodeexpress-service" service by specifying build context as Dockerfile
    • specify bindmount to /usr/app container path
    • specify volume mount to /usr/app/node_modules
    • Expose port 9030 and 9229
     7. Create vscode launch.json file and add appropriate configuration for debugging
     8. Spin up container using docker-compose up command
     9. Attach VSCode debugger
     10. check http://localhost:9030

Step 1:
    > npm i express

Step 2: 
     > npm install -D nodemon

Step 3:
"scripts": {
        "start""nodemon -L --inspect=0.0.0.0 src/"
    }

Step 4:
const express = require("express");
const app = express();

app.get('/', (req, res) => {
    res.send("sample express GET end point")
})

app.listen(9300, () => {
    console.log("app listening on port 9300");
})

Step 5:
FROM mhart/alpine-node
WORKDIR /usr/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 9030
CMD ["npm""run""start"]


Step 6:
version'3'
services:
    testnodeexpress-service:
      build.
      volumes:
        - .:/usr/app 
        - /usr/app/node_modules       
      environment:
        NODE_ENVdevelopment  
      ports:
        - 9030:9030
        - 9229:9229
      commandnpm run start      
   

Step 7:

Select VSCode Run option from left menu and create "launch.json" file with following content

{
    "version""0.2.0",
    "configurations": [
        {
            "name""Node.Js with Docker Attach",
            "type""node",
            "request""attach",
            "port"9229,
            "address""localhost",
            "localRoot""${workspaceFolder}",
            "remoteRoot""/usr/app",
            "protocol""inspector",
            "restart"true,
            "skipFiles": [
                "<node_internals>/**/*.js",
                "${workspaceFolder}/node_modules/**/*.js"
              ]
        }
    ]
}

  • VSCode stores debug configuration in a file called "launch.json" which exists in .vscode folder
  • "name" attribute used to specify name of the configuration which display in the debugger dropdown
  • "type" attribute  used to specify  type of debugger i.e. Node, Chrome, CoreCLR, PHP and etc
  • "request" attribute used to specify type of action i.e. Launch/Attach
  • "port" attribute used to specify debug port
  • "address" attribute to specify TCP/IP address of the debug port
  • "localRoot" attribute used to specify current workspacefolder path from local host machine
  • "remoteRoot" attribute used to specify container workdir path
  • "protocol" attribute used to specify debug protocol i.e. ( debug/inspector based on node version)
  • "restart" attribute used to restart sessions i.e. ( it is useful when nodemon used )
  • "skipFiles" attribute used for skipping files for debugging

Step 8: 
   > docker-compose up
   we can even spin up docker containers by right click on docker-compose.yml in vscode and select "Compose up" option

Step 9:
 run "Node.Js with Docker Attach" configuration from the vscode debug dropdown


Happy Coding :)