API request through Docker & Nodejs fails but works perfectly when accessed directly using the Nodejs

I am developing an application using Nodejs and Docker. Within the code, I need to make the request to GitLab API to get the data. When I run the application through the Docker command docker-compose exec web sh -c "project=GitLab type=New npm start" then I get the error as it is unable to get the response from the API call but the same code and API request works perfectly when running with the direct command node index.js.

Following is the code I have:

./web/index.js:

const   express     =   require('express');
const   http        =   require("http");
const   bodyParser  =   require('body-parser');
const   app         =   express();
const   port        =   process.env.PORT || 9000;
const   gitlabDump  =   require("./controller/GitLabDump");

app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: true }));

//Make NodeJS to Listen to a particular Port in Localhost
app.listen(port, function(){
    
    var project = process.env.project;
    var type    = process.env.type;

    if(project.trim() === "GitLab" && (type.trim() === "New" || type.trim() === "Update")){
        //If porject is GitLab then fetch the data from Gitlab
        console.log("Fetching GitLab Data.......");

        gitlabDump.gitlabDump(type, function(data){
            console.log("Completed Execution for GitLab")
            process.exit();
        })
    }
}

Following is my controller code where I am making the API request:
./web/controller/GitLabDump.js

const request = require('request');

exports.gitlabDump = function(callback){
    var gitlabAPI = "https://gitlab.com/api/v4/projects/<project_id>/repository/tree?ref=<target_branch>&path=path/to/subdirectory";

    console.log("BEFORE \n")

    request(gitlabAPI, function(error, response, body) {
        console.log(JSON.parse(body)) 
        callback("Completed");
    })
}

Following is my DockerFile:
./docker.compose.yml

version: '3'

services:
  db:
    container_name: db
    image: mysql:5.7
    volumes:
      - "./data/mysql:/var/lib/mysql:rw"
    environment:
      MYSQL_DATABASE: myDatabase
      MYSQL_ROOT_PASSWORD: myPassword
      MYSQL_PASSWORD: myPassword
      DATABASE_HOST: localhost
    restart: always

  web:
    container_name: web
    image: node:8
    volumes:
      - ./web:/usr/src/app
    working_dir: /usr/src/app
    depends_on:
      - db
    restart: on-failure
    command: "tail -f /dev/null"
    environment: ["project=${project}", "type=${type}"]

Following is the command I am using to run the application:

docker-compose exec web sh -c "project=GitLab type=New npm start"

Following is the error that I get:

Fetching GitLab Data.......
BEFORE 

undefined:1
undefined
^

The error is coming due to the line console.log(JSON.parse(body)). Because the body is undefined as the API call returns no data.

Please Note:

  1. API URL is correct and I have the proper access because the same URL gives me data when accessing through Chrome, Postman, and even when running the code using the node index.js command.

  2. I am using the same application to make other API calls apart from GitLab and they are working fine.

Can someone please help me what’s the issue here and why is failing for GitLab API?

Posting the answer here as it can be useful to someone else in the future:

Finally, I was able to find the resolution. The issue is not happening because of the docker but rather because of the Nodejs itself. If we console.log the error then we get the certificate has expired message.

The fix is to request something like this:

request({
  url: gitlabAPI,
  agentOptions: {
    rejectUnauthorized: false
  }
}, function (error, response, body) {
  console.log(JSON.parse(response.body))
});

Refer to the questions: javascript - Node.js request CERT_HAS_EXPIRED - Stack Overflow

1 Like