Monday, October 19, 2020

Docker Assignments #21: Dockerizing an Angular Application using Multi-stage build

Multi-stage builds is a new feature used to optimize Dockerfiles while keeping them easy to read and maintain

Before multi-stage build, developers used to maintain two dockerfiles (i.e. Dockerfile.dev and Dockerfile.prod) to build and deploy an application. But it is hard to maintain and it may increase image size also.

With multi-stage builds, you can use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different base, and each of them begins a new stage of the build. So, we can selectively copy artifacts from one stage to another without keeping everything in final image. 

In the last two previous articles, we created two Dockerfiles and docker-compose yml files to generate dist folder and service application using Nginx respectively. 


With help of multi-stage builds, we can create a single Dockerfile to build and serve an angular application

  1.  Create new scaffolding angular application using ng new command
  2.  Validate folder structure as per below image in the host machine

  3. Set default host for ng serve in package.json file
  4. Configure Dockerfile with below instructions
    • set base image as "node:12.7-alpine" and stage name as "build"
    • set working directory as "/usr/app"
    • write command to copy package.json
    • write command to run npm install
    • write command to copy all files from host machine into an image
    • expose Port 4200
    •  set CMD command to execute npm run build
    • set second From base image as "nginx:1.17.1-alpine"
    • copy dist folder from previous stage to nginx/html folder
          6. Write following instructions in docker-compose yml file
    • Configure "dockerangular-multistage-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 8081
        7. Spin up container using docker-compose up command
        8. check http://localhost:8081 


    Step 1: 
       > ng new docker-angular-multi-stage

    Step 4: 
    "scripts": {    
        "start""ng serve --host 0.0.0.0"    
      }
     
    Step 5:
    FROM node:12.7-alpine AS build
    WORKDIR /usr/app
    COPY package*.json ./
    RUN npm install
    COPY . .
    EXPOSE 4200
    CMD ["npm""run""build"]

    FROM nginx:1.17.1-alpine
    COPY --from=build /usr/app/dist/docker-angular-multi-stage /usr/share/nginx/html



    Step 6:
    version'3'
    services:
        dockerangular-multistage-service:
          build.
          volumes:
            - .:/usr/app
            - /usr/app/node_modules
          environment:
            NODE_ENVproduction
          ports:
            - 8081:80


    Step 7:
      > 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 :)

Docker Assignments #20: Deploy an Angular Application using Nginx

 Nginx is a webserver and can also be used as reverse-proxy, load balancer and http cache

  1. Setup an angular docker application as per previous article http://millionvisit.blogspot.com/2020/10/docker-assignments-19-dockerizing.html
  2. change command as "npm run build" in docker-compose.yml
  3. run docker-compose up command  to generate dist folder in the host machine
  4. make sure to remove dist folder entry in .dockerignore file
  5. create Dockerfile.nginx in the root directory and add following content
FROM nginx:1.17.1-alpine
COPY ./dist/docker-angular/ /usr/share/nginx/html/


     6. create docker-compose.prod.yml file in the root directory and add following content
version'3'
services:
    dockerangular-prod-service:
      build:
        context.
        dockerfileDockerfile.nginx
      environment:
        NODE_ENVproduction
      ports:
        - 8080:80

 
    7. run following docker compose up command

       > docker-compose -f "docker-compose.prod.yml" up

    8. check http://localhost:8080/

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

Source code available under https://github.com/ramasubbareddy1224/docker-angular

Happy Coding :)

Sunday, October 18, 2020

Run Angular dist folder locally using http-server

http-server is a simple, zero-configuration command-line http server used for running html static files in the localhost.

  1. Setup an angular docker application as per previous article http://millionvisit.blogspot.com/2020/10/docker-assignments-19-dockerizing.html
  2. change command as "npm run build" in docker-compose.yml
  3. run docker-compose up command  to generate dist folder in the host machine
  4. install http-server globally by using
          > npm install -g http-server

     5.  navigate to dist folder directory and run following command with default port 8080
    
         > http-server dist/docker-angular

     6. check http://localhost:8080/
     7. index.html file will be served as default file
     8. run following command if you want to change port number

> http-server -p 8022 dist/docker-angular 

     9. check http://localhost:8022/

http-server supports wide range of options like Https, SSL, CORS, basic authentication, request caching and etc.


Happy Coding :)

