Tuesday, May 5, 2020

Docker Assignments #14: Node.js, MySQL, Express, Nodemon and Docker Compose Dependencies Wait-for-it

Usually we use "depends_on" configuration in docker-compose.yml file if you are working on multi container application where as one container depending on another  container.

However "depends_on" only checks whether a container is running or not. It doesn't not verify whether container accepting connections are not.

For Example,  web app depending on "mysql" service. It will only checks mysql container running or not. It will not check weather mysql ready to accept connections or not . i.e. mysql might be still executing migration db scripts or initial startup db script.

Wait-for-it bash script helps to over come this problem by checking the availability of TCP host and port before running web app container

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

add following content into startscript.sql
create database hr;
use hr;
create table employee(id intname varchar(10));
insert INTO employee VALUES(1,'rama');

  1. Addd "mysql" and "express" npm packages as a dependency in the package.json file
  2. Add "nodemon" npm package as a dev dependency in the package.json file
  3. configure npm start command as "nodemon -L index.js" in package.json
  4. Write required code into index.js file to connect "mysql" container and expose endpoint using      express.js
  5. Configure Dockerfile with below instructions
  • set base image as "mhart/alpine-node"
  • setworking directory as "/usr/app"
  • download wait-for-it.sh from https://github.com/vishnubob/wait-for-it
  • provide execute permission to run wait-for-it.sh file
  • copy all files from host machine and do npm install
  • set CMD command to execute npm run start
     6. Write following instructions in docker-compose yml file
  • Configure"testmysql-service" service by pulling "mysql:5.7" image, set "MY_SQL_ROOT_PASSWORD" as "mysql123" , set up init script and port mapping - 3306
  • Configure"testnodeexpress-service" service by specifying build context as Dockerfile, create bindmount to /usr/app container path, volume mount to /usr/app/node_modules, dependent on "testmysql-service" and link to "testmysql-service"
  • Configure "testnodeexpress-service" npm command with wait-for-sh bash script
     7. Spin up containers using docker-compose up command
     8. check http://localhost:9030

Step 1: 
     > npm install mysql
     > npm install express

Step 2: 
     > npm install -D nodemon

Step 3: 
"scripts": {
    "start""nodemon -L index.js"
  },

Step 4:
var express = require('express');
var mysql=require('mysql');
var app = express();

app.get('/mysql'function (reqres) {
    var con = mysql.createConnection({
        host"testmysql",
        user"root",
        password"mysql123",
        port:"3306",
        database:"hr"
      });
      con.connect(function(err) {
        if (errthrow err;
        con.query("select * from employee",function(err,result,fields){
          if (errthrow err;
          res.send(result); 
        })
             
      });
});

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

Step 5:
FROM mhart/alpine-node
WORKDIR /usr/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 9030

RUN chmod +x /usr/app/wait-for-it.sh
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
      commandsh -c "/usr/app/wait-for-it.sh --timeout=0 testmysql:3306 && npm run start"
      depends_on
        - testmysql-service
      links
        - "testmysql-service:testmysql"  
    testmysql-service:
      imagemysql:5.7
      environment
        MYSQL_ROOT_PASSWORDmysql123  
      ports
        - 3306:3306  
      volumes
        - ./scripts:/docker-entrypoint-initdb.d   

Step 7:
docker-compose up


No comments:

Post a Comment