Docker Community Forums

Share and learn in the Docker community.

Unable to access node express routes

I am running node js and mongo in docker. There are no errors in the console But I am unable to access express routes.
This is my Dockerfile:-

FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
#EXPOSE 2345
CMD ["node","main.js"]  

This is docker-compose.yml file:-

version: "2"
services:
  app:
    container_name: app
    restart: always
    build: .
    ports:
      - "2345:2345"
    links:
      - mongo
  mongo:
    container_name: mongo
    image: mongo
    volumes:
      - ./data:/data/db
    ports:
      - "27017:27017"

This is main.js which is running:-

const http = require("http");
// const http = require("https");
const url = require("url");
const os = require("os");
const fileUpload = require('express-fileupload');
const express = require("express");
global.API_KEY = '';
global.LOGIN_API_KEY = 'hellovimal@47.com';
const app = express();
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
const session = require("express-session");
const MongoStore = require("connect-mongo")(session);
const cors = require("cors");
const exphbs = require("express-handlebars");
const { WebSocketServer } = require("protoo-server");
const mediasoup = require("mediasoup");
const ConfRoom = require("./lib/Room");
const amqp = require('amqplib/callback_api');
const mongoose = require('./routes/externalRoutes').mongoose;

app.use('/static', express.static('public'));
app.engine("handlebars", exphbs({ defaultLayout: "main" }));
app.set("view engine", "handlebars");
app.use(fileUpload());
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(session({ secret: "23432fgfdfddgjfdg23#%$*%#",
                 // cookie: { maxAge: 60000,
                  resave: false,
                  saveUninitialized: false,
                  store: new MongoStore({ mongooseConnection: mongoose.connection })}));
app.use(function (req, res, next) {
  res.locals.session = req.session;
  next();
});

var externalRoutes = require('./routes/externalRoutes');

const totalNumberOfWorkers = os.cpus().length;
const rooms = new Map();
const mediasoupWorkers = [];
let nextMediasoupWorkerIdx = 0;


(async () => {
  // Created Mediasoup Worker
  for (let i = 0; i < totalNumberOfWorkers; ++i) {
    const worker = await mediasoup.createWorker({
      rtcMinPort : 40000,
			rtcMaxPort : 49999
    });

    worker.on("died", () => {
      console.log("mediasoup Worker died, exit..");
      process.exit(1);
    });
    mediasoupWorkers.push(worker);
  }
  const worker = getMediasoupWorker();
  const router = await worker.createRouter({
    mediaCodecs: [
      {
        kind: "audio",
        name: "opus",
        mimeType: "audio/opus",
        clockRate: 48000,
        channels: 2
      },
      {
        kind       : 'video',
        mimeType   : 'video/VP8',
        clockRate  : 90000,
        parameters :
        {
          'x-google-start-bitrate' : 1000
        }
      },
      {
        kind       : 'video',
        mimeType   : 'video/VP9',
        clockRate  : 90000,
        parameters :
        {
          'profile-id'             : 2,
          'x-google-start-bitrate' : 1000
        }
      }
    ]
  });
  
  const room = new ConfRoom(router);
  // const tls = {
  //   cert : fs.readFileSync('/etc/letsencrypt/live/videoabc.tk/fullchain.pem'),
  //   key: fs.readFileSync('/etc/letsencrypt/live/videoabc.tk/privkey.pem')
  // }
  // const httpServer = http.createServer(tls, app);
  const httpServer = http.createServer(app);
  await new Promise(resolve => {
    console.log("--resolve--");
    // console.log(resolve);
    // httpServer.listen(2345, "0.0.0.0", resolve);
    let server = httpServer.listen(2345, function (){
      let host = server.address().address;
      let port = server.address().port;
      console.log('running at http://' + host + ':' + port);
      resolve
    });
  });
  const wsServer = new WebSocketServer(httpServer);

  // handle connections from client
  wsServer.on("connectionrequest", async (info, accept, reject) => {
    console.log(
      "protoo connection request [peerId:%s, address:%s, origin:%s]",
      info.socket.remoteAddress,
      info.origin
    );
    const u = url.parse(info.request.url, true);
    console.log("backend event");
    // Code added by Vimal------------------------------------------------
    const roomId = u.query["roomId"];
    console.log("roomId - ", u.query["roomId"]);
    if (!roomId) {
      reject(400, "Connection request without roomId and/or peerId");
      return;
    }
    const room = await getOrCreateRoom({ roomId, router });

    console.log("room - " + room);
    // -------------------------------------------------------------------
    room.handlePeerConnect({
      // to be more and more strict
      peerId: `p${String(Math.random()).slice(2)}`,
      protooWebSocketTransport: accept()
    });
  });

  // console.log("websocket server started on http://127.0.0.1:2345");
  await createExpressApp();
})();