Docker Assignments #19: Dockerizing an Angular Application using Dockerfile and Docker Compose

  1.  Create new scaffolding angular application using ng new command
  2.  Validate folder structure as per below image in the host machine
  3. Set default host for ng serve in package.json file
  4. Configure Dockerfile with below instructions
    • set base image as "node:12.7-alpine"
    • set working directory as "/usr/app"
    • write command to copy package.json
    • write command to run npm install
    • write command to copy all files from host machine into an image
    • expose Port 4200
    •  set CMD command to execute npm run start
      6. Write following instructions in docker-compose yml file
    • Configure "dockerangular-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 4200
    • Set command as "npm run start"
    7. Spin up container using docker-compose up command
    8. check http://localhost:4200

Step 1: 
   > ng new docker-angular

Step 4: 
"scripts": {    
    "start""ng serve --host 0.0.0.0"    
  }
 
Step 5:
FROM node:12.7-alpine
WORKDIR /usr/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 4200
CMD ["npm""run""start"]


Step 6:
version'3'
services:
    dockerangular-service:
      build.
      volumes:
        - .:/usr/app
        - /usr/app/node_modules
      environment:
        NODE_ENVdevelopment
      ports:
        - 4200:4200
      command"npm run start"


Step 7:
  > 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 :)

Tuesday, October 6, 2020

5 Different ways to Debug Node.js Apps using Visual Studio Code

 In the previous article (node.js debug using Chrome DevTools) we have seen how to debug Node.js applications using Chrome DevTools. 

Visual Studio Code has built-in debugging support for Node.js runtime without relaying on chrome DevTools .

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

 

a. Add "express" npm package as a dependency in package.json file by doing ( npm i express )
b. Add following sample code in the index.js file

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");
})

1. By using "Launch" configuration

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

{    
    "version""0.2.0",
    "configurations": [
        {
            "type""node",
            "request""launch",
            "name""Debug Node.Js App",
            "skipFiles": [
                "<node_internals>/**"
            ],
            "program""${workspaceFolder}\\index.js",
        }
    ]

}
  • VSCode stores debug configuration in a file called "launch.json" which exists in .vscode folder
  • "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
  • "name" attribute used to specify name of the configuration which display in the debugger dropdown
  • "skipFiles" attribute used to avoid source code that you don't want to debug/step through. The Built-in node.js core modules referred by the <node_internals> name
  • "program" attribute used to specify Node.Js app start file to run the application in debug mode

set break-point in the index.js file and run "Debug Node.Js App" configuration from the dropdown



2. By using "Attach by Process ID" configuration
  • This is useful to Attach debugger when application already running with --inspect mode
  • Add configuration with following content in the launch.json file
{
    "version""0.2.0",
    "configurations": [
        {
            "type""node",
            "request""attach",
            "name""Debug Node.Js App With Attach",
            "skipFiles": [
                "<node_internals>/**"
            ], 
            "processId""${command:PickProcess}"          
        }
    ]
}
  • start node js app using  node --inspect index.js
  • set break-point in index.js file
  • run "Debug Node.Js App With Attach" configuration from the  VScode run dropdown 

3. By using "Attach to Port" configuration
  • This is useful to Attach debugger when application already running with --inspect mode and specific port
  • Add configuration with following content in launch.json file
{
    "version""0.2.0",
    "configurations": [
        {
            "type""node",
            "request""attach",
            "name""Debug Node.Js App with Port",
            "skipFiles": [
                "<node_internals>/**"
            ], 
            "port"9229         
        }
    ]
}

  • Start node js app using  node --inspect index.js ( i.e. 9229 is the default port for node.js app debugging)
  • set break-point in index.js file
  • run "Debug Node.Js App With Port" configuration from the  VScode run dropdown 

4. By using "Nodemon Launch" configuration

  • install nodemon globally by using > npm i  -g nodemon
  • Add configuration with following content in launch.json file
{
    "version""0.2.0",
    "configurations": [    
        {
            "type""node",
            "request""launch",
            "name""Debug Node.Js with Nodemon",
            "skipFiles": [
                "<node_internals>/**"
            ],
            "program""${workspaceFolder}\\index.js",
            "restart"true,
            "runtimeExecutable""nodemon"
        }
    ]
}

  • "restart" : set it true as nodemon does auto-restart on application changes. So, debugger gets attached automatically 
  • "runtimeExecutable" attribute used to specify different executable i.e. node/nodemon/npm and etc.
  • set break-point in index.js file
  • run "Debug Node.Js App With Nodemon" configuration from the  VScode run dropdown 

5. By using "Node:Auto Attachconfiguration

  • VSCode has built-in feature to debug Node js applications without writing any launch.json configuration file
  • Go to VSCode settings and set "Node: Auto Attach" on

  • Set break-point in the index.js file
  • Go to VScode terminal and run node.js application using --inspect mode
  • > node --inspect index.js

Happy Coding :)