// Get the existing room or create a new room -----------------------------

function getOrCreateRoom({ roomId, router }) {
  const room = rooms.get(roomId);
  // If the Room does not exist create a new one.
  if (!room) {
    return new Promise(resolve => {
      const room = new ConfRoom(router, roomId);
      rooms.set(roomId, room);
      room.on("close", () => {
        if(room._protooRoom.peers.length === 1)
        {
          rooms.delete(roomId)
        } else {
          console.warn(`Room has ${room._protooRoom.peers.length} in it`);
        }
      });
      resolve(room);
    });
  }
  return room;
}

// Get mediasoup worker -----------------------------------------------------

function getMediasoupWorker() {
  const worker = mediasoupWorkers[nextMediasoupWorkerIdx];

  if (++nextMediasoupWorkerIdx === mediasoupWorkers.length)
    nextMediasoupWorkerIdx = 0;

  return worker;
}

async function createExpressApp() {
  console.log("Hello express app");
  app.use('/', externalRoutes);
}

// Send to the worker----------------------------------------------------------

global.sendToQueue = function(msg) {
  amqp.connect('amqp://localhost', function(err, conn) {
    conn.createChannel(function(err, ch) {
      const q = 'email';
      ch.assertQueue(q, { durable: true });
      ch.sendToQueue(q, new Buffer.from(msg), { persistent: true });
      console.log("Message sent to queue : ", msg);
    });
  });
}

And this is my router File:-
var externalRoutes = require(‘express’).Router();
const path = require(‘path’);
const fs = require(“fs”);
const AWS = require(‘aws-sdk’);
var mongoose = require(‘mongoose’);
var Key = require(’…/models/Key’);
var VideoList = require(’…/models/VideoList’);
var mime = require(‘mime’);
var request = require(‘request’);
const urlF = require(‘url’);
const auth = require(’…/middleware/auth’);
// ---------------------------------------------
var awshttps = require(‘https’);
var awsAgent = new awshttps.Agent({maxSockets: 25});

    mongoose.connect('mongodb://172.20.0.2/VideoChat??socketTimeoutMS=90000',{useNewUrlParser:true, useUnifiedTopology: true}).catch((err)=> console.log(err));

    const s3 = new AWS.S3({
        accessKeyId: 'AKIAIVTN4SPZ4M6SNTWA',
        secretAccessKey: '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',
        signatureVersion: 'v4',
        region: 'us-east-2',
        // ------ Https Added -----------
        httpOptions:{ agent: awsAgent }
    });

    module.exports = (function() {
        'use strict';

        externalRoutes.get("/video-stream/:videoName*?" ,auth ,async function(req, res) {
            console.log(API_KEY);
            const videoName = req.query.videoName;
            console.log(videoName);
            let extName = path.extname(`encoded-video/${videoName}`);
            let fileName = path.basename(`encoded-video/${videoName}`).replace(extName,'');
            let fileExtension = extName.replace('.','');
            let path1 = await new Promise(resolve => {
              fs.stat(`encoded-videos/${videoName}`, (err, stats) => {
                if (stats.isFile(videoName) ) { // do this
                  console.log("file found");
                resolve(`./encoded-videos/${videoName}`);
                }
                else { // do this
                  console.log("file not found");
                  resolve(`assets/sample.mp4`);
                }});
              });
              console.log(path1);

            // const path = "assets/sample.mp4";
            const stat = fs.statSync(path1);
            const fileSize = stat.size;
            const range = req.headers.range;
            console.log(`range of request headers - ${range}`);
            if (range) {
              const parts = range.replace(/bytes=/, "").split("-");
              const start = parseInt(parts[0], 10);
              const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;
              const chunksize = end - start + 1;
              const file = fs.createReadStream(path1, { start, end });
              const head = {
                "Content-Range": `bytes ${start}-${end}/${fileSize}`,
                "Accept-Ranges": "bytes",
                "Content-Length": chunksize,
                "Content-Type": "video/"+fileExtension
              };
              res.writeHead(206, head);
              file.pipe(res);
            } else {
              const head = {
                "Content-Length": fileSize,
                "Content-Type": "video/"+fileExtension
              };
              res.writeHead(200, head);
              fs.createReadStream(path1).pipe(res);
            }
          });

        // Upload video template rendering
        externalRoutes.get('/video-upload',  auth,(req, res) => {
           res.render('video-upload');
        });

        // Upload video function
        externalRoutes.post('/video-upload', auth, (req,res) => {
          if (!req.files || Object.keys(req.files).length === 0) {
            return res.status(400).send('No files were uploaded.');
          }
          let sampleFile = req.files.video;
          sampleFile.mv(`./uploads/${sampleFile.name}`, function(err) {
            if (err){
              return res.status(500).send(err);
            } 
            else {
              sendToQueue(`./uploads/${sampleFile.name}`)
              res.render('upload-res');
            }
          });
        });

        externalRoutes.get('/video-list', auth, (req,res) => {
          // Read the mongo DB here for the video list
          let videoList = VideoList.find({}, (err, response) => {
            console.log(response);
            res.render('vlist',{
              'file_list': response
            });
          });
        }); 

        externalRoutes.get('/get-api-key',(req,res) => {
          // Mongoose Code here
          Key.find({},(err,docs) => {
            if(err) throw err;
            console.log(docs);
            let apiKey = '';
            docs.forEach((data) => {
              console.log(`DATA - id = ${data._id}, key =  ${data.key}`);
              apiKey = data.key;
              API_KEY = apiKey;
            });
            let randomNumber =  parseInt(Math.random() * 10);
            if (randomNumber>5){
              res.json({
                'data':{'api_key':apiKey},
                'success':1
              })
            } else {
              API_KEY = '';
              res.statusCode =  400
              res.json({
                'data': {
                  'message':'No Api Key data found!'
                },
                'success':0
              })
            }
          }).catch(err => {
            console.log(err);
            res.send(err);
          });
        });

        externalRoutes.get('/login',(req, res) => {
          res.render('login');
        });

        externalRoutes.post('/login',(req,res) => {
          console.log(req.body.password);
          if(LOGIN_API_KEY === req.body.password){
            req.session.password = LOGIN_API_KEY;
            req.session.isLoggedIn = true;
          }
          res.redirect('/video-list');
        });

        externalRoutes.get('/logout', (req,res) => {
          req.session.destroy();
          res.redirect('/login');
        });
        externalRoutes.get('/', (req,res) => {
          res.send('<h3>Home Page</h3>');
        });

        externalRoutes.get('/s3-video-stream/:videoName*?', auth, (req,res) => {
        let videoName = req.query.videoName;
        const signedUrlExpireSeconds = 6000 * 5;
        let videoList = ['320x240-'+videoName+'.mp4','640x480-'+videoName+'.mp4','1280x720-'+videoName+'.mp4'];
        let signedUrl = []
        let url;
        videoList.forEach((data)=>{
              url = s3.getSignedUrl('getObject', {
              Bucket: 'video-stream-demo',
              Key: data,
              Expires: signedUrlExpireSeconds
          })
          signedUrl.push(encodeURIComponent(url));

        });
        console.log(signedUrl);
        res.render('video-stream',{
          'baseUrl': signedUrl,
          '240-video':signedUrl[0],
          '480-video':signedUrl[1],
          '720-video':signedUrl[2],
          layout: 'video'
        })  
      })
        return externalRoutes;
    })();
    module.exports.mongoose = mongoose;